Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
prendio2 opened this issue May 13, 2013 · 2 comments
Labels

Comments

@prendio2
Copy link

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?

@ghost ghost assigned jstn May 13, 2013
@jstn
Copy link
Contributor

jstn commented May 14, 2013

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

@jstn jstn closed this as completed May 14, 2013
@prendio2
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants