JavaFX app using retrofit async request quitting very slowly - java

I'm developing a JavaFX app with Java 8 and for api requests I'm using retrofit 2.1.0 with converter-gson 2.1.0.
If I make the synchronous request:
Patient p = Core.api.getPatient(2).execute().body();
Everything works fine, but if I do the asynchronous version:
Core.api.getPatient(2).enqueue(new Callback<Patient>() {
#Override
public void onResponse(Call<Patient> call, Response<Patient> response) {
System.out.println("DONE");
}
#Override
public void onFailure(Call<Patient> call, Throwable t) {
// Nothing
}
});
Everything also works out correctly (it prints "DONE"). However when I quit the application using the standard JavaFX call Platform.exit() the UI closes but the application lingers open still and will only exit after ~40 seconds.
If I just do System.exit(0) everything works as intended so I'm guessing this might be some threading issue but I'm not sure.
Anyone have an idea on what might be wrong?
EDIT:
I found out that after doing Platform.exit() a few threads, with names like RMI TCP Connection(2) keep alternating and using 100% of the CPU.

OkHttp uses two thread pools that keep threads alive for 60 seconds after use. You can shut em down with force by calling shutdown on the dispatcher's executor and by calling evictAll on the connection pool.

Related

How to simulate timeout in response to a Rest request in Spring?

I have a Rest API implemented with Spring Boot 2. To check some client behavior on timeout, how can I simulate that condition in my testing environment? The server should regularly receive the request and process it (in fact, in production timeouts happen due to random network slowdowns and large big response payloads).
Would adding a long sleep be the proper simulation technique? Is there any better method to really have the server "drop" the response?
Needing sleeps to test your code is considered bad practice. Instead you want to replicate the exception you receive from the timeout, e.g. java.net.SocketTimeoutException when using RestTemplate.exchange.
Then you can write a test as such:
public class FooTest
#Mock
RestTemplate restTemplate;
#Before
public void setup(){
when(restTemplate.exchange(...)).thenThrow(new java.net.SocketTimeoutException())
}
#Test
public void test(){
// TODO
}
}
That way you wont be twiddling your thumbs waiting for something to happen.
Sleep is one way to do it, but if you're writing dozens of tests like that then having to wait for a sleep will create a really long-running test suite.
The alternative would be to change the 'threshold' for timeout on the client side for testing. If in production your client is supposed to wait 5 seconds for a response, then in test change it to 0.5 seconds (assuming your server takes longer than that to respond) but keeping the same error handling logic.
The latter might not work in all scenarios, but it will definitely save you from having a test suite that takes 10+ mins to run.
You can do one thing which I did in my case .
Actually in my case, when my application is running in a production environment, we keep on polling trades from the API and sometimes it drops the connection by throwing an Exception SSLProtocolException.
What we did
int retryCount =5;
while (true ){
count++;
try{
//send an api request here
}catch (Exception e){
if(retryCount == count ) {
throw e
// here we can do a thread sleep. and try after that period to reconnect
}
}
}
Similarly in your case some Exception it will throw catch that Exception and put your thread in Sleep for a while and after that again try for Connection the retryCount you can modify as per your requirment, in my case it was 5.

Calling Method at the End of Program Execution

I am creating a client library for an API endpoint using Unirest to simulate GET and POST requests. Once the program finishes, the following code must be called in order to terminate the current thread.
Unirest.shutdown(); // must be called in order to clear the high CPU consuming thread
Is there any possible way implicitly call this in my client library at the end of the program's execution?
Yes - your best option is likely a Shutdown Hook. It will be called/executed when the JVM is terminating. As an example:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
System.out.println("JVM shutting down, closing Unirest");
Unirest.shutdown();
}
}));
You should ideally call the addShutdownHook() method as soon as possible, after you have started the Unirest service.

How to notify "content consumed" for Jetty 9.02. ContentListener?

I have a Jetty HttpClient sending Async Requests using Jetty v9.0.2. I have a Response.ContentListener that successfully buffers-up response and a Response.CompeleteListener that is called when the call has completed.
Jetty 9.2 JavaDocs has a Request.AsyncContentListener which has a parameter to tell Jetty the content has been consumed:
callback - the callback to call when the content is consumed.
This listener type is NOT in the Jetty v9.0.2 Response api:
import org.eclipse.jetty.client.api.Result;
There are two questions really:
Does the Response.ContentListener need to notify Jetty client that the content is consumed?
If so: how is that managed with Jetty v9.0.2
What kind of clean-up will be required using Async calls with these two Response.ContentListener and Response.CompeleteListener set-up?
Are there potential gottchas using async with Jetty v9.0.2?
It seems to be working fine; I need to ensure we have no resource leaks or potential leaks, etc. And of course we need the program to be nice and clean so it can run 24x7. Thanks in advance for your welcome help.
note:
Request.AsyncContentListener - Stable Jetty doc (jetty 9.2, I believe)
The short answer to this question is to call HttpClient.stop() after the async call has completed processing. A solution approach is outlined in this tutorial example:
Jetty's HTTP Client
The main aspect is that stop() may not be called until (all) listeners have finished-up and processing has completed. In the example above, a CountdownLatch is used to synchronize the stop() call. This isn't really explained in the Jetty examples, e.g.:
The new Jetty 9 HTTP client
Chapter 28. HTTP Client - Asynchronous APIs
Class HttpClient
Some async interfaces use calls like "consume content", etc. However with Jetty 9 the stop() call does the clean-up.
Our use-case was straight forward enough. In the onComplete() method in the listener, a call is made to a setCompleted() method that decrements a count down latch for the Httpclient.send(). Following the send() call, we have a synchronization method called, finished() that wait on the call for setCompleted().
public boolean finish(){
boolean result = false;
int retryCount = 0;
try
{
if( !this.latch.await( 5, TimeUnit.SECONDS ) )
{
Util.warn(LOG,"Timed-out -- msg #", String.format("%0,4d", this.msgId) );
}
this.httpClient.stop();
result = this.httpClient.isStopped();
}
catch (InterruptedException ex )
{
log.warn("Interrupted -- msg #", String.format("%0,4d", this.msgId)" );
}
catch (Exception ex)
{
log.error(LOG,"Stop-exception -- msg #", String.format("%0,4d", this.msgId) );
}
if( !result )
{
log.warn(" * HttpClient NOT stopped -- msg #", String.format("%0,4d", this.msgId) );
}
return result;
}
The stop call seems to be happy with a call as long as the setCompleted() is called at the end of our onComplete() method. I'm not clear if you can't be sure of the internal timing for onComplete. Otherwise it all seems satisfactory. I really believe API documentation should include "clean-up code" for opertations of this kind - data comms, database, etc. Hopefully this posting will save time for others.

Executing DeferredTask with JAVA GAE sdk

I'm trying to execute delayed DeferredTask in Google App Engine (JAVA).
So far here is what I got.
The task class itself:
public class TestTask implements DeferredTask {
#Override
public void run() {
System.out.print("test");
}
}
And the execution:
QueueFactory.getDefaultQueue().add(TaskOptions.Builder.withEtaMillis(10000).payload(new TestTask()));
When I run it on the dev server, console output show up right away when task is added to queue, and not after 10 seconds as I wanted :(
The Dev Server typically handles the execution differently. This is detailed in the following section : https://developers.google.com/appengine/docs/java/taskqueue/overview-push#Java_Push_queues_and_the_development_server
So, it is likely that some of the parameters that you are trying to specify are ignored by the dev server and the task is executed immediately. In case you do not want the task to be executed and prefer that you manually invoke it in the dev server, there is a setting to be provided for the app server as detailed in the note above.

Android SignalR should be implemented as Service or IntentService?

On my Android App, I'm implementing SignalR connection (https://github.com/erizet/SignalA) to connect to a Hub server to send requests and receive responses.
a sample of my code is as follows:
signalAConnection = new com.zsoft.SignalA.Connection(Constants.getHubUrl(), this, new LongPollingTransport())
{
#Override
public void OnError(Exception exception)
{
}
#Override
public void OnMessage(String message)
{
}
#Override
public void OnStateChanged(StateBase oldState, StateBase newState)
{
}
};
if (signalAConnection != null)
signalAConnection.Start();
There's also the sending bit
signalAConnection.Send(hubMessageJson, new SendCallback()
{
public void OnError(Exception ex)
{
}
public void OnSent(CharSequence message)
{
}
});
The sending and receiving will occur across activites, and some responses will be sent at random times regardless of the activity, also, the connection should be opened as long as the app is running (even if the app is running in the background) that's why I wish to implement the signalA connection as a background service
The question is should I implement it as:
1 - a Service (http://developer.android.com/reference/android/app/Service.html)
OR
2 - an Intent Service (http://developer.android.com/training/run-background-service/create-service.html)
Keeping in mind that I will need to send strings to the service and get response strings from the service.
I would be most grateful if someone would show me how to implement this kind of connection in code as a background service/intentservice.
Thanks for reading.
UPDATE:
Please see this demo activity made by the developer as how he implemented SignalA
https://github.com/erizet/SignalA/blob/master/Demo/src/com/zsoft/SignalADemo/DemoActivity.java
The problem is AQuery (which I know nothing about) is being used in this demo activity. Does AQuery run in the background all the time ?
The problem is, the latest update on SignalA mentions the following
I have changed the transport. LongPolling now uses basic-http-client
instead of Aquery for http communication. I've removed all
dependencies on Aquery.
Hence I'm not sure whether I should follow this demo activity or not
Update 2:
This is the thing that is confusing me most
in the IntentService, the OnHandleIntent method calls stopSelf after it finishes its tasks, when I actually want the code in the IntentService to keep running all the time
protected abstract void onHandleIntent (Intent intent)
Added in API level 3
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().
SignalA is running on the thread that creates and starts the connection, but all network access is done in the background. The remaining work on the starting thread is really lightweight, hence its perfectly ok to do it on the UI tread.
To answer your question, you need to have a thread running the signala connection. Therefore I think a Service is the best choice since SignalA need to be running all the time.
Regarding Aquery and the demo project. I removed all dependencies to Aquery in the libraries, not in the Demo. To be clear, you don't need Aquery to run SignalA.
In my case, what I wanted was a Service not an Intent Service, since I wanted something that would keep running until the app closes

Categories