Here comes episode 2.
The code:
public static void main(String[] args) throws IOException {
TCPNIOTransport tcpTransport =
TCPNIOTransportBuilder.newInstance().build();
tcpTransport.start();
final FilterChain clientFilterChain = FilterChainBuilder.stateless()
.add(new TransportFilter())
//.add(new DbProtocolFilter())
.build();
TCPNIOConnectorHandler connectorHandler =
TCPNIOConnectorHandler.builder(tcpTransport)
.processor(clientFilterChain)
.build();
SingleEndpointPool singleEndpointPool = SingleEndpointPool
//database connections
.builder(SocketAddress.class)
.connectorHandler(connectorHandler)
.endpointAddress(new
InetSocketAddress(InetAddress.getByName("localhost"), 12345))
.maxPoolSize(10)
.build();
HttpServer server = HttpServer.createSimpleServer(null,
"localhost", 9090);
server.getServerConfiguration().addHttpHandler(new
JsonHttpHandler(singleEndpointPool), "/users");
}
class JsonHttpHandler extends HttpHandler {
public void service(Request request, Response response) throws Exception {
final NIOInputStream in = request.getNIOInputStream();
in.notifyAvailable(new ReadHandler() {
singleEndpointPool.take(
new EmptyCompletionHandler<Connection>() {
public void completed(final Connection dbConnection) {
final AsyncQueueWriter writer = (AsyncQueueWriter)
dbConnection.getTransport().getWriter(false);
writer.write(dbConnection, new ByteBufferWrapper(dbRq), new
EmptyCompletionHandler<RecordWriteResult>() {
public void completed(RecordWriteResult result) {
final AsyncQueueReader reader = (AsyncQueueReader)
dbConnection.getTransport().getReader(false);
reader.read(dbConnection, buffer, new
CompletionHandler<ReadResult>() {
public void completed(ReadResult result) {
response.setStatus(HttpStatus.OK_200);
response.finish();
}
});
}
});
}
}
);
});
}
}
This works (reader's CompletionHandler.completed is invoked) only when
immidiate call to socketChannel.read in
org.glassfish.grizzly.nio.transport.TCPNIOUtils#readSimpleBuffer returns
all the respons bytes, the trace:
at
org.glassfish.grizzly.nio.transport.TCPNIOUtils.readSimpleBuffer(TCPNIOUtils.java:326)
at
org.glassfish.grizzly.nio.transport.TCPNIOUtils.readBuffer(TCPNIOUtils.java:285)
at
org.glassfish.grizzly.nio.transport.TCPNIOTransport.read(TCPNIOTransport.java:641)
at
org.glassfish.grizzly.nio.transport.TCPNIOAsyncQueueReader.read0(TCPNIOAsyncQueueReader.java:68)
at
org.glassfish.grizzly.nio.AbstractNIOAsyncQueueReader.doRead(AbstractNIOAsyncQueueReader.java:314)
at
org.glassfish.grizzly.nio.AbstractNIOAsyncQueueReader.read(AbstractNIOAsyncQueueReader.java:118)
at org.glassfish.grizzly.AbstractReader.read(AbstractReader.java:82)
at com.niomongo.JsonHttpHandler$1$2.completed(JsonHttpHandler.java:176)
at com.niomongo.JsonHttpHandler$1$2.completed(JsonHttpHandler.java:132)
but if db/net/whatever was a bit slow and first read returned 0 bytes, then
reader's CompletionHandler.updated is called instead of completed, and this
is of course fine. What is not so fine is that reader's CompletionHandler
never receives subsequent events from selector as the only processor my
dbConnection has is FilterChain and I don't have any filters there.
So, the qustions:
1) Is it possible to get events delivered to reader's CompletionHandler (I
remember you advised to add a filter, but still)?
And if anwer to question 1 is not, then
2) How should HttpHandler be notified that DbProtocolFilter filter finished
reading and response is ready to be produced. It also needs data from
filter's FilterChainContext.message.
Thank you for your help!
Best reagrds, Eugene.