use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class TermAppender method claim.
/**
* Claim length of a the term buffer for writing in the message with zero copy semantics.
*
* @param header for writing the default header.
* @param length of the message to be written.
* @param bufferClaim to be updated with the claimed region.
* @return the resulting offset of the term after the append on success otherwise {@link #TRIPPED}
* or {@link #FAILED} packed with the termId if a padding record was inserted at the end.
*/
public long claim(final HeaderWriter header, final int length, final BufferClaim bufferClaim) {
final int frameLength = length + HEADER_LENGTH;
final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
final long rawTail = getAndAddRawTail(alignedLength);
final long termOffset = rawTail & 0xFFFF_FFFFL;
final UnsafeBuffer termBuffer = this.termBuffer;
final int termLength = termBuffer.capacity();
long resultingOffset = termOffset + alignedLength;
if (resultingOffset > termLength) {
resultingOffset = handleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId(rawTail));
} else {
final int offset = (int) termOffset;
header.write(termBuffer, offset, frameLength, termId(rawTail));
bufferClaim.wrap(termBuffer, offset, frameLength);
}
return resultingOffset;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class TermAppender method appendFragmentedMessage.
/**
* Append a fragmented message to the the term buffer.
* The message will be split up into fragments of MTU length minus header.
*
* @param header for writing the default header.
* @param srcBuffer containing the message.
* @param srcOffset at which the message begins.
* @param length of the message in the source buffer.
* @param maxPayloadLength that the message will be fragmented into.
* @param reservedValueSupplier {@link ReservedValueSupplier} for the frame.
* @return the resulting offset of the term after the append on success otherwise {@link #TRIPPED}
* or {@link #FAILED} packed with the termId if a padding record was inserted at the end.
*/
public long appendFragmentedMessage(final HeaderWriter header, final DirectBuffer srcBuffer, final int srcOffset, final int length, final int maxPayloadLength, final ReservedValueSupplier reservedValueSupplier) {
final int numMaxPayloads = length / maxPayloadLength;
final int remainingPayload = length % maxPayloadLength;
final int lastFrameLength = remainingPayload > 0 ? align(remainingPayload + HEADER_LENGTH, FRAME_ALIGNMENT) : 0;
final int requiredLength = (numMaxPayloads * (maxPayloadLength + HEADER_LENGTH)) + lastFrameLength;
final long rawTail = getAndAddRawTail(requiredLength);
final int termId = termId(rawTail);
final long termOffset = rawTail & 0xFFFF_FFFFL;
final UnsafeBuffer termBuffer = this.termBuffer;
final int termLength = termBuffer.capacity();
long resultingOffset = termOffset + requiredLength;
if (resultingOffset > termLength) {
resultingOffset = handleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
} else {
int offset = (int) termOffset;
byte flags = BEGIN_FRAG_FLAG;
int remaining = length;
do {
final int bytesToWrite = Math.min(remaining, maxPayloadLength);
final int frameLength = bytesToWrite + HEADER_LENGTH;
final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
header.write(termBuffer, offset, frameLength, termId);
termBuffer.putBytes(offset + HEADER_LENGTH, srcBuffer, srcOffset + (length - remaining), bytesToWrite);
if (remaining <= maxPayloadLength) {
flags |= END_FRAG_FLAG;
}
frameFlags(termBuffer, offset, flags);
if (null != reservedValueSupplier) {
final long reservedValue = reservedValueSupplier.get(termBuffer, offset, frameLength);
termBuffer.putLong(offset + RESERVED_VALUE_OFFSET, reservedValue, LITTLE_ENDIAN);
}
frameLengthOrdered(termBuffer, offset, frameLength);
flags = 0;
offset += alignedLength;
remaining -= bytesToWrite;
} while (remaining > 0);
}
return resultingOffset;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class DriverConductorTest method shouldTimeoutPublicationWithNoKeepaliveButNotFlushed.
@Test
public void shouldTimeoutPublicationWithNoKeepaliveButNotFlushed() throws Exception {
driverProxy.addPublication(CHANNEL_4000, STREAM_ID_1);
driverConductor.doWork();
final ArgumentCaptor<NetworkPublication> captor = ArgumentCaptor.forClass(NetworkPublication.class);
verify(senderProxy, times(1)).newNetworkPublication(captor.capture());
final NetworkPublication publication = captor.getValue();
final int termId = 101;
final int index = LogBufferDescriptor.indexByTerm(termId, termId);
final RawLog rawLog = publication.rawLog();
final TermAppender appender = new TermAppender(rawLog.termBuffers()[index], rawLog.metaData(), index);
final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[256]);
final HeaderWriter headerWriter = new HeaderWriter(createDefaultHeader(publication.sessionId(), STREAM_ID_1, termId));
final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class);
when(msg.consumptionTermId()).thenReturn(termId);
when(msg.consumptionTermOffset()).thenReturn(0);
when(msg.receiverWindowLength()).thenReturn(10);
publication.onStatusMessage(msg, new InetSocketAddress("localhost", 4059));
appender.appendUnfragmentedMessage(headerWriter, srcBuffer, 0, 256, null);
doWorkUntil(() -> nanoClock.nanoTime() >= PUBLICATION_LINGER_NS + CLIENT_LIVENESS_TIMEOUT_NS * 2);
assertTrue(publication.hasReachedEndOfLife());
verify(senderProxy).removeNetworkPublication(eq(publication));
assertNull(driverConductor.senderChannelEndpoint(UdpChannel.parse(CHANNEL_4000)));
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class DriverConductorTest method setUp.
@Before
public void setUp() throws Exception {
// System GC required in order to ensure that the direct byte buffers get cleaned and avoid OOM.
System.gc();
when(mockRawLogFactory.newNetworkPublication(anyString(), anyInt(), anyInt(), anyLong(), anyInt())).thenReturn(LogBufferHelper.newTestLogBuffers(TERM_BUFFER_LENGTH));
when(mockRawLogFactory.newNetworkedImage(anyString(), anyInt(), anyInt(), anyLong(), eq(TERM_BUFFER_LENGTH))).thenReturn(LogBufferHelper.newTestLogBuffers(TERM_BUFFER_LENGTH));
when(mockRawLogFactory.newIpcPublication(anyInt(), anyInt(), anyLong(), anyInt())).thenReturn(LogBufferHelper.newTestLogBuffers(TERM_BUFFER_LENGTH));
currentTimeNs = 0;
final UnsafeBuffer counterBuffer = new UnsafeBuffer(ByteBuffer.allocateDirect(BUFFER_LENGTH));
final CountersManager countersManager = new CountersManager(new UnsafeBuffer(ByteBuffer.allocateDirect(BUFFER_LENGTH * 2)), counterBuffer);
final MediaDriver.Context ctx = new MediaDriver.Context().unicastFlowControlSupplier(Configuration.unicastFlowControlSupplier()).multicastFlowControlSupplier(Configuration.multicastFlowControlSupplier()).toConductorFromReceiverCommandQueue(new OneToOneConcurrentArrayQueue<>(1024)).toConductorFromSenderCommandQueue(new OneToOneConcurrentArrayQueue<>(1024)).errorLog(mockErrorLog).rawLogBuffersFactory(mockRawLogFactory).countersManager(countersManager).nanoClock(nanoClock).sendChannelEndpointSupplier(Configuration.sendChannelEndpointSupplier()).receiveChannelEndpointSupplier(Configuration.receiveChannelEndpointSupplier()).congestControlSupplier(Configuration.congestionControlSupplier());
ctx.toDriverCommands(fromClientCommands);
ctx.clientProxy(mockClientProxy);
ctx.countersValuesBuffer(counterBuffer);
final SystemCounters mockSystemCounters = mock(SystemCounters.class);
ctx.systemCounters(mockSystemCounters);
when(mockSystemCounters.get(any())).thenReturn(mockErrorCounter);
ctx.epochClock(new SystemEpochClock());
ctx.receiverProxy(receiverProxy);
ctx.senderProxy(senderProxy);
ctx.fromReceiverDriverConductorProxy(fromReceiverConductorProxy);
ctx.fromSenderDriverConductorProxy(fromSenderConductorProxy);
ctx.clientLivenessTimeoutNs(CLIENT_LIVENESS_TIMEOUT_NS);
ctx.receiveChannelEndpointThreadLocals(new ReceiveChannelEndpointThreadLocals(ctx));
driverProxy = new DriverProxy(fromClientCommands);
driverConductor = new DriverConductor(ctx);
doAnswer(closeChannelEndpointAnswer).when(receiverProxy).closeReceiveChannelEndpoint(any());
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class IpcPublication method cleanBuffer.
private void cleanBuffer(final long minConsumerPosition) {
final long cleanPosition = this.cleanPosition;
final UnsafeBuffer dirtyTerm = termBuffers[indexByPosition(cleanPosition, positionBitsToShift)];
final int bytesForCleaning = (int) (minConsumerPosition - cleanPosition);
final int bufferCapacity = dirtyTerm.capacity();
final int termOffset = (int) cleanPosition & (bufferCapacity - 1);
final int length = Math.min(bytesForCleaning, bufferCapacity - termOffset);
if (length > 0) {
dirtyTerm.setMemory(termOffset, length, (byte) 0);
this.cleanPosition = cleanPosition + length;
}
}
Aggregations