use of io.pravega.shared.protocol.netty.WireCommands.AppendBlock in project pravega by pravega.
the class CommandEncoder method encode.
@Override
protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
log.trace("Encoding message to send over the wire {}", msg);
if (msg instanceof Append) {
Append append = (Append) msg;
Session session = setupSegments.get(append.segment);
if (session == null || !session.id.equals(append.getWriterId())) {
throw new InvalidMessageException("Sending appends without setting up the append.");
}
if (append.getEventNumber() <= session.lastEventNumber) {
throw new InvalidMessageException("Events written out of order. Received: " + append.getEventNumber() + " following: " + session.lastEventNumber);
}
if (append.isConditional()) {
breakFromAppend(out);
ConditionalAppend ca = new ConditionalAppend(append.writerId, append.eventNumber, append.getExpectedLength(), wrappedBuffer(serializeMessage(new Event(append.getData()))));
writeMessage(ca, out);
} else {
Preconditions.checkState(bytesLeftInBlock == 0 || bytesLeftInBlock > TYPE_PLUS_LENGTH_SIZE, "Bug in CommandEncoder.encode, block is too small.");
if (append.segment != segmentBeingAppendedTo) {
breakFromAppend(out);
}
if (bytesLeftInBlock == 0) {
currentBlockSize = Math.max(TYPE_PLUS_LENGTH_SIZE, blockSizeSupplier.getAppendBlockSize());
bytesLeftInBlock = currentBlockSize;
segmentBeingAppendedTo = append.segment;
writeMessage(new AppendBlock(session.id), out);
if (ctx != null) {
ctx.executor().schedule(new Flusher(ctx.channel(), currentBlockSize), blockSizeSupplier.getBatchTimeout(), TimeUnit.MILLISECONDS);
}
}
session.lastEventNumber = append.getEventNumber();
session.eventCount++;
ByteBuf data = append.getData();
int msgSize = TYPE_PLUS_LENGTH_SIZE + data.readableBytes();
// Is there enough space for a subsequent message after this one?
if (bytesLeftInBlock - msgSize > TYPE_PLUS_LENGTH_SIZE) {
bytesLeftInBlock -= writeMessage(new Event(data), out);
} else {
byte[] serializedMessage = serializeMessage(new Event(data));
int bytesInBlock = bytesLeftInBlock - TYPE_PLUS_LENGTH_SIZE;
ByteBuf dataInsideBlock = wrappedBuffer(serializedMessage, 0, bytesInBlock);
ByteBuf dataRemainging = wrappedBuffer(serializedMessage, bytesInBlock, serializedMessage.length - bytesInBlock);
writeMessage(new PartialEvent(dataInsideBlock), out);
writeMessage(new AppendBlockEnd(session.id, currentBlockSize - bytesLeftInBlock, dataRemainging, session.eventCount, session.lastEventNumber, 0L), out);
bytesLeftInBlock = 0;
session.eventCount = 0;
}
}
} else if (msg instanceof SetupAppend) {
breakFromAppend(out);
writeMessage((SetupAppend) msg, out);
SetupAppend setup = (SetupAppend) msg;
setupSegments.put(setup.getSegment(), new Session(setup.getWriterId()));
} else if (msg instanceof Flush) {
Flush flush = (Flush) msg;
if (currentBlockSize == flush.getBlockSize()) {
breakFromAppend(out);
}
} else if (msg instanceof WireCommand) {
breakFromAppend(out);
writeMessage((WireCommand) msg, out);
} else {
throw new IllegalArgumentException("Expected a wire command and found: " + msg);
}
}
Aggregations