Alright, I'll use the connection to pass data between the calling thread
and the filter. That'll be fine. Even with callbacks I would have to find a
way to actually pass the callback instance to the filter so it would know
which callback to call when onRead finishes so it's basically the same
problem and can be solved in the same way. Thanks a lot!
2014-05-22 20:19 GMT+02:00 Oleksiy Stashok <oleksiy.stashok_at_oracle.com>:
> Hi,
>
> if you want to do that in a blocking fashion (like in your sample), I'd
> recommend to create an Attribute associated with the Connection.
>
> private final Attribute<FutureImpl<HttpContent>> httpResponseAttr =
> Grizzly.DEFAULT_ATTRIBUTE_BUILDER.
> createAttribute("HttpResponseAttribute");
> ......
>
>
> // 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();
>
> FutureImpl<HttpContent> responseFuture =
> Futures.<HttpContent>createSafeFuture();
> httpResponseAttr.set(connection, responseFuture);
>
> connection.write(m);
>
> final HttpContent response = responseFuture.get();
> }
>
>
> class MyClientFilter extends BaseFilter {
> public NextAction handleRead(FilterChainContext ctx) throws IOException {
> // process the response message from the server
>
> FutureImpl<HttpContent> responseFuture =
> httpResponseAttr.get(ctx.getConnection);
> responseFuture.result(httpContent);
> return ctx.getStopAction();
> }
> }
>
> If you want HTTP client to work in non-blocking fashion - you probably
> need to introduce a callback interface, which will be notified once a
> response is received.
>
> WBR,
> Alexey.
>
>
>
> On 22.05.14 05:38, Johan Maasing wrote:
>
> 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
>>
>>
>>
>>
>
>