users@grizzly.java.net

Re: Question on how to design statless filters

From: Johan Maasing <johan_at_zoom.nu>
Date: Thu, 22 May 2014 14:38:59 +0200

Thanks, that wasn't so hard :-)

I am still confused about the second part. What design has people used to
solve multi-threaded clients? Assuming something like the below:

// Singleton instance
class Client {
private TCPNIOTransport transport
 // Only called once
public void startup() {
FilterChainBuilder cb = FilterChainBuilder.stateless();
cb.add(new MyClientFilter()) ;
transport =
TCPNIOTransportBuilder.newInstance().build();
transport.setProcessor(cb.build());
transport.start();
}

// Called in parallel from many threads
public MyResponse makeRequestToServer(MyRequest m) {
        GrizzlyFuture<Connection> connectionGrizzlyFuture =
                this.transport.connect(this.serverName, this.serverPort);
Connection connection = connectionGrizzlyFuture.get();
connection.write(m);
 //How to get the response the filter created??
}
}

class MyClientFilter extends BaseFilter {
public NextAction handleRead(FilterChainContext ctx) throws IOException {
// process the response message from the server
 MyResponse result = ... // How to get this back to caller thread?
 return ctx.getStopAction();
}
}

Cheers,
JM


2014-05-21 22:41 GMT+02:00 Oleksiy Stashok <oleksiy.stashok_at_oracle.com>:

> Oh, jusr realized it's HTTP server example, but still it might be useful
> sample for you, on client side the code will look similarly, except that
> you don't need to send response :)
>
> WBR,
> Alexey.
>
>
> On 21.05.14 13:35, Oleksiy Stashok wrote:
>
> Hey Johan,
>
> On 21.05.14 05:28, Johan Maasing wrote:
>
> I'm going through the tutorials (for 2.3.12) making a simple HTTP client.
> I followed this https://grizzly.java.net/httpframework.html#/Sampleswhich works fine.
>
> However I get a bit stuck on how to modify the sample to make the filter
> stateless.
> My use case is that I will have many threads making the same type of
> HTTP-requests to the same end-point. So I guess that I should set up the
> filter chain and start the transport once as a singleton. Then I use
> transport.connect and transport.write in each "client" thread.
> Will there ever be the case that my filter will be called several time for
> the same response - I'm thinking about how/where to accumulate in memory
> the entire response body if that is the case?
>
> I think here is the Filter sample, which may help you:
>
> *new BaseFilter() {*
> * @Override*
> * public NextAction handleRead(FilterChainContext ctx) throws
> IOException {*
> * final HttpContent requestContent = ctx.getMessage();*
> * if (!requestContent.isLast()) { // if it's not the last
> content chunk - keep accumulating the response content*
> * return ctx.getStopAction(requestContent);*
> * }*
>
> * HttpRequestPacket request = (HttpRequestPacket)
> requestContent.getHttpHeader();*
> * HttpResponsePacket response = request.getResponse();*
>
> * final Buffer payload = requestContent.getContent();*
> * // retrieve the entire response payload *
> * HttpContent responseContent =
> response.httpContentBuilder().*
> *
> content(payload).last(requestContent.isLast()).build(); // build the
> response*
> * ctx.write(responseContent); // send the response back on
> the same connection*
> * return ctx.getStopAction();*
> * }*
>
>
> Please let me know if you have more questions.
>
> WBR,
> Alexey.
>
>
>
> How do I return the response to the calling thread? In the sample the
> filter gets a future from the caller in the constructor to return the
> result to the caller. But this won't work if I set up the chain once and it
> is shared between threads.
>
> Any pointers are appreciated.
>
> Cheers,
> JM
>
>
>
>