use of net.morimekta.util.io.ByteBufferInputStream in project providence by morimekta.
the class NonblockingSocketServer method handleRead.
@SuppressWarnings("unchecked")
private void handleRead(SelectionKey key, Context context) throws IOException {
long startTime = System.nanoTime();
// part a: read into the readBuffer.
if (context.currentFrameSize == 0) {
// read frame size.
try {
if (context.channel.read(context.sizeBuffer) < 0) {
context.close();
key.cancel();
return;
}
if (context.sizeBuffer.position() < 4) {
return;
}
} catch (IOException e) {
// LOGGER.error(e.getMessage(), e);
context.close();
key.cancel();
return;
}
context.sizeBuffer.flip();
try (ByteBufferInputStream in = new ByteBufferInputStream(context.sizeBuffer);
BigEndianBinaryReader reader = new BigEndianBinaryReader(in)) {
context.currentFrameSize = reader.expectInt();
}
context.sizeBuffer.rewind();
if (context.currentFrameSize > maxFrameSizeInBytes) {
LOGGER.warn("Attempting message of " + context.currentFrameSize + " > " + maxFrameSizeInBytes);
context.close();
key.cancel();
return;
}
if (context.currentFrameSize < 1) {
LOGGER.warn("Attempting message of " + context.currentFrameSize);
context.close();
key.cancel();
return;
}
context.readBuffer.rewind();
context.readBuffer.limit(context.currentFrameSize);
}
try {
if (context.channel.read(context.readBuffer) < 0) {
LOGGER.warn("Closed connection while reading frame");
context.close();
key.cancel();
return;
}
} catch (IOException e) {
LOGGER.warn("Exception reading frame: {}", e.getMessage(), e);
context.close();
key.cancel();
return;
}
if (context.readBuffer.position() < context.readBuffer.limit()) {
// wait until next read, and see if remaining of frame has arrived.
return;
}
// part b: if the read buffer is complete, handle the content.
PServiceCall call;
try {
context.currentFrameSize = 0;
context.readBuffer.flip();
call = serializer.deserialize(new ByteBufferInputStream(context.readBuffer), processor.getDescriptor());
context.readBuffer.clear();
workerExecutor.submit(() -> {
PServiceCall reply;
try {
reply = processor.handleCall(call);
} catch (Exception e) {
reply = new PServiceCall<>(call.getMethod(), PServiceCallType.EXCEPTION, call.getSequence(), PApplicationException.builder().setMessage(e.getMessage()).setId(PApplicationExceptionType.INTERNAL_ERROR).initCause(e).build());
}
synchronized (context.writeQueue) {
context.writeQueue.offer(new WriteEntry(startTime, call, reply));
key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
selector.wakeup();
}
});
} catch (IOException e) {
double duration = ((double) System.nanoTime() - startTime) / NS_IN_MILLIS;
instrumentation.onTransportException(e, duration, null, null);
}
}
use of net.morimekta.util.io.ByteBufferInputStream in project providence by morimekta.
the class FramedBufferInputStream method readFrame.
private int readFrame() throws IOException {
frameSizeBuffer.rewind();
in.read(frameSizeBuffer);
if (frameSizeBuffer.position() == 0) {
return -1;
}
if (frameSizeBuffer.position() < Integer.BYTES) {
throw new IOException("Not enough bytes for frame size: " + frameSizeBuffer.position());
}
frameSizeBuffer.flip();
int frameSize;
try (ByteBufferInputStream in = new ByteBufferInputStream(frameSizeBuffer);
BigEndianBinaryReader reader = new BigEndianBinaryReader(in)) {
frameSize = reader.expectInt();
}
if (frameSize < 1) {
throw new IOException("Invalid frame size " + frameSize);
} else if (frameSize > buffer.capacity()) {
IOException ex = new IOException("Frame size too large " + frameSize + " > " + buffer.capacity());
try {
// Try to consume the frame so we can continue with the next.
while (frameSize > 0) {
buffer.rewind();
buffer.limit(Math.max(frameSize, buffer.capacity()));
int r = in.read(buffer);
if (r > 0) {
frameSize -= r;
} else {
break;
}
}
} catch (Exception e) {
ex.addSuppressed(e);
}
throw ex;
}
buffer.rewind();
buffer.limit(frameSize);
while (in.read(buffer) > 0) {
if (buffer.position() == frameSize) {
break;
}
LOGGER.debug("still not enough: " + buffer.position() + " of " + frameSize);
}
if (buffer.position() < frameSize) {
throw new IOException();
}
buffer.flip();
return frameSize;
}
Aggregations