cancel specific request #2

Closed
mythodeia opened this Issue Oct 6, 2012 · 5 comments

3 participants

@mythodeia

Hello
i am trying to add many upload requests to a "queue".
in your example you do:
self.connection = [self makeConnection];
[self.connection start];

i have 2 questions:
1st -> how can i upload many requests to a single queue?
2nd -> how can i cancel a specific one from the queue?

thanks a lot

@mythodeia

Nevermind...
i am looping through all available connection and cancel the one i want.

thanks a lot for contributing with this excellent piece of code

@mythodeia mythodeia closed this Oct 6, 2012
@gwk
gwk commented Oct 6, 2012

FSNConnection has no explicit queueing mechanism, because the underlying Cocoa NSURLConnection provides its own opaque concurrency handling.

If you are simply concerned about having too many concurrent connections on the client side, I suggest trying it first; you should be able to create hundreds of connections and let Cocoa deal with the concurrency for you. If you encounter problems, or if your server side requires that you only issue one connection at a time, then I suggest that you:

  • keep a mutable array or mutable set of all your items to upload
  • write a function or method like - (void)startNextConnection that:
    • checks if there are any items left, and if so, returns
    • removes one item from the set
    • creates a connection with that item
    • creates a completionBlock for the connection that calls startNextConnection
    • any error handling that you need

You should also be able to expand on this approach to run an arbitrary k number of concurrent connections, by also checking [FSNConnection connections].count in the first step.

If you want to cancel a specific connection, you must hold onto it somehow in order to call cancel; how you do this should depend on your criteria for cancelation. If you want to cancel based on request URL, the simplest thing to do is iterate over the set of connections and cancel every connection matching your criteria.

For more complex example, you can create a cancel button for each connection; a view controller maintains a mutable dictionary mapping buttons to the request. Each button calls an action method on the controller that looks up the appropriate connection in the dictionary by sender and cancel it. On iOS UIButton is not hashable, so the keys into the dictionary need to be an NSValue of the button's address. You must clear out items in the dictionary manually as necessary for the lifecycle of each connection.

Hope that helps!

@mythodeia

thanks for your detailed answer.
as i mentioned before i found a way to manage with cancelling a specific upload request from the total uploads running at a specific time. i did it the same way you described so that means that my initial thinking was correct.

what i found though is that when i try to upload 8 images i get 100% a timeout in 3 of them and the rest upload correctly.
what i did was this:
NSMutableURLRequest* r = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLCacheStorageAllowedInMemoryOnly timeoutInterval:180];

instead of what was previously there. my question is since as you said FSNConnection does not a queuing mechanism how can i limit the concurrent requests to 4 at a time?
thanks again for your efforts and code

@mythodeia mythodeia reopened this Oct 6, 2012
@jstart

You could subclass FSNConnection and override the + (NSOperationQueue *)queue method and setMaxConcurrentOperationCount to 4. Something like this:

+ (NSOperationQueue *)queue {
    static NSOperationQueue *q = nil;
    if (!q) {
        q = [NSOperationQueue new];
        q.name = @"FSNConnection queue";
        [q setMaxConcurrentOperationCount:4];
    }
    return q;
}

To do this without subclassing you would need to wrap your NSURLConnections in NSOperations and use an NSOperationQueue and then limit the queue's operation limit. You can use the method setMaxConcurrentOperationCount: on NSOperationQueue as seen here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html

Theoretically FSNetworking could implement something like AFNetworking's AFHTTPClient that keeps its own NSOperationQueue, but I would recommend subclassing or wrapping the FSNConnections in NSOperations and use a Queue.

@gwk

I don't think you need to subclass FSNConnection; simply call:
[[FSNConnection queue] setMaxConcurrentOperationCount:4];

This will change the existing global queue.

@mythodeia mythodeia closed this Jun 29, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment