Commit f44242c4 authored by Lubomir Bulej's avatar Lubomir Bulej

Modify connection handler to use SocketChannel and reuse/grow buffers

This avoids allocating a new direct ByteBuffer for every request
(and response). This is something to worry about for analysis requests,
of which there are many.

The ConnectionHandler code in the integrated "server" and the legacy
"disl-server" contains a lot of duplication, indicating the need to
create a separate project with server protocol and server utility
code to be shared.
parent 28360e62
Pipeline #6743 failed with stages
in 4 minutes and 23 seconds
......@@ -119,7 +119,7 @@ final class Server {
// Hand off the client socket to connection handler.
__workerCount.incrementAndGet ();
executor.submit (new ConnectionHandler (
__context, clientSocket.socket (), terminationCallback
__context, clientSocket, terminationCallback
));
} catch (final ClosedByInterruptException e) {
......
......@@ -34,38 +34,42 @@ public final class ByteBufferUtils {
* @param requiredByteCount The number of available bytes required in the buffer.
* @return A {@link ByteBuffer} with the required space available.
*/
public static ByteBuffer ensureCapacity (
public static ByteBuffer ensureAvailable (
final ByteBuffer buffer, final int requiredByteCount
) {
final int requiredCapacity = buffer.position () + requiredByteCount;
int newCapacity = 2 * buffer.capacity ();
while (newCapacity < requiredCapacity) {
newCapacity *= 2;
if (requiredCapacity <= buffer.capacity ()) {
return buffer;
}
// Align capacity to 4096 bytes.
final int newCapacity = (requiredCapacity + 4095) & (-1 << 12);
buffer.flip ();
return alloc (newCapacity).put (buffer);
}
/**
* Receives the given number of bytes from the given {@link SocketChannel}
* into the given {@link ByteBuffer}.
* into the given {@link ByteBuffer}. Marks the position in the buffer
* before receiving data and resets the position to the mark after receiving
* the data so that the buffer remains in read mode for processing data.
*
* @param length
* The number of bytes to receive.
* @param channel
* The socket channel to receive the data from.
* @param buffer
* The buffer to receive the data into.
*
* @throws IOException
* If an I/O error occurs.
*/
public static int recvFrom (
final int length, final SocketChannel channel, final ByteBuffer buffer
) throws IOException {
buffer.limit (buffer.position () + length);
) throws IOException {
buffer.limit (buffer.position () + length).mark ();
while (buffer.hasRemaining ()) {
final int bytesRead = channel.read (buffer);
if (bytesRead < 0) {
......@@ -73,6 +77,7 @@ public final class ByteBufferUtils {
}
}
buffer.reset ();
return length;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment