-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Queue capacity exceeded #57
Comments
This is surprising, because the maximum capacity of the work queue is 64M. FJP commonPool should create more threads to handle the load such that this wasn't expected. The logging was intended if someone supplied their own bounded executor to indicate a resource constraint. This should be benign, except if you have a |
Is there any chance you can provide a test program to reproduce this? I'm not sure how you were able to exhaust the work queue, and if there's anything much I can do about it. I'll fix the removal listener issue, though. |
I will see if I can extract a reproduction. The code in question seems to |
The executor is used by Caffeine for the for periodic maintenance (after a write or a bunch of reads), removal notifications, refresh / refreshAfterWrite, and AsyncLoadingCache futures. In your case of a manual cache that means only periodic maintenance or removal notifications should be enqueued by the cache. Periodic maintenance is guarded by a The actual maintenance work is pretty small, except that it calls into a |
So we do have a long living cache for each web thread that we invalidateAll at the beginning of each request. Could this be causing the issue? Should we be building a new cache instead? |
Are these caches thread local? If so a bounded LinkedHashMap might be best regardless. I think if we can reproduce the issue then I should be able to make the cache more resilient. |
The caches are ThreadLocal. And they often only contain a few entries. I haven't reproduced locally yet. |
I cleaned up the stress test to help investigate this. It prints out useful information like the ForkJoinPool pending queue size. For write heavy workloads the state machine isn't perfect, so additional tasks do get scheduled. However that mostly doesn't occur if there is any intermediate work, like The perfect state machine doesn't have any race for the executor's work queue. Then even in the synthetic non-yielding case the queue stays empty, though as described before the cache can't evict fast enough to keep up with the writes. Again, that issue isn't a real concern because it requires the machine be dedicated to doing nothing but writing into the cache. So the state machine change might help in your case and be a decent safety net. I'll play with it a little more and probably add it into the next release. It has a tiny performance penalty, but not enough to be noticeable outside of a micro-benchmark. However, I think your resolution is best served by asking why a concurrent cache is used as a thread-local cache? A cache usually isn't write heavy, nor cleared so frequently. It sounds like you need a bounded scratchpad area, so a |
Integrated the improved scheduling, but feel free to continue the discussion. |
The simpler state machine and tryLock guard protected against most unnecessary scheduling of the maintenance task. This could occur though due to some benign races, a high write rate, and pronounce the effect of a clogged executor. This perfect scheduling has a negligible cost while ensuring that even in synthetic stress tests no excess occurs.
Thanks for looking so much into this! I've taken your suggestion and used a LinkedHashMap in this instance, instead, as there was no need for a concurrent structure. No doubt your improvement to scheduling will help others, and prevent this issue from occurring in our caches that do need concurrent access. |
Thanks for the update. I hope to finish #56 this weekend and cut a release. I'm been a little slow on that one because it has an API change, and I'm unsure if there is a better method name. If you can take a look and offer a suggestion I'd appreciate it. |
Release |
I am getting the following exception adding items to cache. Is this an actionable error?
The text was updated successfully, but these errors were encountered: