Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Offer returns false occasionally when space should exist #21
I have a use case where I'm using the queue size as a specific limit and relying on the offer rejection as a boundary. I found that it seems there are times when
A unit test that demonstrates this behavior is here: https://github.com/benjchristensen/JCTools/blob/offer/jctools-core/src/test/java/org/jctools/queues/SpmcArrayQueueTest.java#L54
This test does the following
I can't see anything wrong with the code that would cause more values to be offered than items polled.
This unit test works if I replace the
@benjchristensen I'm aware of this issue and debating the right course of action. Currently I am favouring a weaker Queue interface where offer may return false if the next slot is not available and poll may return null if the next slot is empty. Confusingly this is not the same as the queue being full/empty.
Thank you for jumping on this so quickly @nitsanw.
I think there are use cases where the weak version can work, but in some I'm not sure how to make it behave deterministically without causing other problems. I have use cases where I rely on the accuracy of offer/poll so that threads can be released, as I don't have threads dedicated to offering/polling. This means spinning is somewhat difficult to implement as I won't know if it is spinning due to "weak guarantees" or spinning because it's actually empty/full (because both just return null) and that would leave me with a bad choice – spin until it succeeds (possibly never) or spin until some arbitrary count (accepting either latency and/or an eventual non-deterministic failure).
For example, I may have n threads offering to a queue and then one of those will "win" the fight for draining the queue. The handoff from thread-to-thread in stealing the ability to drain is important, otherwise the whole system can just stop without anyone doing any work. If a value is in the queue, but the threads think the queue is empty, they'll stop draining and wait for a notification to start again, but they may never receive a notification if the value is the last to ever be offered.
In my use case this would likely mean I stop relying on offer/poll and put my own volatile counter in front and rely on it instead to handle my thread coordination – but I believe that defeats the point of the performance optimization in a weak implementation of offer/poll.
I also think that an implementation of the
added a commit
Jul 28, 2014
referenced this issue
Jul 28, 2014
@benjchristensen internal debate over this issue continues... I agree with your sentiment, but a bit heart broken that the Queue interface which is a single threaded mindset kind of interface is forced upon this concurrent data structure.