public final class ManyToOneRingBuffer extends Object implements RingBuffer
INSUFFICIENT_CAPACITY, PADDING_MSG_TYPE_ID
Constructor and Description |
---|
ManyToOneRingBuffer(AtomicBuffer buffer)
Construct a new
RingBuffer based on an underlying AtomicBuffer . |
Modifier and Type | Method and Description |
---|---|
void |
abort(int index)
Abort claim and allow consumer to proceed after the claimed length.
|
AtomicBuffer |
buffer()
Get the underlying buffer used by the RingBuffer for storage.
|
int |
capacity()
Get the capacity of the ring-buffer in bytes for exchange.
|
void |
commit(int index)
Commit message that was written in the previously claimed space thus making it available to the consumer.
|
long |
consumerHeartbeatTime()
The time of the last consumer heartbeat.
|
void |
consumerHeartbeatTime(long time)
Set the time of the last consumer heartbeat.
|
long |
consumerPosition()
The position in bytes from start up for the consumers.
|
int |
controlledRead(ControlledMessageHandler handler)
Read as many messages as are available to the end of the ring buffer with the handler able to control progress.
|
int |
controlledRead(ControlledMessageHandler handler,
int messageCountLimit)
Read messages up to a limit of available to the end of the ring buffer with the handler able to control progress.
|
int |
maxMsgLength()
The maximum message length in bytes supported by the underlying ring buffer.
|
long |
nextCorrelationId()
Get the next value that can be used for a correlation id on an message when a response needs to be correlated.
|
long |
producerPosition()
The position in bytes from start up of the producers.
|
int |
read(MessageHandler handler)
Read as many messages as are available to the end of the ring buffer.
|
int |
read(MessageHandler handler,
int messageCountLimit)
Read as many messages as are available to end of the ring buffer to up a supplied maximum.
|
int |
size()
Size of the buffer backlog in bytes between producers and consumers.
|
int |
tryClaim(int msgTypeId,
int length)
Try to claim a space in the underlying ring-buffer into which a message can be written with zero copy semantics.
|
boolean |
unblock()
Unblock a multi-producer ring buffer when a producer has died during the act of offering.
|
boolean |
write(int msgTypeId,
DirectBuffer srcBuffer,
int offset,
int length)
Non-blocking write of an message to an underlying ring-buffer.
|
public ManyToOneRingBuffer(AtomicBuffer buffer)
RingBuffer
based on an underlying AtomicBuffer
.
The underlying buffer must a power of 2 in size plus sufficient space
for the RingBufferDescriptor.TRAILER_LENGTH
.buffer
- via which events will be exchanged.IllegalStateException
- if the buffer capacity is not a power of 2
plus RingBufferDescriptor.TRAILER_LENGTH
in capacity.public int capacity()
capacity
in interface RingBuffer
public boolean write(int msgTypeId, DirectBuffer srcBuffer, int offset, int length)
write
in interface RingBuffer
msgTypeId
- type of the message encoding.srcBuffer
- containing the encoded binary message.offset
- at which the encoded message begins.length
- of the encoded message in bytes.public int tryClaim(int msgTypeId, int length)
RingBuffer.commit(int)
should be called thus making it available to be
consumed. Alternatively a claim can be aborted using RingBuffer.abort(int)
method.
Claiming a space in the ring-buffer means that the consumer will not be able to consume past the claim until the claimed space is either committed or aborted. Producers will be able to write message even when outstanding claims exist.
An example of using tryClaim
:
final RingBuffer ringBuffer = ...;
final int index = ringBuffer.tryClaim(msgTypeId, messageLength);
if (index > 0)
{
try
{
final AtomicBuffer buffer = ringBuffer.buffer();
// Work with the buffer directly using the index
...
}
finally
{
ringBuffer.commit(index); // commit message
}
}
Ensure that claimed space is released even in case of an exception:
final RingBuffer ringBuffer = ...;
final int index = ringBuffer.tryClaim(msgTypeId, messageLength);
if (index > 0)
{
try
{
final AtomicBuffer buffer = ringBuffer.buffer();
// Work with the buffer directly using the index
...
ringBuffer.commit(index); // commit message
}
catch (final Throwable t)
{
ringBuffer.abort(index); // allow consumer to proceed
...
}
}
tryClaim
in interface RingBuffer
msgTypeId
- type of the message encoding. Will be written into the header upon successful claim.length
- of the claim in bytes. A claim length cannot be greater than RingBuffer.maxMsgLength()
.RingBuffer.INSUFFICIENT_CAPACITY
indicating that there is not enough free space in the buffer.RingBuffer.commit(int)
,
RingBuffer.abort(int)
public void commit(int index)
commit
in interface RingBuffer
index
- at which the encoded message begins, i.e. value returned from the RingBuffer.tryClaim(int, int)
call.RingBuffer.tryClaim(int, int)
public void abort(int index)
RingBuffer.PADDING_MSG_TYPE_ID
.abort
in interface RingBuffer
index
- at which the encoded message begins, i.e. value returned from the RingBuffer.tryClaim(int, int)
call.RingBuffer.tryClaim(int, int)
public int read(MessageHandler handler)
If the ring buffer wraps or encounters a type of record, such a a padding record, then an implementation
may choose to return and expect the caller to try again. The RingBuffer.size()
method may be called to
determine of a backlog of message bytes remains in the ring buffer.
read
in interface RingBuffer
handler
- to be called for processing each message in turn.public int read(MessageHandler handler, int messageCountLimit)
If the ring buffer wraps or encounters a type of record, such a a padding record, then an implementation
may choose to return and expect the caller to try again. The RingBuffer.size()
method may be called to
determine of a backlog of message bytes remains in the ring buffer.
read
in interface RingBuffer
handler
- to be called for processing each message in turn.messageCountLimit
- the number of messages will be read in a single invocation.public int controlledRead(ControlledMessageHandler handler)
If the ring buffer wraps or encounters a type of record, such a a padding record, then an implementation
may choose to return and expect the caller to try again. The RingBuffer.size()
method may be called to
determine of a backlog of message bytes remains in the ring buffer.
controlledRead
in interface RingBuffer
handler
- to be called for processing each message in turn which will return how to progress.public int controlledRead(ControlledMessageHandler handler, int messageCountLimit)
If the ring buffer wraps or encounters a type of record, such a a padding record, then an implementation
may choose to return and expect the caller to try again. The RingBuffer.size()
method may be called to
determine of a backlog of message bytes remains in the ring buffer.
controlledRead
in interface RingBuffer
handler
- to be called for processing each message in turn which will return how to progress.messageCountLimit
- the number of messages will be read in a single invocation.public int maxMsgLength()
maxMsgLength
in interface RingBuffer
public long nextCorrelationId()
This method should be thread safe.
nextCorrelationId
in interface RingBuffer
public AtomicBuffer buffer()
buffer
in interface RingBuffer
public void consumerHeartbeatTime(long time)
Note: The value for time must be valid across processes which means System.nanoTime()
is not a valid option.
consumerHeartbeatTime
in interface RingBuffer
time
- of the last consumer heartbeat.public long consumerHeartbeatTime()
consumerHeartbeatTime
in interface RingBuffer
public long producerPosition()
producerPosition
in interface RingBuffer
public long consumerPosition()
consumerPosition
in interface RingBuffer
public int size()
This method gives a concurrent snapshot of the buffer whereby a concurrent read or write may be partially complete and thus the value should be taken as an indication.
size
in interface RingBuffer
public boolean unblock()
If no action is required at the position then none will be taken.
unblock
in interface RingBuffer
Copyright © 2014-2021 Real Logic Limited. All Rights Reserved.