Why is JAX-RS/restEasyClient async not working as async - java

may be I am not understanding the ASYNC part of this.
I have a resteasy client ( only one client )
client = new ResteasyClientBuilder().connectionPoolSize(maxConnections).connectTimeout(timeout, TimeUnit.SECONDS).readTimeout(timeout, TimeUnit.SECONDS).httpEngine(engine).build();
where maxConenctions is 10, the client is created on startup and does async calls on each request like this in a for loop :
ResteasyWebTarget resteasyWebTarget = client.target(restRequestFromGateway.getUrl());
Future<Response> response = resteasyWebTarget.
request().
headers(headers).
async().
get(restWSResponseCallback);
if (response!= null){
response.isDone();
}
I created ten requests and in a for loop send them through. on the WebService end I put a debug point and just waited. So i got the first request and didnt let it go through.
I was expecting that as it was async the client will continue and will send multiple requests and wait for the response in the invocationCallback but it did not
the next request didnt come thorugh to the webservice till the response from the webservice was received.
Why didn't the requests go through one by one after the another from the client.

Related

Server sends "ping request" to client in a single URL using JAX-RS and RESTeasy

I would like to create a web application that is able to "ping" the client once the client has accessed certain URL (e.g. www.example.com/ping/hello) in order to get the round trip time between server and client. And by "ping" request i mean a simple request with a timestamp from server and client sends back response with its timestamp. I was hoping for this activity to be done with a single URL if possible.
The flow is something like this:
Client goes to the URL
Server sends the response to the client with its timestamp
Client then sends another response to server with new timestamp
Server finally concludes the connection with 200 OK
So far I've only been able to do the first and second steps but not sure how to ensure client to go to the same URL again without back to the first step.
My server code is something like this:
#GET
#Path("/helloping")
public Response getPingServerClient(#Context HttpServletRequest req) {
String result = Long.toString(System.currentTimeMillis());
return Response.status(200).entity(result).build();
//the code to receive the response from client containing timestamp
}
Is there a way to do that?
There are two client to server calls. You'll have to figure out a way to differentiate between these two calls.
I can think of 3 options for this purpose:
HTTP header
Query parameter in GET request
POST request with a marker to differentiate the two calls
The request/response flow will be something like this:
Client -> Server : Request
Server -> Client : Response with timestamp t1
Client -> Server : Request with timestamp t2 and the above mentioned marker
Server -> Client : Response 200
In this approach, you'll have to write custom code at both server and client side to handle the mentioned logic.
I'm not a fan of what you are proposing because you're basically forcing the client to setup up code to effectively become a server, itself. This is inconvenient for the client.
Instead, consider a ping-pong approach where the client first calls the server's ping endpoint, which returns the server's timestamp. As soon as the client obtains the server's ping response, the client is instructed to call a second pong method, which accepts the new timestamp.
It's easier and simpler to require the client to call web service methods than it is to force to client to become a pseudo server. Hence the recommendation.

Setting timeout on webservice

I am very new to webservices, I call a webservice through a wrapper provided by some party. I need to wait for certain amount of time after calling the webservice, if response is not received, i should shoot up time out response.
Remember i do not call the webservice directly. Below is the psuedo code.
String responseXML = pro.sendToCustomer("https://india.com/ClientGatewayV2/GatewayClientInterfaceV2", asaXML);
pro.senToCustomer is present in the jar provided by third party. How do i handle session time out on this?

How to send a HTTP 100-continue response with netty

I instantiated a netty 4 (using netty-all-4.0.9.jar) service and initialized the channel by adding 3 ChannelHandler objects:
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("handler", new MyHandler());
When testing w/ curl HTTP PUTing a file to my server and I found MyHandler.channelRead is not called immediately for requests with Expect: 100-continue header is sent (curl is waiting for the server to reply with 100 Continue. This means my handler is not able to reply with a HTTP/1.1 100 Continue response to tell the client (curl) to initiate the actual upload of the file immediate.
Interestingly further debugging this issue with telnet shows that a channelRead is called right once the actual body is being uploaded (right after the first byte is received).
Any hints on how to handle PUT requests with 'Expect: 100-continue' header properly to trigger 100 Continue response immediately?
Examples coming with netty (e.g. HttpHelloWorldServerHandler.java) have the following code in the channelRead() method:
if (is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
}

Link HTTP request-response using netty4 async call

I am writing a simple HTTP client using netty-4.0x.
Build the pipeline as below :
pipeline.addLast("codec", new HttpClientCodec());
pipeline.addLast("inflater", new HttpContentDecompressor());
pipeline.addLast("handler", new HttpResponseHandler());
where HttpResponseHandler provides implementation of messageReceived(),
Now there is a thread-pool which call the client and keep sending http message,
I understand that ChannelFuture future = channel.write(request); is async call and will come out without blocking
The query which i am having is, is there a way to link request-response, without calling
future.sync() call.
Thanks for all the help in advance !!!
If you code the server too, you could have the client add a unique id to the HTTP header and have the server echo it back in the response.
If you are following strict HTTP pipelining rules then, on any given channel, the responses will be returned in the order the requests were sent in. It should be enough to maintain a request queue, removing the front of the queue for each response received.
If you are creating a new channel, and a new pipeline for that channel, for each request, it's even easier. Either way you can add a handler to your pipeline which remembers the request (or queue of requests), and returns the request and response to your application when the response is received.

Java many threads to many threads relation

I have a service that gets requests from many clients and after some processing sends a response to the clients. I use a ThreadPoolExecutor (threadExecuterClient) to handle client requests and put them in a BlockingQueue (requestQueue). Many clients can send concurrent requests. I have another ThreadPoolExecutor (threadExecuterServer) that processes requests in requestQueue. This processing is basically consists of send that request to a server and get response. After processing, I need to send that response to the client which has made that request. I am having difficulties to track which client has made which request. I basically need to find a way to map the client request to the result of processing. The service will be like a gateway.
Any idea to handle this issue is appreciated.
Thanks
I assume your service accepts requests via HTTP ? Accept the request from your service and send back a HTTP 202 response. This response means that the request was accepted for processing. When you send the response, send the Location header to tell the client which URL to invoke to ascertain the status of your request. The client can poll this URL for status and a result.
The URL should contain a unique ID for each request. Your server can track that and populate a response when it is ready.

Categories