Does Retrofit or OkHttp limit number of parallel requests? - retrofit

I use RxJavaCallAdapterFactory.create() and Schedulers.io(), so Dispatcher isn't used and maxRequests and maxRequestsPerHost not a problem. Schedulers.io() creates infinite number of threads.
The problem is when I run 10 requests and then 1 more while previous not finished this 1 request takes longer time to start. If 10 requests finished the next request run immediately.
When I have a several requests running I see in logs that Call.execute() is called and then request started only after 6 seconds. When there are no active requests, new request starts immediately. So is it limitation of android or some network libraries?

Use OkHttp Dispatcher.
Dispatcher dispatcher = new Dispatcher(Executors.newFixedThreadPool(20));
dispatcher.setMaxRequests(20);
dispatcher.setMaxRequestsPerHost(1);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.dispatcher(dispatcher)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(HttpUrl.get("https://example.com/"))
.client(okHttpClient)
.build();

Yes, configure this in OkHttp’s Dispatcher.

Related

Jersey async client handler never times out after server restarts

I have a ReST service I'm connecting to with a Jersey async client. I'm using InvocationCallback to handle responses as callbacks. All is well unless I bounce the server during heavy load from my client service. After a couple of bounces, I find that, beneath the covers, jersey client has registered internal callback handlers for messages that the server will never respond to (because it's been restarted and has lost any indication of an outstanding request).
I would have expected Jersey to (internally) poll its registered async handler list looking for "stale" handlers and cleaning them up with timeout exceptions to the registered invocation callback handlers periodically, but these unanswered handlers never get cleaned up.
What am I doing wrong? This has GOT to be a known issue in Jersey.
I'm building my client like this:
ClientBuilder builder = ClientBuilder.newBuilder();
this.client = builder
.executorService(es)
.register(JsonProcessingFeature.class)
.register(LoggingFeature.class)
.property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_CLIENT, log.getName())
.connectTimeout(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)
.withConfig(new ClientConfig().connectorProvider(new JdkConnectorProvider()))
.build();

HttpClient on ASP.NET Core application times out when connecting to service on localhost

I have a XML-RPC server (using XML-RPC.net) running as a .NET console application. I'm trying to connect to it via my ASP.NET Core (2.1.1) web app but the client keeps timing out. Postman also returns a response immediately without issues.
Here is how I'm calling it:
HttpClient client = _clientFactory.CreateClient();
client.Timeout = TimeSpan.FromSeconds(10);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, instance.ServiceUrl);
var stringContent = new ByteArrayContent(Encoding.UTF8.GetBytes(request.ToString()));
httpRequest.Content = stringContent;
httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("text/xml");
var httpResponse = await client.SendAsync(httpRequest);
var response = await httpResponse.Content.ReadAsByteArrayAsync();
I can see that the request was made successfully as the console app returns a response. Fiddler shows there was a 200 response but await client.SendAsync(httpRequest); times-out!
The request usually completes in under 10ms so the timeout value is just for debugging, if I leave it out it would take 60s. The response returns XML.
I've tried rewriting this to use StringContent and using PostAsync, same issue. I also attempted to rewrite this using WebClient but it returned The remote server returned an error: (100) Continue. not sure if that's relevant.
Been stuck on this for a whie, anyone know what could be happening?
OK I did some googling and it looks like I needed this line:
client.DefaultRequestHeaders.ExpectContinue = true;
It was definitely related to 100 status code returned not being handled properly.
Found it here:
https://social.msdn.microsoft.com/Forums/en-US/042016f0-d70e-42f9-9924-5febeb2bea86/excluding-the-quotexpect-100continuequot-header-from-httpwebrequest-posts?forum=winappswithcsharp

Spring Job Response To Client

Spring batch job runs to completion successfully with following code:
#RestController
#RequestMapping(value = "api/jobs")
public class JobLaunchingController {
#Autowired
private JobOperator jobOperator;
#RequestMapping(value = "/pay/{paymentPeriod}", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.ACCEPTED)
public void launchPaymentJob(#PathVariable Integer paymentPeriod) throws Exception {
this.jobOperator.start("paymentJob", String.format("paymentPeriod=%s,time=" + System.currentTimeMillis(), paymentPeriod));
}
}
I am using JavaFX client where the endpoint is used to send request for the job to be launched. Basically, with the help of jersey client http request is sent like so
Client client = ClientBuilder.newBuilder().build();
WebTarget webTarget = client.target(getBaseUri()).path(path);
Response response = webTarget.request().get(Response.class);
The problem is i don't have a way for the client to know when the job is complete. How can client be notified by server when job is done
Any help is highly appreciated.
This is more of a architectural question than coding. You can solve this by multiple ways, I will suggest you below three
Simplest -> If your jobs doesn't take long - make your client wait for the outcome of job. Send them final status back in response.
Send job reference number immediately to client and introduce another endpoint where client can check with reference number if jobs is done - This involves your client having some polling mechanism.
Use something like Server Sent Events/Websockets - Thanks cerp0
How can client be notified by server when job is done?
Try to use Websokets to send data from server to client. Here is a pretty good guide how to do it with Spring.
On the client side I believe you can use this approach: https://github.com/nickebbutt/stomp-websockets-java-client

ASP.Net Application Idle Timeout and App Pool Recycling

I have the following job schedlued to run every minute using hangfire to try and keep my site alive but it still seems to idle out? I've just checked the hangfire dashboard and looks like the job never ran over the weekend presumembly because no one visited the site (note it's an intranet application)
try
{
var url = "http://xyz.domain.com/myapp"
var request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 6000;
request.AllowAutoRedirect = false;
request.Method = "HEAD";
using (var response = request.GetResponse())
{
// TO DO
}
}
catch (Exception ex)
{
logger.Error(ex, "Error in KeepAlive job");
}
Would using webclient be more reliable or is it the same as using HttpWebRequest -something like below:
WebClient webClient = new WebClient();
Stream stream = webClient.OpenRead("http://xyz.domain.com/myapp");
By default, Hangfire Server instance in a web application will not be started until the first user hits your site. Even more, there are some events that will bring your web application down after some time (I’m talking about Idle Timeout and different app pool recycling events). In these cases your recurring tasks and delayed jobs will not be enqueued, and enqueued jobs will not be processed.
This is particulary true for smaller sites, as there may be long periods of user inactivity. But if you are running critical jobs, you should ensure that your Hangfire Server instance is always running to guarantee the in-time background job processing.
http://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html

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."

Resources