I am performing multiple read operations on the same resource stored on disk.
Sometimes the read operation itself takes longer than the time between requests for that same resource. In those cases it would make sense to batch the read operations into one read request from the disk and then return the same result to the various requester.
Initially I tried caching the result from the initial fetch resource request - but this didn't work because the time it took to read the resource was too long, and new requests came in - meaning that they would try to fetch the resource as well.
Is it possible to "append" the additional requests to the ones that are already in progress?
The code I have now follows this basic structure (which isn't good enough):
-(void)fileForKey:(NSString *)key completion:(void(^)(NSData *data) {
NSData *data = [self.cache threadSafeObjectForKey:key];
if (data) {
// resource is cached - so return it - no need to read from the disk
completion(data);
return;
}
// need to read the resource from disk
dispatch_async(self.resourceFetchQueue, ^{
// this could happen multiple times for the same key - because it could take a long time to fetch the resource - all the completion handlers should wait for the resource that is fetched the first time
NSData *fetchedData = [self fetchResourceForKey:key];
[self.cache threadSafeSetObject:fetchedData forKey:key];
dispatch_async(self.completionQueue, ^{
completion(fetchedData);
return;
});
});
}
I think you want to introduce a helper object
Your reader method now becomes something like
This is uncompiled code, so please check the spelling and logic, but I hope it explains the idea. I like this post if you want an introduction to semaphores.