I have already implemented NSOperationQueue successfully in application.
I have one operation queue which might have 1000 of NSOperations like below.
@interface Operations : NSOperation
@end
@implementation Operations
- (void)main
{
NSURL *url = [NSURL URLWithString:@"Your URL Here"];
NSString *contentType = @"application/json";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSError *err = nil;
NSData *body = [NSJSONSerialization dataWithJSONObject:postVars options:NSJSONWritingPrettyPrinted error:&err];
[request setHTTPBody:body];
[request addValue:[NSString stringWithFormat:@"%lu", (unsigned long)body.length] forHTTPHeaderField: @"Content-Length"];
[request setTimeoutInterval:60];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *resData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
}
@end
Now for that queue I am adding all 1000 operations at a time. I add operation like below.
Operations *operation = [[Operations alloc]init];
[downloadQueue addOperation:operation];
Now what happens time interval is 60 as [request setTimeoutInterval:60]
So think like after 60 seconds if 300 operations out of 1000 operations is finished then other 700 operations are throwing request time out error.
So what should I do in this case.
Can I resume failed operations? Or I should again make operation and add it in queue.
Is there any better mechanism than this one?
Suspending and Resuming Queues If you want to issue a temporary halt to the execution of operations, you can suspend the corresponding operation queue using the setSuspended: method. Suspending a queue does not cause already executing operations to pause in the middle of their tasks.
A queue that regulates the execution of operations.
An abstract class that represents the code and data associated with a single task.
My initial inclination would be, yes, just create new operations for the timed out requests and toss 'em back into the queue. It just feels simpler since you already have logic for adding those operations for your requests. HOWEVER:
Be careful to not get into sort of an infinite loop. If just ONE of those fails indefinitely for whatever reason, your queue will keep on chugging. I'd keep a failure count so that you know to stop retrying a request after some finite number of attempts.
If you KNOW that a large number will always fail, consider batching them in some fashion. One option would be a chain of dependencies. eg. You could try adding 200 of your ops, a "wait" NSOperation, the next 200, another "wait" NSOperation, another "wait" op, etc. Make the first wait op be dependent on those first 200 requests. Then make the next 200 depend on that first wait op, and so on:
Basically like 2 but instead of a "wait" op, have a "done" op. Lets say you have an array of 1000 requests to send: Toss 200 into the queue, then a "done" op which depends on those 200. When the "done" op runs (by definition, AFTER those 200 are done), it can then pull the next 200 from the array and toss them in (plus a new "done" op).
(maybe even consider making the wait/done op "pause" a few seconds to give the server a breather)
In other words, with #2 and #3, I'm saying "blast 200 at once, wait, then blast the next 200, wait, etc." (200 is arbitrary on my part, you know better than I as to what the best number is for your situation)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With