TumblrArchive / TMCache

Fast parallel object cache for iOS and OS X.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

objectForKey:block: fails to call completion block when asked to process "large" numbers of requests

prendio2 opened this issue · comments

I noticed this issue when trying to cache a number of images at the same time in my own project and was able to recreate it in a sample project by simply requesting lots of object lookups in quick succession:

for (int i=1; i<=100; i++)
{
    [[TMCache sharedCache] objectForKey:[NSString stringWithFormat:@"key %d",i]
                                  block:^(TMCache *cache, NSString *key, id object) {
                                      NSLog(@"completed %@",key);
                                  }];
}

I would expect the above to output:

completed key 1
completed key 2
completed key 3
…
completed key 100

but it generally drops out after 1 or 2, or sometimes doesn't respond at all.

By switching:

 _queue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_CONCURRENT);

in TMCache.m:33 with:

_queue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_PRIORITY_DEFAULT);

I was able to get the cache responding as expected but this may have other side effects that I am unaware of. Any thoughts?

Great catch, thank you!

What's happening is that GCD is hitting its thread limit (~= 64). Here's some brief discussion:
http://stackoverflow.com/questions/7213845/number-of-threads-created-by-gcd

Basically, TMCache has been using TMMemoryCache with a synchronous call to objectForKey:, which should theoretically be fine because it's happening on another queue (that is, until it's waiting for more objects than there are threads and they all get blocked).

The fix was to switch everything in objectForKey: to asynchronous calls, which is messier but ultimately safer and avoids this problem. I've also added a unit test to hopefully catch this if it happens in the future. Here's the commit: e44251f

Thanks so much @jstn for resolving this so quickly and letting me know what was going wrong. Glad I could help in some small way.