Clarifying RxJava Observable Threading with Retrofit - 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."

Related

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.

Request Flow in Asynchronous Controller 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.

spring-mvc, websockets push integration

I've followed this link http://spring.io/guides/gs/messaging-stomp-websocket/ and got the app up and running.
What I wanted was a little more than that, I wanted to to be able to push the data back to the client without the client having to send any thing.
So I've setup a long running task with a listener similar to the below
GreetingController implements RunnableListener
and the RunnableListener has a method
public Greeting greeting(HelloMessage message);
The implementation of the method is to kick off a thread and then call the listener method..
I see the output on the console when that happens, but I don't see anything on the browser.
Could anyone please show me how to kick off a running task and let the server push the content to the browser using Spring instead of poll (setTimeout stuff in javascript?)
Regards
Tin
What is this RunnableListener interface?
What is triggering this task - is it scheduled regularly?
Once the client has subscribed to a given topic (here, /topic/greetings), you can send messages to that topic whenever you want using a MessagingTemplate. For example, you could schedule this task and let it send messages regularly on a given topic:
#Service
public class GreetingService {
private SimpMessagingTemplate template;
#Autowired
public GreetingService(SimpMessagingTemplate template) {
this.template = template;
}
#Scheduled(fixedDelay=10000)
public void greet() {
this.template.convertAndSend("/topic/greetings", "Hello");
}
}
Check out the reference documentation for more details.

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.

MVC 3 Async Controller for video conversion

I'm not really to up on Async controller, I'm currently reading what I can but I thought I'd try and save myself some time as I'm on a rather tight deadline.
I'm working on a project that allows users to upload video clips but I then want to convert them to different formats for playback on different devices. I was thinking of doing this straight after the upload has happened but the down side is the user will be waiting for that to finish before they can navigate away.
So to my question, would using a async controller and action allow the conversion process to happen with out the user having to wait at the upload page?
Apologies if this is a stupid question, like I said I've only just started reading about async controllers
Thanks
No. AsyncController frees up the thread executing the controller to do other things when there is low CPU usage (for example heavy I/O). A result will not be returned to the client until the action method returns.
You are better off starting your conversion in a separate thread, if you want to return a page quickly. We use this approach when sending emails, so that the user does not have to wait for the email to be sent before we return a view to them.
Here is how we send emails.
// this can go in an action method, or you can DI this code as a service
var sender = new SmtpEmailSender(message);
var thread = new Thread(sender.Send);
thread.Start();
...
return View(model);
// this is the code run by the new thread
// (EmailMessage is a custom type in our app)
public class SmtpEmailSender
{
public SmtpEmailSender(EmailMessage emailMessage)
{
// arg to instance field
}
public void Send()
{
// construct System.Net mail and send over SMTP
}
}

Resources