Skip to content

Running parser in the background #183

Open
futuretap opened this Issue May 9, 2011 · 4 comments

3 participants

@futuretap

I've some lengthy parsing going on that I'd like to do in the background. I'd like to run the HTTP fetching and the parsing in a NSOperation because there are multiple requests going on in parallel that have to be managed by an NSOperationQueue.

By default, asi-http-request sends all delegate messages to the main thread. The documentation says:

"For more complex situations, or where you want to parse the response in the background, create a minimal subclass of ASIHTTPRequest for each type of request, and override requestFinished: and failWithProblem:"

Besides the fact that the error method is called failWithError:, I don't know how to write this subclass. I tried to copy the standard method implementations and replaced the performSelectorOnMainThread calls. However this doesn't work reliably, I get all sorts of strange crashes. I found there are many more occurrences of performSelectorOnMainThread in the code. Do I have to replace all of them?
Then, does asi-http-request need a Runloop when running on the background thread?

@atnan
atnan commented May 11, 2011

A minimal subclass for parsing off the main thread looks like this:

@implementation MyParsingRequest
- (void)requestFinished {
  NSError* parseError;
  self.parsedObject = [MyParser parse:[self responseData] error:&parseError];
  if (self.parsedObject != nil) {
    [super requestFinished];
  } else {
    [self failWithError:parseError];
  }
}
- (void)failWithError:(NSError *)theError {
  // Optionally, you can do extra error handling here
  [super failWithError:theError];
}
@end
@futuretap

Thanks. It seems to work, but when I start another async request in the delegate from the same thread it blocks after a few requests. Could this be a deadlock situation that doesn't occur when coordinating via the main thread?

I settled to a solution with standard main thread delegate callbacks that spawn a background thread for the parsing. Seems to work reliably so far.

@atnan
atnan commented May 11, 2011

All delegate methods (such as requestDidFinish:) are done on the main thread, and there should be no problem with kicking off an additional asynchronous request. Starting another request from within your ASIHTTPRequest subclass might cause issues, though.

@adib
adib commented Jan 21, 2012

I'm thinking of shunting the operation to some background thread in the subclass methods that call the delegate methods. Is there any potential problem to this approach? Reason being is that there are a lot of functionality already present in ASIHTTPRequest methods that are called in the main thread and it is cumbersome to copy-paste everything just to replace the performSelectorOnMainThread: calls (and not to mention @futuretap experienced a lot of strange errors implementing that approach).

The code may look like this:

-(void) reportFailure 
{
   [[[self class] sharedQueue] addOperationWithBlock:^{
      [super reportFailure];
   }];
}

(note that this is off-the-cuff and I didn't compile this beforehand)

@atnan @pokeb What do you think of this approach?

UPDATE: I've just done this and my quick tests doesn't show any issues so far. Please refer to:

https://github.com/adib/BSTwitterFramework/tree/master/BSHTTPRequest

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.