My iOS app does a lot of different requests to a Web service. Each request is a call to a method of a ConnectionManager object. When the response arrives from the Web service, a delegate's method is called to notify an interested receiver. Moreover, to maintain the session active, a polling every X seconds is required.
Said so, in your opinion it is better if ConnectionManager is a Singleton or not?
The singleton is simpler (because I do not have to pass a ConnectionManager's reference to all those who need to do a request to the Web service or I do not have to create more ConnectionManagers). Moreover, it is easy to handle the issue of polling: I just add two methods startPolling and stopPolling on the ConnectionManager. But I do not like to use the delegates with a singleton (because there can be only one delegate, and what happens if a response comes when there is not one set?) and at the same time I do not like to use the notifications. I do not like the singleton, too :)
Do you have advice on alternative patterns?
I went through similar thinking as you and ended up with this pattern:
ConnectionManager [singleton] - responsible for maintaining a connection to the server and submitting & receiving requests
ConnectionQueue [singleton] - Stores a stack of Requests waiting to be fulfilled
Request - Created each time something is needed from the server. It contains all the request data (urls, params etc) and a reference to the delegate.
Response - A container for the data retrieved from the server along with the original request.
Hooking it all together...
The ConnectionManager is started at startup and it creates the ConnectionQueue
When a call to the server is needed create a Request object, pass in all required params and add it to the ConnectionQueue
The queue lets the manager know there's a request that needs to be processed
The manager removes the request from the queue & makes the call to the server
Data is received
The manager creates the response and sends it back to the delegate.
You can see this other post:.
I think it can be useful.
Related
Could please Give RealTime Example when we should use AddSingleTon and when AddScoped and When should use AddTransient.
As far as I know, the Singleton is normally used for a global single instance. For example, you will have an image store service you could have a service to load images from a given location and keeps them in memory for future use.
A scoped lifetime indicates that services are created once per client request. Normally we will use this for sql connection. It means it will create and dispose the sql connection per request.
A transient lifetime services are created each time they're requested from the service container. For example, during one request you use httpclient service to call other web api request multiple times, but the web api endpoint is different. At that time you will register the httpclient service as transient. That means each time when you call the httpclient service it will create a new httpclient to send the request not used the same one .
Transient — Services are created each time they are requested. It gets a new instance of the injected object, on each request of this object. For each time you inject this object is injected in the class, it will create a new instance.
Scoped — Services are created on each request (once per request). This is most recommended for WEB applications. So for example, if during a request you use the same dependency injection, in many places, you will use the same instance of that object, it will make reference to the same memory allocation.
Singleton — Services are created once for the lifetime of the application. It uses the same instance for the whole application.
This question is about wrapping RestKit requests in custom objects, and whether or not I can guarantee that an object sending the RestKit request will also be used as a delegate when the response is returned.
I'm working with an abstruse REST API (Salesforce), and RestKit doesn't appear to handle some of Salesforce's peculiarities well -- for example, when you make a call to the Salesforce REST API, you might get back a partial dataset, and then be given a "nextRecordsUrl" that you must follow to get the next chunk. Others working with Salesforce and REST have run into the same issue (ref https://groups.google.com/forum/#!msg/restkit/HJNjB7I6WVM/8u5n7nHoJQUJ). I created a class to wrap the calls to Salesforce and automatically follow these links, and process the returned data sets correctly. The class instance registers itself as the delegate for the REST call.
The class I wrote works great on its own (when there's a single instance), but I'll be creating other classes and have several instances that will need to handle their data independently. I've read through the documentation and code (it's been a learning experience, I've only worked with ios for about a month now), but I can't see if it's guaranteed that a particular instance will respond as the delegate for its requests alone, or if it might accidentally pick up the responses for another instance.
For example, suppose I have instances A and B, both of which are making requests using RKObjectLoader, and which set themselves as delegates using loader.delegate = self;. Both are running simultaneously (asynchronous). Here's a potential flow I see:
A's RKObjectLoader makes call, registers self as delegate for response
RestKit framework sends request for A
B's RKObjectLoader makes call, registers self as delegate for response
RestKit framework sends request for B
... wait ...
RestKit framework gets response, and somehow determines that this response was from B's request, calling B as the delegate
B delegate methods get called
RestKit framework gets response, and somehow determines that this response was from A's request, calling A as the delegate
A delegate methods get called
I couldn't see how the RestKit framework would distinguish between responses from requests, and thereby ensure that the correct delegate instances get called. In other words, it appears to me that RestKit might get a response to a request, and then call any delegate it wants ... but that seems counterintuitive, and the framework author appears to be very sharp.
So, my questions:
If I have a class instance using RKObjectLoader and setting itself as the delegate, can I be guaranteed that it will be called when the response for that request comes in?
Can you point me to the actual implementation in the RestKit framework that handles this, so I can learn how it's done?
Thanks very much!
I haven't received an answer to this question, but in case somebody has the same question and comes across this, here's the answer: yes, RestKit does appear to match the correct delegate with the outgoing request.
I created a small class (with an (NSString*) identifier property that calls a service, and in the delegates I printed out the instance's identifier with the result. I confirmed that instance A's delegate method was handling instance A's call, and B's was handling B's, with several simultaneous calls.
I need to extract several header values at the start of each request and place them into a ClientContext object that can be injected into my application code by MEF. I am using Preview 5 of the WCF Web API and don't see a way to do this.
In 'standard' WCF, I would create a class that implements IExtension<OperationContext> and have the following property to wire it all together:
[Export(typeof(IClientContext)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public static ClientContextExtension Current
{
get
{
var operationContext = OperationContext.Current;
if (operationContext == null)
return null;
var extension = operationContext.Extensions.Find<ClientContextExtension>();
if (extension == null)
{
extension = new ClientContextExtension();
operationContext.Extensions.Add(extension);
}
return extension;
}
}
A custom DelegatingHandler calls ClientContextExtension.Current and sets the properties from the header values. Unfortunately, with WCF Web API, OperationContext.Current is always null!
I cannot figure out a way to make this work with the Web API. Any help is appreciated!!!
I've come up with a working solution but remain open to other options. First, some rationale behind the original approach...
Because WCF uses thread pooling, anything based on a per-thread model may (and will) have a lifetime that extends beyond an individual request. I needed a way to store client context information pulled from the HTTP headers for each request as the information will be different each time. This means I can't persist the context information per-thread because the thread will be re-used.
Or can I?
The flaw in my logic was that thread re-use was the problem. In reality, each thread is only every servicing a single request at one time thereby making any information in that thread isolated to that request. Therefore, all I need to do is make sure that the information is relavent to that request and my problem is solved.
My solution was to refactor the Current property to reference a private static field marked with the [ThreadStatic()] attribute, ensuring that each instance was specific to the thread. Then, in my DelegatingHandler, which executes for each request, I reset the properties of the object for that request. Subsequent calls to Current during that request return the request-specific information and the next request handled by the thread gets updated in the DelegatingHandler so as far as my other code is concerned, the context is per-request.
Not perfect, but it at least gets me up and running for the moment. As I said, I am open to other solutions.
UPDATE
Upon closer inspection, this solution is not working as there is no thread affinity between the DelegatingHandler and the service code that is making use of the context object. As a result, sometimes my call to retrieve the ThreadStatic object works as expected but on other occasions I get a new instance because the code is operating on a different thread than the handler.
So, disregard this solution. Back to the drawing board.
UPDATE TO MY UPDATE
After discussing my problem with Glenn Block, it turns out that it is just a matter of making sure the context is set on the same thread the request handler (the service) is executing. The solution is to use an HttpOperationHandler instead of a MessageHandler.
According to Glenn, message handlers operate asynchronously which means they could execute on a different thread from the request handler (service) so we should never do anything in a message handler that requires thread affinity. On the other hand, operation handlers run synchronously on the same thread as the request handler, therefore we can rely on thread affinity.
So, I simply moved my code from a MessageHandler to an HttpOperationHandler and have the desired results.
You can read a full explanation here: http://sonofpirate.blogspot.com/2011/11/modeling-client-context-in-wcf-web-api.html
You can try to use a
HttpOperationHandler<HttpRequestMessage, HttpRequestMessage>
There you should be able to access the headers.
I aplogise if my terminology is inaccurate, still deep in learning.
I am creating a web service to act as an intermediary between Silverlight and XMPP. To start all of this I have created a web service call to enable me to ask the server to log on on my behalf and the idea is that the server will log on and then push back to my client once complete.
I have based the idea on the code form this site: http://weblogs.asp.net/dwahlin/archive/2011/02/06/syncing-data-with-a-server-using-silverlight-and-http-polling-duplex.aspx
Now the problem I have is that the Register call I have created will use an asynchronous call to log into XMPP. But the register call itself is also asychronous. So I don't know the best way for a web service call to wait for another service's async call
What I thought of doing was making the Register a one way call with the idea being that my server will log into XMPP then push the client once logged in (or fileld etc)
[OperationContract(IsOneWay = true)]
void Register(string name, string password, string nickname);
But when I imported the Service Reference the class generated appears to have a RegisterCompleted() call which debug shows is invoked. But I thought one-way meant no response is called so why is it?
One Way means No Response Data. Internet protocols are a request-response model where there is an acknowledgement for the receipt of the request. Your Register service returns no data (void) so RegisterCompleted really did "completed accepting three string parameters and returned no data".
This is a good thing - now you know if you had a problem starting the registration or everything is good so business as usual until you hear back from the server. You don't know yet if you're actually registered yet so that's why your client continues to Poll the server until the server responds - good or bad.
His previous article references an good MSDN example on using the PollingDuplexHttpBinding.
I am using wcf 4 and trying to transparently transfer context information between client and server.
I was looking at behaviors and was able to pass things around. My problem is how to flow the context received in the incoming headers to the other services that might be called by a service.
In the service behavior I intercept the the message and read the headers but don't know where to put that data to be accessible to the next service call that the current service might make.
What I am looking for is something like:
public void DoWork()
{
var someId = MyContext.SomeId;
//do something with it here and call another service
using(var proxy = GetProxy<IAnotherService>())
proxy.CallSomeOtherMethodThatShouldGetAccessTo_ MyContextualObject();
}
If I store the headers in thread local storage I might have problems due to thread agility(not sure this happens outside ASP.NET, aka custom service hosts). How would you implement the MyContext in the code above.
I chose the MyContext instead of accessing the headers directly because the initiator of the service call might not be a service in which case the MyContext is backed by HttpContext for example for storage.
In the service behavior I intercept
the the message and read the headers
but don't know where to put that data
to be accessible to the next service
call.
Typically, you don't have any state between calls. Each call is totally autonomous, each call gets a brand new instance of your service class created from scratch. That's the recommended best practice.
If you need to pass that piece of information (language, settings, whatever) to a second, third, fourth call, do so by passing it in their headers, too. Do not start to put state into the WCF server side! WCF services should always be totally autonomous and not retain any state, if at ever possible.
UPDATE: ok, after your comments: what might be of interest to you is the new RoutingService base class that will be shipped with WCF 4. It allows scenarios like you describe - getting a message from the outside and forwarding it to another service somewhere in the background. Google for "WCF4 RoutingService" - you should find a number of articles. I couldn't find antyhing in specific about headers, but I guess those would be transparently transported along.
There's also a two-part article series Building a WCF Router Part 1 (and part 2 here) in MSDN Magazine that accomplishes more or less the same in WCF 3.5 - again, not sure about headers, but maybe that could give you an idea.