Re: Resizing the ring buffer

651 views
Skip to first unread message

Michael Barker

unread,
Apr 30, 2013, 6:52:17 PM4/30/13
to lmax-di...@googlegroups.com
No, the Disruptor does not offer this option. Note that when the ring
buffer is full you can either block (RingBuffer.publishEvent) or fail
(RingBuffer.tryPublishEvent).

We feel that having a strict bound on the depth of the ring buffer is
the right implementation. If you allow the ring buffer to resize you
are effectively allowing an unbounded queue within the system. In
which case when the consumers are failing behind the producers, then
you have only one failure mode, which is to crash with an out of
memory error. With the bounded queue you set a limit to how far
behind you allow the consumers to get and when that limit is reached
you can make an informed decision on the appropriate action. As to
what that appropriate action should be will depend on your
application, unfortunately this is a question with no easy or
generalisable answer.

Mike.

On Wed, May 1, 2013 at 10:36 AM, Rajiv Kurian <geet...@gmail.com> wrote:
> I have a use case with multiple concurrent producers but a single consumer.
> Is there a way for me to resize the ring buffer. My understanding is that if
> a producer is trying to add to a full ring buffer it would block till the
> consumer catches up. Could I instead under such a condition resize the ring
> buffer instead and keep the producer(s) blocking till then?
>
> Thanks,
> Rajiv
>
> --
> You received this message because you are subscribed to the Google Groups
> "Disruptor" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to lmax-disrupto...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Rajiv Kurian

unread,
Apr 30, 2013, 7:57:31 PM4/30/13
to lmax-di...@googlegroups.com
I see the philosophical reason for putting a bound on the depth of the ring buffer. 

I am trying to actually see if I could use a ring buffer (with multiple producers and a single consumer) to implement an actor mailbox instead of the typical ConcurrentLinkedQueue etc. Since actors are used to model concurrent but not necessarily parallel entities I'd prefer to be able to create a lot of them (one per user session, one per chat room etc). The fixed size of the ring buffer would make it difficult to use since these entities are not very symmetric. For eg: A particular chatroom could have a disproportionately high number of users or a particular user could have way too many photos. There would be no good upper bound for a buffer size across similar entities.

If we ignore the implications on system design for a moment, do you think it would be prudent to try and implement a resizable ring buffer and still benefit from most of the factors that make their performance characteristics so awesome. My only goal is to get a more performant ConcurrentLinkedQueue.

Thanks,
Rajiv

jo...@mentics.com

unread,
Apr 30, 2013, 8:04:28 PM4/30/13
to lmax-di...@googlegroups.com
Here are a few possibilities:

1) Not all applications are ideal for a ring buffer. If yours is not,
don't use it. Use a screwdriver for screws, hammer for nails, etc.

2) If you need to resize it, maybe you didn't size it correctly in the first
place? Make it bigger to start with.

3) When the buffer gets full at runtime, create a new bigger ring
buffer and switch over to
using that. So instead of "resizing" one, just switch over to using a
bigger one. Given that it's backed by an array, this is exactly what
would happen if it was resizable. So, you can do it at the application
level already.

Rajiv Kurian

unread,
Apr 30, 2013, 8:41:01 PM4/30/13
to lmax-di...@googlegroups.com, jo...@mentics.com

(1) Completely agree. I am doing this for academic reasons i.e seeing if I can use a ring buffer to get a more performant ConcurrentLinkedQueue replacement.
(2) I am trying to use this to build a mailbox for an actor. Actor based systems have 100s of thousands of concurrent entities which differ in size requirement. If each user on the system had a ring buffer instead of a concurrent linked queue there is no right size since users differ in how many incoming messages they have. Your point (1) applies again in that maybe this is not a good use for disruptor. Again I am only doing this for academic reasons.
(3) Sounds like a good idea. My understanding of Disruptor is that multiple producers and consumers coordinate through barriers. Would my logic for ring buffer replacement be on the producer and consumer barriers then (instead of the ring buffer)?

Thanks,
Rajiv

Michael Barker

unread,
Apr 30, 2013, 8:57:20 PM4/30/13
to lmax-di...@googlegroups.com, jo...@mentics.com
It depends what you want to optimise for. Most actor implementation
aim for really large numbers of actors each with a very small
footprint. This makes the Disruptor with it's bounded and
preallocated buffer a less appealing choice for the per-actor mailbox.
This topic did come up on the concurrency interest list recently and
I made a few suggestions[0]. If you want to support the low footprint
per-actor model then you'll probably need something list backed rather
than array backed.

I don't think adding resizing support to the Disruptor is a good idea.
For use cases that need that behaviour I think using the Disruptor is
the wrong choice.

[0] http://jsr166-concurrency.10961.n7.nabble.com/Quest-for-the-optimal-queue-td6994.html

Rajiv Kurian

unread,
Apr 30, 2013, 10:01:20 PM4/30/13
to lmax-di...@googlegroups.com, jo...@mentics.com
Thank you Mike. I'll read through it.
Reply all
Reply to author
Forward
0 new messages