use of io.pravega.shared.protocol.netty.Append in project pravega by pravega.
the class ClientConnectionInboundHandler method sendAsync.
@Override
public void sendAsync(List<Append> appends, CompletedCallback callback) {
recentMessage.set(true);
Channel ch;
try {
ch = getChannel();
} catch (ConnectionFailedException e) {
callback.complete(new ConnectionFailedException("Connection to " + connectionName + " is not established."));
return;
}
PromiseCombiner combiner = new PromiseCombiner();
for (Append append : appends) {
batchSizeTracker.recordAppend(append.getEventNumber(), append.getData().readableBytes());
combiner.add(ch.write(append));
}
ch.flush();
ChannelPromise promise = ch.newPromise();
promise.addListener(new GenericFutureListener<Future<? super Void>>() {
@Override
public void operationComplete(Future<? super Void> future) throws Exception {
Throwable cause = future.cause();
callback.complete(cause == null ? null : new ConnectionFailedException(cause));
}
});
combiner.finish(promise);
}
use of io.pravega.shared.protocol.netty.Append in project pravega by pravega.
the class AppendProcessor method getNextAppend.
private Append getNextAppend() {
synchronized (lock) {
if (outstandingAppend != null || waitingAppends.isEmpty()) {
return null;
}
UUID writer = waitingAppends.keys().iterator().next();
List<Append> appends = waitingAppends.get(writer);
if (appends.get(0).isConditional()) {
outstandingAppend = appends.remove(0);
} else {
ByteBuf[] toAppend = new ByteBuf[appends.size()];
Append last = appends.get(0);
int eventCount = 0;
int i = -1;
for (Iterator<Append> iterator = appends.iterator(); iterator.hasNext(); ) {
Append a = iterator.next();
if (a.isConditional()) {
break;
}
i++;
toAppend[i] = a.getData();
last = a;
eventCount += a.getEventCount();
iterator.remove();
}
ByteBuf data = Unpooled.wrappedBuffer(toAppend);
String segment = last.getSegment();
long eventNumber = last.getEventNumber();
outstandingAppend = new Append(segment, writer, eventNumber, eventCount, data, null);
}
return outstandingAppend;
}
}
use of io.pravega.shared.protocol.netty.Append in project pravega by pravega.
the class AppendProcessor method performNextWrite.
/**
* If there isn't already an append outstanding against the store, write a new one.
* Appends are opportunistically batched here. i.e. If many are waiting they are combined into a single append and
* that is written.
*/
private void performNextWrite() {
Append append = getNextAppend();
if (append == null) {
return;
}
long traceId = LoggerHelpers.traceEnter(log, "storeAppend", append);
Timer timer = new Timer();
storeAppend(append).whenComplete((v, e) -> {
handleAppendResult(append, e);
LoggerHelpers.traceLeave(log, "storeAppend", traceId, v, e);
if (e == null) {
WRITE_STREAM_SEGMENT.reportSuccessEvent(timer.getElapsed());
} else {
WRITE_STREAM_SEGMENT.reportFailEvent(timer.getElapsed());
}
}).whenComplete((v, e) -> append.getData().release());
}
use of io.pravega.shared.protocol.netty.Append in project pravega by pravega.
the class ClientConnectionInboundHandlerTest method setUp.
@Before
public void setUp() throws Exception {
when(buffer.readableBytes()).thenReturn(10);
appendCmd = new Append("segment0", UUID.randomUUID(), 2, buffer, 10L);
doNothing().when(tracker).recordAppend(anyLong(), anyInt());
when(ctx.channel()).thenReturn(ch);
when(ch.eventLoop()).thenReturn(loop);
when(ch.writeAndFlush(any(Object.class))).thenReturn(completedFuture);
handler = new ClientConnectionInboundHandler("testConnection", processor, tracker);
}
use of io.pravega.shared.protocol.netty.Append in project pravega by pravega.
the class SegmentOutputStreamTest method testFailDurringFlush.
@Test(timeout = 10000)
public void testFailDurringFlush() throws ConnectionFailedException {
UUID cid = UUID.randomUUID();
PravegaNodeUri uri = new PravegaNodeUri("endpoint", SERVICE_PORT);
MockConnectionFactoryImpl cf = new MockConnectionFactoryImpl();
ScheduledExecutorService executor = mock(ScheduledExecutorService.class);
// Ensure task submitted to executor is run inline.
implementAsDirectExecutor(executor);
cf.setExecutor(executor);
MockController controller = new MockController(uri.getEndpoint(), uri.getPort(), cf);
ClientConnection connection = mock(ClientConnection.class);
cf.provideConnection(uri, connection);
InOrder order = Mockito.inOrder(connection);
SegmentOutputStreamImpl output = new SegmentOutputStreamImpl(SEGMENT, controller, cf, cid, segmentSealedCallback, RETRY_SCHEDULE, "");
output.reconnect();
order.verify(connection).send(new SetupAppend(1, cid, SEGMENT, ""));
cf.getProcessor(uri).appendSetup(new AppendSetup(1, SEGMENT, cid, 0));
ByteBuffer data = getBuffer("test");
CompletableFuture<Boolean> ack = new CompletableFuture<>();
output.write(new PendingEvent(null, data, ack));
order.verify(connection).send(new Append(SEGMENT, cid, 1, Unpooled.wrappedBuffer(data), null));
assertEquals(false, ack.isDone());
Mockito.doThrow(new ConnectionFailedException()).when(connection).send(new WireCommands.KeepAlive());
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
cf.getProcessor(uri).appendSetup(new AppendSetup(3, SEGMENT, cid, 1));
return null;
}
}).when(connection).send(new SetupAppend(3, cid, SEGMENT, ""));
Async.testBlocking(() -> {
output.flush();
}, () -> {
cf.getProcessor(uri).connectionDropped();
});
order.verify(connection).send(new SetupAppend(3, cid, SEGMENT, ""));
assertEquals(true, ack.isDone());
}
Aggregations