users@grizzly.java.net

Re: Read doesn't work

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Fri, 21 Nov 2014 12:11:42 -0800

Hi,

in general the idea is correct, the only concern I have is that you try
to make
HttpHandler I/O non-blocking, but at the same time the client-side code
inside HttpHandler is blocking.

I can suggest following changes:

1) Retrieve client connection from pool using CompletionHandler:

/ pool.take(new EmptyCompletionHandler<Connection>() {//
//
// @Override//
// public void completed(final Connection connection) {//
// ....//
// }//
////
// });//
/
2) Connection.read(), as you probably noticed doesn't work (it works
only in a specific case), I'd suggest to rework this part to be
non-blocking as well
The solution could be similar to what is described in the cookbook [1].

I'd also suggest to implement a client-side DbProtocolFilter, which will
be able to decode DB responses and pass it to the next Filter, only when
entire response is received.
But I can help here only if I know the underlying DB protocol.

Thanks.

WBR,
Alexey.

[1] https://grizzly.java.net/cookbook.html

On 21.11.14 11:28, Евгений Бушуев wrote:
> Hello,
>
>
> Need your help for my problem. I'm trying to write json <-> db service
> with custom 'nio' connection to my database (no jdbc driver). In
> short the code so far looks lie:
>
> public static voidmain(String[] args)throwsIOException {
>
> TCPNIOTransport tcpTransport = TCPNIOTransportBuilder.newInstance().build();
> tcpTransport.start();
>
>
> finalFilterChain clientFilterChain = FilterChainBuilder.stateless()
> .add(newTransportFilter())
> .build();
>
> TCPNIOConnectorHandler connectorHandler = TCPNIOConnectorHandler.builder(tcpTransport)
> .processor(clientFilterChain)
> .build();
>
>
> SingleEndpointPool singleEndpointPool = SingleEndpointPool//database connections
> .builder(SocketAddress.class)
> .connectorHandler(connectorHandler)
> .endpointAddress(newInetSocketAddress(InetAddress.getByName("localhost"),12345))
> .maxPoolSize(10)
> .build();
>
> HttpServer server = HttpServer.createSimpleServer(null,"localhost",9090);
> server.getServerConfiguration().addHttpHandler(newMyHandler(singleEndpointPool),"/users");
>
> server.start();
>
> System.in.read();
> }
> thenMyHandler(from org.glassfish.grizzly.samples.httpserver.nonblockinghandler.UploadHttpHandlerSample):
> ...
> public voidservice(Request request, org.glassfish.grizzly.http.server.Response response)throwsException {
> finalNIOInputStream in = request.getNIOInputStream();
> response.suspend();
> in.notifyAvailable(newReadHandler() {
> ................
> @Override
> public voidonAllDataRead()throwsException {
> // getting connection to db
> GrizzlyFuture<Connection> connectionFuture =singleEndpointPool.take();
> Connection connection = connectionFuture.get(10, TimeUnit.MILLISECONDS);
> //didn't find any better place to set timeouts, looks like no way to do it through pool?
> connection.setReadTimeout(1000, TimeUnit.MILLISECONDS);
> connection.setWriteTimeout(1000, TimeUnit.MILLISECONDS);
> //here code to make dbRq from http request
> .......................
> connection.write(newByteBufferWrapper(dbRq),newEmptyCompletionHandler<RecordWriteResult>() {
> .....
> @Override
> public voidcompleted(RecordWriteResult result) {
> connection.read(newCompletionHandler<ReadResult>() {
> HERE IS THE PROBLEM
> Neithercompleted nofailedare colled
> });
> }
> });
> }
> });
> }
> The first question - is this code looks like optimal way to write json/db service?
> And then, if it is, why doesn't it receive anything from db? It writes, I can see records inserted, and I'm sure db wants to return something, at least "pure nio" implementation receives db responses.
>
> Best regards, Eugene.