use of voldemort.server.protocol.StreamRequestHandler.StreamRequestHandlerState in project voldemort by voldemort.
the class AsyncRequestHandler method handleStreamRequest.
private void handleStreamRequest(SelectionKey selectionKey) throws IOException {
// You are not expected to understand this.
DataInputStream dataInputStream = new DataInputStream(inputStream);
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
// We need to keep track of the last known starting index *before* we
// attempt to service the next segment. This is needed in case of
// partial reads so that we can revert back to this point.
int preRequestPosition = inputStream.getBuffer().position();
StreamRequestHandlerState state = handleStreamRequestInternal(selectionKey, dataInputStream, dataOutputStream);
if (state == StreamRequestHandlerState.READING) {
// until we're no longer reading anything.
do {
preRequestPosition = inputStream.getBuffer().position();
state = handleStreamRequestInternal(selectionKey, dataInputStream, dataOutputStream);
} while (state == StreamRequestHandlerState.READING);
} else if (state == StreamRequestHandlerState.WRITING) {
// or until we blow past our buffer.
do {
state = handleStreamRequestInternal(selectionKey, dataInputStream, dataOutputStream);
} while (state == StreamRequestHandlerState.WRITING && !outputStream.wasExpanded());
if (state != StreamRequestHandlerState.COMPLETE) {
// We've read our request and are ready to start streaming
// writes to the client.
prepForWrite(selectionKey);
}
}
if (state == null) {
// We got an error...
return;
}
if (state == StreamRequestHandlerState.INCOMPLETE_READ) {
// We need the data that's in there so far and aren't ready to write
// anything out yet, so don't clear the input buffer or signal that
// we're ready to write. But we do want to compact the buffer as we
// don't want it to trigger an increase in the buffer if we don't
// need to do so.
// We need to do the following steps...
//
// a) ...figure out where we are in the buffer...
int currentPosition = inputStream.getBuffer().position();
// b) ...position ourselves at the start of the incomplete
// "segment"...
inputStream.getBuffer().position(preRequestPosition);
// c) ...then copy the data starting from preRequestPosition's data
// is at index 0...
inputStream.getBuffer().compact();
// d) ...and reset the position to be ready for the rest of the
// reads and the limit to allow more data.
handleIncompleteRequest(currentPosition - preRequestPosition);
} else if (state == StreamRequestHandlerState.COMPLETE) {
streamRequestHandler.close(dataOutputStream);
streamRequestHandler = null;
// Treat this as a normal request. Assume that all completed
// requests want to write something back to the client.
prepForWrite(selectionKey);
}
}
use of voldemort.server.protocol.StreamRequestHandler.StreamRequestHandlerState in project voldemort by voldemort.
the class AsyncRequestHandler method handleStreamRequestInternal.
private StreamRequestHandlerState handleStreamRequestInternal(SelectionKey selectionKey, DataInputStream dataInputStream, DataOutputStream dataOutputStream) throws IOException {
StreamRequestHandlerState state = null;
try {
if (logger.isTraceEnabled())
traceInputBufferState("Before streaming request handler");
// this is the lowest level in the NioSocketServer stack at which we
// still have a reference to the client IP address and port
long startNs = -1;
if (logger.isDebugEnabled())
startNs = System.nanoTime();
state = streamRequestHandler.handleRequest(dataInputStream, dataOutputStream);
if (logger.isDebugEnabled()) {
logger.debug("Handled request from " + socketChannel.socket().getRemoteSocketAddress() + " handlerRef: " + System.identityHashCode(dataInputStream) + " at time: " + System.currentTimeMillis() + " elapsed time: " + (System.nanoTime() - startNs) + " ns");
}
if (logger.isTraceEnabled())
traceInputBufferState("After streaming request handler");
} catch (Exception e) {
if (logger.isEnabledFor(Level.WARN))
logger.warn(e.getMessage(), e);
VoldemortException error = e instanceof VoldemortException ? (VoldemortException) e : new VoldemortException(e);
streamRequestHandler.handleError(dataOutputStream, error);
closeStreamRequestHandler(dataOutputStream);
streamRequestHandler = null;
prepForWrite(selectionKey);
close();
}
return state;
}
use of voldemort.server.protocol.StreamRequestHandler.StreamRequestHandlerState in project voldemort by voldemort.
the class SocketServerSession method run.
public void run() {
try {
activeSessions.put(sessionId, this);
DataInputStream inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream(), 64000));
DataOutputStream outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), 64000));
RequestFormatType protocol = negotiateProtocol(inputStream, outputStream);
RequestHandler handler = handlerFactory.getRequestHandler(protocol);
logger.info("Client " + socket.getRemoteSocketAddress() + " connected successfully with protocol " + protocol.getCode());
while (!isInterrupted() && !socket.isClosed() && !isClosed) {
StreamRequestHandler srh = handler.handleRequest(inputStream, outputStream);
if (srh != null) {
if (logger.isTraceEnabled())
logger.trace("Request is streaming");
StreamRequestHandlerState srhs = null;
try {
do {
if (logger.isTraceEnabled())
logger.trace("About to enter streaming request handler");
srhs = srh.handleRequest(inputStream, outputStream);
if (logger.isTraceEnabled())
logger.trace("Finished invocation of streaming request handler, result is " + srhs);
} while (srhs != StreamRequestHandlerState.COMPLETE);
} catch (VoldemortException e) {
srh.handleError(outputStream, e);
outputStream.flush();
break;
} finally {
srh.close(outputStream);
}
}
outputStream.flush();
}
if (isInterrupted())
logger.info(Thread.currentThread().getName() + " has been interrupted, closing session.");
} catch (EOFException e) {
logger.info("Client " + socket.getRemoteSocketAddress() + " disconnected.");
} catch (IOException e) {
// if this is an unexpected
if (!isClosed)
logger.error(e);
} finally {
try {
if (!socket.isClosed())
socket.close();
} catch (Exception e) {
logger.error("Error while closing socket", e);
}
// now remove ourselves from the set of active sessions
this.activeSessions.remove(sessionId);
}
}
Aggregations