3 ms·
https://github.com/coralblocks/CoralRing/blob/1168b047e0183c9195ab48505e43e8fb2faea73d/src/main/java/com/coralblocks/coralring/ring/BlockingRingConsumer.java#L1
by kllrnohj 2y ago
https://github.com/coralblocks/CoralRing/blob/1168b047e0183c9195ab48505e43e8fb2faea73d/src/main/java/com/coralblocks/coralring/ring/BlockingRingConsumer.java#L190 https://github.com/coralblocks/CoralRing/blob/1168b047e0183c...
Am I missing something here or does the BlockingRingConsumer not actually block? And worse doesn't it just return garbage if poll is called without first checking availableToPoll?
The example sure looks like it... https://github.com/coralblocks/CoralRing/blob/main/src/main/java/com/coralblocks/coralring/example/ring/BlockingConsumer.java https://github.com/coralblocks/CoralRing/blob/main/src/main/...
Which if so isn't this like 1/4th a library for doing IPC? It doesn't seem to do much itself
- nulld3v 2y agoIt looks like these are more lower level libraries so clients are supposed to block, but they are responsible for doing the blocking themselves. And given these are designed for "ultra-low-latency" systems, I don't think that's a big problem because the best blocking strategy is probably just to spin. It would be nice if the docs were nicer though, considering this is a paid product...
- joas_coder 2y ago> It looks like these are more lower level libraries so clients are supposed to block, but they are responsible for doing the blocking themselves. You busy spin when blocking (fastest) or you can use a WaitStrategy from https://www.github.com/coralblocks/CoralQueue https://www.github.com/coralblocks/CoralQueue. You can see an example here: https://github.com/coralblocks/CoralQueue/blob/main/src/main/java/com/coralblocks/coralqueue/example/waitstrategy/Minimal.java https://github.com/coralblocks/CoralQueue/blob/main/src/main... > And given these are designed for "ultra-low-latency" systems, I don't think that's a big problem because the best blocking strategy is probably just to spin. If you have an isolated and dedicated CPU core for your thread, that's correct. Busy-spinning is the fastest/best strategy. > It would be nice if the docs were nicer though, considering this is a paid product... CoralRing and CoralQueue are open-source and free at GitHub. There are also a lot of documentation and explanations on the GitHub README.me page (front page). The code has also a lot of comments.
- nulld3v 2y agoOof, I saw "CoralQueue" on the product list on your website and I just immediately assumed it was a paid product. But I didn't even think of looking at the LICENSE files, my bad! Regarding the docs, I was only looking at CoralRing, and it looks like CoralQueue has some additional documentation that applies to CoralRing as well. After reading through them everything makes a lot more sense.
- joas_coder 2y agoavailableToPoll() is the method that blocks, because it can return 0 on an empty ring. When that happens you have to block, by for example busy spinning around availableToPoll() until it returns something to poll. You are never supposed to call poll() without first calling availableToPoll(). How can you poll something if you don't know if there is something available to poll? This is very different than a ConcurrentLinkedQueue where you can call poll() on an empty queue and get a null to indicate that the queue is empty. Also because the ring is a circular queue, you have to know what you can safely poll before polling. That's all done through availableToPoll(). NOTE: By garbage here I don't think you are talking about GC garbage.
- gpderetta 2y ago> How can you poll something if you don't know if there is something available to poll counterexample: you can call ::poll(2) if there isn't anything to available. It will either block or return as desired. That's literally what I would expect a poll function to do: check if something is available; c.f. busy-polling. Maybe it is a language difference?
- joas_coder 2y agoNot a language difference, but a design difference. By calling availableToPoll before polling you can poll a batch of messages without blocking or locking on each message. This design decision allows the ring to perform batching naturally. And batching is very important for perfomance. java.util.concurrent.ConcurrentLinkedQueue does not support batching.
- knome 2y agoI don't think anyone is questioning the strategy, just the naming. Polling, as a term, already generally means asking if there is anything ready. The library might instead have had a poll() to indicate readiness and an unsafeTakeReadyBatch()/releaseBatch() or similar to handle the low level receipt primitives. Or you could even have had a checkForReady() and left poll() to implement a generic version of your busy waiting example, polling with a given sleep and timeout until items were ready, as a convenience for the user. It's fine as is, of course, as you document expected usage quite well.