Request Flow in Asynchronous Controller Spring MVC - spring-mvc

I was trying to understand Asynchronous Controller implementation from one of links:
http://shengwangi.blogspot.in/2015/09/asynchronous-spring-mvc-hello-world.html
I was puzzled on point that Controller thread received request and exists. Then service method received the request for further processing.
#RequestMapping("/helloAsync")
public Callable<String> sayHelloAsync() {
logger.info("Entering controller");
Callable<String> asyncTask = new Callable<String>() {
#Override
public String call() throws Exception {
return helloService.doSlowWork();
}
};
logger.info("Leaving controller");
return asyncTask;
}
Since, Controller exists it and pass the control to appropriate handler mapping/ jsp. What will be seen on the browser for the user ?

Browser waits for the response to process it.
Asynchronous process takes place only at the server end and it has nothing to do with the browser. Browser sends the request and waits for the server to write the response back.
Since you returned Callable doesnt mean that controller exists the flow. Spring`s response handlers will wait for async task to get executed to write the response back.
Please go through AsyncHandlerMethodReturnValueHandler which handles Asynchronous response returned from the controller.
if you return callable then it will be handled by CallableHandlerMethodReturnvaluehandler :
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
Callable<?> callable = (Callable<?>) returnValue;
WebAsyncUtils.getAsyncManager(webRequest).startCallableProcessing(callable, mavContainer);
}

I had cleared my doubt from this link:
https://dzone.com/articles/jax-rs-20-asynchronous-server-and-client
However, they used different way to accomplish the asynchronous processing but the core concept should be the same for every approach.
Some important part of the article:
The idea behind asynchronous processing model is to separate
connection accepting and request processing operations. Technically
speaking it means to allocate two different threads, one to accept the
client connection and the other to handle heavy and time consuming
operations. In this model, the container dispatched a thread to accept
client connection (acceptor), hand over the request to processing
(worker) thread and releases the acceptor one. The result is sent back
to the client by the worker thread. In this mechanism client’s
connection remains open. May not impact on performance so much, such
processing model impacts on server’s THROUGHPUT and SCALABILITY a lot.

Related

Spring Cloud Kafka Binding with Synchronous Rest Call

I'm working on a micro service powered by SpringMVC and Spring Cloud Kafka.
For simplicity I will only focus on the part that makes HTTP request.
I have a binding function like the following (please note that I'm using the functional style binding).
#SpringBootApplication
public class ExampleApplication {
// PayloadSender uses RestTemplate to send HTTP request.
#Autowired
private PayloadSender payloadSender;
#Bean
public Function<KStream<String, Input>, KStream<String, Output>> process() {
// payloadSender.send() is a blocking call which sends payload using RestTemplate,
// once response is received it will collect all info and create "Output" object
return input -> input
.map((k,v) -> KeyValue.pair(k, payloadSender.send(v))); // "send" is a blocking call
// Question: if autoCommitOffset is set to true, would offset automatically commit right after the "map" function from KStream?
}
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
From this example you can see that the payloadSender is sending the payload from the input stream using RestTemplate and upon receiving the response creating the "Output" object and produce to the output topic.
Since payloadSender.send() is blocking, I'm worried that this will cause performance issue. Most importantly if the HTTP request gets timed out, I'm afraid it will exceed the commit interval (usually the HTTP timeout interval is much much greater than the consumer commit interval) and cause the kafka broker to think the consumer is dead (please correct me if I'm wrong).
So is there a better solution for this case? I would eventually switch over to spring-reactive but for the time being I need to make sure the MVC model works. Although I'm not sure spring-reactive would have magically solve this issue.
The default max.poll.interval is 5 minutes; you can increase it or reduce max.poll.records. You can also set a timeout on the rest call.

Why all my requests are blocked until async/await method executed

I have an asp.net mvc async method waiting for 10 second.
The problem is IIS Express (production IIS also) stops processing incoming requests until that async method finishes.
I thought await keyword frees current thread for new incoming request. But it seems that I missed something.
public async Task<ActionResult> AsyncMethod()
{
using (DeliveryPortalEntities context = new DeliveryPortalEntities())
{
await context.Database.ExecuteSqlCommandAsync("WAITFOR DELAY '00:00:10'");
}
return Json(new { status = "ok" });
}
Update! Can anyone explain why during this code execution IIS stops answer requests immediately.
public async Task<ActionResult> AsyncMethod()
{
await Task.Delay(10000).ConfigureAwait(false);
return new EmptyResult();
}
I thought await keyword frees current thread for new incoming request.
It does; the thread is free. However, the request is not complete. And if that request has a read/write lock on the session, then no other requests for that session can be processed until that lock is free.
To resolve this, you'll need to change your session usage. If you can go sessionless, that's best - it allows really good horizontal scalability. If not, try to go read-only. Long requests with a read-only session lock can run concurrently with other requests in that same session if they also only need a read-only session lock.

Clarifying RxJava Observable Threading with Retrofit

At http://square.github.io/retrofit/ where it talks about asynchronous, there is a phrase "Observable requests are subscribed asynchronously and observed on the same thread that executed the HTTP request" where I wanted to clarify.
So in this case which thread that actually will execute the Http Request: Lets say main thread makes a call to Observable getUserPhoto(#Path("id") int id)? Will it be the main thread or thread that subscribe the request that execute the http request?
Regarding to the documentation, it will be the thread which execute the request.
If the result of your request change something in the view, you may need to observe (consume) your result in the main thread. In this case, add a call to the observeOn method before you subscribe to your observable.
The answer is yes, when you execute your method by using a service, using the observeOn method will create an "Observer" that will be waiting for an opportunity to execute the request once the mainThread has an opportunity to do so.
So first use .observeOn(AndroidSchedulers.mainThread()) to observe the main thread, and then subscribe the action or callback that will execute once you got a response from your remote API.
supposing you use this annotation in your API interface
#GET("/home")
Observable<Response> getHome();
this would be an example:
service.getHome().observeOn(AndroidSchedulers.mainThread()).subscribe(
new Action1<Response>() {
#Override
public void call(Response response) {
System.out.println("Response home");
System.out.println(response.getStatus());
System.out.println(response.getBody().mimeType());
System.out.println(response.getReason());
System.out.println(response.getUrl());
StringWriter w = new StringWriter();
try{
IOUtils.copy(response.getBody().in(),w,"UTF-8");
System.out.println(w.toString());
}catch (IOException e){}
}
});
For more information you may check this RxJava(the one that Retrofits uses of course) link where it states that it uses Android's Handler(which is a class for handling threads)
"It provides a Scheduler that schedules an Observable on a given Android Handler thread, particularly the main UI thread."

Spring MVC Returns Response Before Completion of Controller Method

I have the following method which is returning an incorrect response to the browser before the method is even complete. This is in Spring 3.2.
#RequestMapping(value="/process1/createEditContract/validate", method=RequestMethod.POST)
public #ResponseBody StatusResponse validateProcess1(#ModelAttribute("contractEditForm") #Valid Process1CreateEditContractDTO dto, BindingResult bindingResult) {
StatusResponse response = new StatusResponse();
response.setSuccess(true);
if (bindingResult.hasErrors()) {
log.debug("Errors found. Processing status response");
response.setSuccess(false);
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fe: fieldErrors) {
response.getMessages().add(messageSource.getMessage(fe, null));
}
}
return response;
}
StatusResponse is a simple object that a javascript function in the JSP reads to generate a Javascript alert stating whether the action was successful or errors occurred. The method makes it all the way through, but as soon as it tries to write the response, I get this:
java.net.SocketException: Software caused connection abort: socket write error
I've been stuck for a day now, any help would be appreciated.
UPDATE
I rolled back from Spring 3.2 to Spring 3.1, and the wording of the error message changed enough to give me more information.
Basically, I'm getting now seeing this:
IllegalStateException: Response already committed
What I don't see is what is causing the response to commit so quickly. Maybe a conflict with the OpenSessionInViewFilter?
This error can occur when the local network system aborts a connection, such as when WinSock closes an established connection after data retransmission fails (receiver never acknowledges data sent on a datastream socket).". See this MSDN article. See also Some information about 'Software caused connection abort.
To prove which component fails I would monitor the TCP/IP communication using wireshark and look who is actaully closing the port, also timeouts could be relevant.
The javascript runs in browser, and your controller runs on server. You cannot pass a complex object from the controller to the javascript without converting it to a textual format such as xml or json.
So you should :
choose a format (say json)
add a produces="application/json" in your RequestMapping annotation
do generate json in your controller method

asp.net(mvc) not consuming any thread while waiting for a chat message using async/await?

What I want to do is to achieve 100% thread agility with asp.net 4.5 async/await while waiting for a chat message (or a MSMQ message)to come. Async/await can release the HTTP request handling thread to the thread pool, but how to not use any thread while waiting for chat messages to come?
In java, I can use the latest Jersey rest API to achieve this using the #ManagedAsync/#Suspended annotation:
// Java code, using Jersey rest API
#Path("/Chatroom")
public class ChatHandler {
private static final HashMap<Integer, AsyncResponse> map = new HashMap<>();
#GET
#Path("/JoinRoom")
#ManagedAsync
public void joinRoom(#PathParam("UserId") String id, #Suspended final AsyncResponse ar) {
map.put(i, ar);
}
#GET
#Path("/PostChat")
public String sendChat(#PathParam("UserId") String id, #QueryParam("message") String message) throws InterruptedException {
map.get(i).resume(message);
return "Message successfully sent to user " + id;
}
}
Here is a description for the above code. John first uses a URL like this to join the chat room as user john in order to receive some chat messages. In the corresponding method joinRoom(), Jersey will, same as async/await in asp.net 4.5, return the http request thread back into the thread pool. However here I put the HttpContext, in Jersey the AsyncResponse object, in a hashmap for later use.
Then say for the next 50 seconds, there is nobody sending chat messages, the backend Jersey server will not use any threads on anything during that 50 seconds. No thread is spent on waiting for the next chat message. Then on the 51st second, Mary goes to the URL to send a hello message to user john. In sendChat() method, I retrive the HttpContext (AsyncResponse) from the hash map, and resume it with the chat message. At this time, Jersey will find an available thread in the http request thread pool to resume the AsyncResponse and send the chat message "hello" to John's browser. Mary's browser will see "Message successfully sent to user john".
So how can I acheive the same 100% thread agility with asp.net async/await? In my await method, I can not find a correct way to wait for the chat message without occupying a worker thread.
There is already an ASP.NET system designed for this: SignalR. It was designed with async in mind, so it makes optimum use of threads.
If you don't want to use SignalR, you can use any of a number of asynchronous coordination primitives. TPL Dataflow may be a good fit for this kind of scenario, or you can use SemaphoreSlim or TaskCompletionSource or any of the primitives in my AsyncEx library.

Resources