iOS - ASINetworkQueue, requests continue to execute even after a request fails - ios

I'm using ASINetworkQueue to execute multiple ASIHTTPRequests, and if any request fails I'd like the queue to cancel any pending requests and end. From reading the docs this should be the default behaviour. But I'm finding that even after a request fails, I still get 'requestStarted' for most of the remaining requests, and 'requestFailed' for all of them - is this how it is supposed to be? I'm guessing it's maybe because my requests are quite small and the requests start before it has chance to cancel them once a failure is detected. I tried implicitly setting setShouldCancelAllRequestsOnFailure:YES but this made no difference.

Without knowing the exact nature of your requests ... short answer: Yes, it's working how it's supposed to. Your requests are starting before a failure occurs. Longer answer: Try setting the queue's maxConcurrentOperationCount property. This may help you control the request pipeline a bit better if you need to test for failure.

Related

iOS NSURLSession waits for timeout if server doesn't exist

We use an NSURLSession to download data in the background, and have timeoutIntervalForResource defined so it will timeout if it takes too long, but if, for whatever reason, the source server doesn't exist then it still sits and waits. Is there any way to get it to abort immediately, or 'ask' the NSURLSessionDownloadTask if anything has been downloaded yet?
Failing that, what would be the best way of performing a pre-check to ensure a server exists before trying to download data from it?
These servers may be out of our control so we can't place a small file to download to check availability. The only file we may not about could be a sizeable video, for example.
You can indeed ask the task about its status. First, check the response property. If that is nil, then you haven't gotten the first packet from the server. If that is non-nil, use countOfBytesExpectedToReceive and countOfBytesReceived as needed to determine progress.
I should also note that these properties all support KVO, AFAIK.
You could also perform an explicit DNS lookup prior to scheduling the background request if you'd prefer, with the caveat that doing so would prevent you from scheduling something that might actually work if the user's Internet connection comes back online in the meantime. :-)

NSURLConnection getting limited to a Single Connection at a time?

OK - let's rephrase this whole question shall we?
Is there any way to tell if iOS is holding onto an NSURLConnection after it has finished & returned it's data?
I've got 2 NSURLConnections I'm instantiating & calling into a server with. The first one initiates the connection with the server and then goes into a COMET style long-polling wait while another user interacts with the request. The second one goes into the server and triggers a cancel mechanism which safely ends the first request and causes both to return successfully with a "Cancelled by you" message.
In the happy path case the Cancel button will never be clicked. But it's possible to click it and exit the current action.
This whole scenario works GREAT once. And then never works again (until the app is reset).
It's as though the first time thru one of the connections is never released and we are from then on limited to only a single connection because one of them is locked.
BTW I've tried NSURLConnection, AFNetwork, MKNetworkKit, ASIHTTPRequest - no luck what-so-ever with any other frameworks. NSURLConnection should do what I want. It's just ... not letting go of one of my connections.
I suspect the cancellation request in Step 2 is leaving the HTTP connection open.
I don't know exactly how the NS* classes work with respect to the HTTP/1.1 recommendation of at most two simultaneous connections, but let's assume they're enforcing at most two connections. Let's suppose the triggering code in Instance A (steps 1 and 3 of your example) cleans up after itself, but the cancellation code in Instance B (steps 2 and 4) leaves the connection open. That might explain what you are observing.
If I were you, I'd compare the code that runs in step 1 against the code that runs in step 2. I bet there's a difference between them in terms of the way they clean up after themselves.
If I'm not wrong,
iOS/Mac holds on to a NSURLConnection as long as the "Keep-Alive" header dictates it to.
But as a iOS developer you shouldn't be worried. any reason why you would like to know that?
So unfortunately with the lack of a real solution to this issue being found in all my testing I've had to implement simple polling to resolve the issue.
I've also had to implement iOS only APIs on the server.
What this comes down to is an API to send up a command and put it into a queue on the server, then using an NSTimer on the client to check the status of the of the queued item on a regular interval.
Until I can find out how to make multiple connections on iOS with long-polling this is the only working solution. Once I have a decent amount of points I'll gladly bounty them away for a solution to this :(

Issuing an asnyc I/O on a page

I was wondering what the correct way of issuing an asynchronous read operation on a page that has been swapped out is. And once this is done is there a way to execute a callback that happens so that I can execute some logic with that page?
madvise(start_address, length, MADV_WILLNEED) will do that.
A callback does not really exist, though you can poll a snapshot of the status with the mincore syscall, if you want.
Note that the opposite hint MADV_DONTNEED does not do what you think, nor does msync. The documentation is lying.
There is no non-broken-by-design way to start asynchronous writeback under Linux (although the documentation says so). You can choose between no-op, throwing pages away, synchronous writeback, or asynchronous writeback with purging the cache.

Adobe Actionscript - multiple service request processing

Does anyone know of any good resources that fully explain how functions and results will fire in an Adobe AIR app where multiple things are happening at once?
As a simple test, I've created a single service that I just keep changing the url of, then issuing a send(). It seems that no matter how many send() calls I put in, all of these get executed before the 'result' eventListener function gets called for the first time.
Is this how it works? i.e. the current function gets fully executed, with the async returns queueing up to be processed after AIR has finished what it's currently doing.
Likewise, if the user does something while all this is going on, I presume their request goes to the back of the queue as well?
All that makes sense, but I'm just wondering if it's documented anywhere.
While I'm on one, is it recommended practice to reuse the same HTTPService in this way, or is it better to create one for each concurrent transaction? Just because it works, doesn't mean it's the right thing to do...
I'm not aware of any documentation that explains this, but I can confirm that code blocks get executed before async calls are made, or at least before their result is being processed. If it didn't work that way, you would for instance not always be able to attach a responder to a token of a service call, because the result might already have been processed.
var token:AsyncToken = myService.someMethod();
token.addResponder(new Responder(resultHandler, faultHandler));
Developers coming from other platforms find this strange as they would expect the assignment of the responder to be too late.
So while I don't have an official explanation about the technical details inside the Flash Player, I can assure that it works this way.
If the user does something while a call is pending, the new request will indeed just be added as a new asynchronous call. Note that we can't realy speak of a queue, as there is no guarantee that the response of the first call comes in before the response of the second call. This depends on how much time the actual requests take.
You can perfectly reuse an HTTPService instance.
PS: Based on this, we were able to build the Operation API in Spring ActionScript. It is basically an API that allows you to execute asynchronous processes in a uniform way, without having to worry about the details of the actual async process.
The following code executes an async process and attaches a handler to it. This is also something that puzzles many developers at first, for reasons similar to the asyncToken situation.
var operation:IOperation = doSomeOperation();
operation.addCompleteListener(aCompleteHandler);
operation.addErrorListener(anErrorHandler);

.NET cancel stream BeginRead

I have not been able to find a way to cancel/terminate asynchronous read operation after successful HttpWebRequest. There is no way to set timeout, ThreadPool.RegisterWaitForSingleObject is not working too. And closing the underlying socket is not an option too because neither HttpWebRequest/Reponse provide access to it.
Edit:
Sadly this approach that Sunny suggestet works only for HttpWebRequest.BeginGetResponse. For the stream that you get after GetResponseStream() for some reason RegisterWaitForSingleObject is not working - the callback is never called.
The situation is the following:
I got an application that uses HttpGetRequest. It is build by using the default MSDN example for async httpwebrequest. Getting response is working like a charm. But on rare occasions the server that my httpwebrequest is connecting to forgets to close the socket. So I am hung on a infinite read from BeginRead.
In some rare occasions the other server forget
Why not RegisterWaitForSingleObject? You can use it for time out, and in the handler you can call request.Abort().
Here's an example. Btw, I have used simial approach before I found this article in the past, and it worked like a charm.
NOTE: The real end of the operation will happen on the next Stream.Read (of only the request/response was async) or Stream.EndRead (if the reading is async as well). You still need to capture the exception thrown in the EndXXXX handler.
EDIT: If the RegisterWaitForSingleObject never get called, then you have another issue, which is most probably a ThreadPool having not enough free threads. The callback for RegisterWaitForSingle object is called on a ThreadPool thread, and if there is no a free thread in the pool, it will never get called. You have some solutions:
Make your pages asynchronous. Why? How.
Change the max threads in the pool.
In any case, increasing the pool size will not help you too much. You have to inspect your code for resource (stream) leaks, and make sure that you not only call request.Abort(), but also close the response. Make sure than in your callbacks you use the proper EndXXX method, etc.
I nazdrave :)

Resources