I have a function where I have to get code from server and return its operation.
Here is the code
public String getResult
{
// Call to your backend
try {
String url = String.format(Constants.LOGIN_URL,
URLEncoder.encode(countryCode + phoneNumber, "UTF-8"),
URLEncoder.encode(smsCode, "UTF-8"),
URLEncoder.encode(Constants.WHERE_API_KEY, "UTF-8"));
while (new LoginToServer().execute(url).get());
}catch (Exception e)
{}
return result; // Result will be saved to class in onPostExecute()
My LoginToServer returns true if there was an error retrieving the result. Now, This will most obviously remove the Exception of NetworkOnMainThread, however it iwll block UI.
since the function is to be called by some sdks , it is imperative that i make httpconnection so that it completes then pass on the result.
How can I make UI To unblock while executing this code ?
Again i can't call entire function as aysnc because the function is to be called by most sdk functions internally and they will diffidently not call it in Async
You have to use something like an AsyncTask. Of course you can abstract this way from users of your SDK/library so that they call simply call a doLogin() function, and into that function they pass a callback interface that will be called when the login result returns.
public void doLogin(final MyCallback callback) {
new AsyncTask<URL, Void, Boolean> {
protected Boolean doInBackground(URL... urls) {
// make network calls to login in this "background" thread.
loginSuccess = true;
return loginSuccess;
}
protected void onPostExecute(Boolean loginSuccess) {
callback.onResult(loginSuccess);
}
}.execute();
}
Notice how this doLogin method returns immediately, and will call the callback only after the network call has completed (perhaps many seconds later). This is how you do non-blocking work, and keep the main thread and app UI responsive.
How can I make UI To unblock while executing this code ?
Get rid of get() and process the results of the URL in onPostExecute() of your AsyncTask.
Or, replace AsyncTask with a regular thread, and call getResult() on a background thread, with appropriate synchronization logic between them. This would be wasteful, as you should not need two threads here, but it gets the main application thread out of the mix.
You simply cannot call getResult() on the main application thread, for a blocking call, and have that blocking call somehow not block.
Async threads are used for time consuming operations (Network might be slow/server might be slow/ many hops between client server etc.)
To not block the UI thread functioning, while data is being fetched from server, is what async calls are used for.
You can call this function from Asyctasks doInBackground() method.
the UI thread will function normally and process result in PostExecute() callback.
What is the challenge you are facing? surely several functions can call it in async. Do you want to synchronize the Async calls? You can use Executor for that.
Look into Native Android async Class or libraries like LoopJ
Related
I'm looking at the Simple RPC example from grpc.io's basic tutorial:
#Override
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
responseObserver.onNext(checkFeature(request));
responseObserver.onCompleted();
}
...
private Feature checkFeature(Point location) {
for (Feature feature : features) {
if (feature.getLocation().getLatitude() == location.getLatitude()
&& feature.getLocation().getLongitude() == location.getLongitude()) {
return feature;
}
}
// No feature was found, return an unnamed feature.
return Feature.newBuilder().setName("").setLocation(location).build();
}
Are there any caveats to interacting with the StreamObserver from other threads? For example, say checkFeature() asynchronously hits another service, returning a CompletableFuture:
#Override
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
checkFeature(request).
thenAccept(feature -> responseObserver.onNext(feature));
responseObserver.onCompleted();
}
Of course the above wouldn't work because the first thread would execute onCompleted() before the feature is returned. So let's fix that:
#Override
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
checkFeature(request).
thenAccept(feature -> {
responseObserver.onNext(feature);
responseObserver.onCompleted();
});
}
I think this should work, but I'm new to Java so I wonder what ramifications there are. For example,
Will Context.current() be consistent?
Will anything cause the StreamObserver to destruct or close prematurely besides onNext() for a unary calls and onError()?
Is there a better practice?
It would be great if someone could also step me through how they reasoned. I tried looking up actual implementations of StreamObserver but I wasn't sure what to look for.
Using thenAccept() to call onNext() and onCompleted() is fine, because the observer is not called concurrently from multiple threads.
The "broken" example that called onCompleted() separately was broken also because it could have called the observer from multiple threads without any form of synchronization. StreamObservers may not be called from multiple threads simultaneously.
Using thenAccept() isn't quite right though, as it doesn't handle the case where the future fails. So you need to receive the Throwable as well, which can be done with whenComplete():
#Override
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
checkFeature(request).
whenComplete((feature, t) -> {
if (t != null) {
responseObserver.onError(t);
} else {
responseObserver.onNext(feature);
responseObserver.onCompleted();
}
});
}
The Context could easily be "wrong" when processing that lambda. Typically we'd look for "architectural" solutions to make sure the context is propagated, like wrapping all application thread pools in Context.currentContextExecutor() when creating them, so individual call sites don't need to be concerned with propagation. I'm not familiar enough with CompletableFuture to provide strategy for it.
Will Context.current() be consistent?
Context.current() is using ThreadLocal. if you are accessing it on a different thread, it won't be consistent. You can propagate context between threads. You may find this post useful.
Will anything cause the StreamObserver to destruct or close prematurely besides onNext() for a unary calls and onError()?
Yes, Normal flow of StreamObserver ends with onError or onCompleted.
As StreamObserver javadoc states, "Since individual StreamObservers are not thread-safe, if multiple threads will be writing to a StreamObserver concurrently, the application must synchronize calls". If you are calling StreamObserver concurrently, you need to synchronize the calls. In other words, if you know for sure it won't be called concurrently even if you are using multiple threads, it should be fine.
If accessing the same StreamObserver on multiple threads, I would try to synchronize it unless the performance is critical since it is error prone. At least, it deserves a nice comment.
I'm using DeferredResult in my Spring MVC application to handle some server-side processing of a potentially long-running action. It might be very fast, or it could take a second or two.
But in either case, the incoming HTTP request causes an action to be pushed to a queue, which a separate thread (via an ExecutorService) is responsible for consuming. A callback is then called, notifying the pusher that the operation has completed.
I refactored some of this behavior into a utility method:
public static DeferredResult<String> toResponse(GameManager gameManager, final Player player, Action action) {
DeferredResult<String> deferredResult = new DeferredResult<>();
gameManager.execute(action, new Handler<Result>() {
#Override
public void handle(Result result) {
JSONObject obj;
try {
obj = gameManager.getGameJSON(player);
obj.put("success", result.getResult());
obj.put("message", result.getMessage());
deferredResult.setResult(obj.toString()); // POINT B
} catch (JSONException e) {
deferredResult.setErrorResult(e);
}
}
});
return deferredResult; // POINT A
}
But I'm wondering what happens if the execution of the action happens so quickly that the setResult() method is called (POINT B) on the DeferredResult before it has been returned (POINT A) to the calling method.
Will Spring see the returned DeferredResult already has a value and handle it, or does it only begin "watching" for the setter to be called after the instance has been provided?
I've not used Spring but would say that Class DeferredResult<> would be a pretty poor implementation of a Deferred if settlement timing made any difference to the downstream behaviour.
It seems safe to assume that the behaviour would be identical regardless of asynchronous process' timing - milliseconds, seconds or whatever, with the only proviso that a timeout didn't occur in which case the onTimeout handler would run (if set). Even if the Deferred was settled synchronously, in the same code block that created it, the caller function should act on the outcome as expected.
If this assumption is not valid then the Class DeferredResult<> is not fit for purpose and shouldn't be used.
What is the difference between Futures.addCallBack() and Futures.transform() in Google Guava Concurrency.
As per the documentation:
Futures.addCallBack():
addCallback(ListenableFuture<V> future, FutureCallback<? super V> callback) Registers separate success and failure callbacks to be run when the Future's computation is complete or, if the computation is already complete, immediately.
Futures.transform():
transform(ListenableFuture<I> input, AsyncFunction<? super I,? extends O> function) Returns a new ListenableFuture whose result is asynchronously derived from the result of the given Future.
As per my understanding addCallback() will register success or failure callback when asynchronous processing is completed. In this case we can handle the out put based on success or failure conditions (example: logging, flow control..etc). and transform() only return the Asynchronous object back. So difference is only Callback?.
whether my understanding is correct?
Which is the best one to use with asynchronous processing?
If I need to call multiple asynchronous methods in a sequence, is there any best practice for that?
What is the difference between using AsyncFunction and Function in transform(ListenableFuture<I> input, Function/AsyncFunction <? super I,? extends O> function)? (AsyncFunction only used for nested Futures.transform()?)
What I tried:
I try to write code like below, whether this is a good practice or not.
public ListenableFuture<MyObject> doSomething() {
logger.info( "Entered in dosomething() Method." );
ListeningExecutorService executor =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(50));
ListenableFuture<MyObject> myAsyncObject =
calculator.calculateSomething(input);
//internally calculator.calculateSomething() have multiple asynchronous
// calls and I am using Futures.transform(), without callback.
Futures.addCallback(myAsyncObject, new FutureCallback<MyObject>() {
public void onSuccess(MyObject result) {
logger.info( "Calculation Completed successfully." );
//TODO: check for success and log it.
}
public void onFailure(Throwable thrown) {
logErrorDetails(thrown);
}
}, executor);
executor.shutdown();
return myAsyncObject;
}
Well you didn't write the full method signature in your question
addCallback returns nothing
transform returns a future that holds result of the function (if the input succeeded) or the original input's failure (if not). This allows to chain transformations, with a fluent syntax.
I've not used AsyncFunction, but I understand they add one level of asynchronicity, ie the result of the Future is another Future.
I have a centralized socket class which is responsible for sending and retrieving data. I have 2 classes:
one which listens to the input stream and
the other one which takes care of writing to it.
Listening running on an infinite loop and then process the messages. For synchronous i block the read and reset these values once i receive the response from the server.
Now i am stuck with asycnhronous. I have 3 methods in my service.
getSomething
readSomething
saySomething.
In my getSomething i want to implement async functionality based on the boolean flag provided. When my app starts i also start both of my threads and if i send concurrent request.
For example readSomething first and then getSomething then i get the return value for readSomething in getSomething which is not what i desire and i can see in the logs that the output for getSomething comes after a while.
It looks like the Future object requires to submit a new task which will run in it's own thread but the way i have design this app, i just can't create a new thread. Can anyone give me insights on how should i handle this asycnhronous like a flow chart etc ?.
If you're doing work Asynchronously, that means that other part of the application does not care when the async work is done.
What you'll normally want to do is notify the other part, when the async work is done. For this, you'll want to use the "Observer Pattern" (the article includes flow-charts).
The basic idea is, that your app starts the async work and is notified, when the work is done. That way, you can loosely couple two parts of the application. A quick example:
/**
* The observer
*/
public interface AsyncWorkDoneListener{
/**
* This method will be called when the async-thread is
* done.
*/
public void done(Object unit);
}
/**
* The worker (which does the asyc-work on another thread).
*/
public class AsyncWorker{
private AsyncWorkDoneListener listener;
/**
* Set (you might want to maintain a list here) the current
* listener for this "AsyncWorker".
*/
public void setListener(AsyncWorkDoneListener listener){
this.listener = listener;
}
/**
* Will do the async-work
*/
public void doWork(){
// Do the work in another thread...
// When done, notify the registered listener with the
// result of the async work:
this.listener.done(the_object_containing_the_result);
}
}
/**
* The application
*/
public class App implements AsyncWorkDoneListener{
public void someMethod(){
// Work on something asynchronously:
mAsyncWorker.setListener(this);
mAsyncWorker.doWork();
}
#Override
public void done(Object unit){
// The asyc work has finished, do something with
// the result in "unit".
}
}
A couple of insights:
you need dataflow, not flow charts
if you cannot create new thread for each task, you can use fixed-sized thread pool created by java.util.concurrent.Executors.newFixedThreadPool()
you cannot use Future.get() from within a task running in a threadpool, or thread starvation deadlock may occur.
your description of the problem is unclear: too many undeclared notions. "reset these values" - what values? "3 methods in my service" - is it server side or client-side? "boolean flag provided" - do we need to understand who provided that flag and what does it mean?
Please provide a dataflow representation of the program you need to implement in order we could help you.
I'd like to create a Service that's capable of creating a number of objects, where each object connects to the internet and downloads some JSON data and a photo. Most of this is pretty straight forward, but I want it to happen one at a time, i.e. a new object cannot be created until the first object has completed its actions.
What's the best way for my Service to know when an object has performed its actions?
Here's a very rough illustration of what I'm looking for:
Use an IntentService. In normal usage, each Intent it receives is processed sequentially and is already in a background thread, so you don't even need to do your network activity in an AsyncTask. Easy.
Alternately, put all your things in a Queue and have the "do next thing" call happen as a result of the onPostExecute() call in AsyncTasks.
Queue<YourObject> unfinished = getQueue();
List<YourObject> finished = new LinkedList<YourObject>();
Handler handler = new Handler(){
handleMessage(Message m){
// Object populated! Start next? Blink lights? Whatever.
}
}
AsyncTask t = new AsyncTask<...>(handler) {
Handler h;
public AsyncTask<...>(Handler h) {
this.h = h;
}
protected V doInBackground(YourObject o) {
// Network stuff, populate the thing
return popualtedThing();
}
protected V onPostExecute(YourObject o) {
h.sendMessage(Message.obtain(0,o);
}
}.execute();
How about this? When the object creation is complete, broadcast an intent (you could use LocalBroadcast for example, if you want it to be private).
In your Service, register for the above mentioned broadcast, and when it is received, perform the next task.
Use listeners. Have the background service register as a listener to the object instance and when the object instance is does it just calls back to all the listeners.