There is something I can't understand. I have several RPC calls in my GWT code like:
private final PravformServiceAsync getPravformService = GWT.create(PravformService.class);
getService.getSome(new AsyncCallback<List<Pravform>>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(List<Pravform> result) {
pravformList = result;
}
});
which must executes at the program start. But with help of debugger I saw that code inside these calls doesn't execute at that time. It executes at the end of onModuleLoad() procedure executing, after all other code. It looks like my RPC calls executes on the second circle of code executing.
Please explain me why it happens.
That is what exactly asyncronous means,You never know when server returns that result to client,and mean while the flow continues.That is why people usually write their code in onSuccess(),so that futhure execution of flow stops until the request completes.
A clear cut execution and RPC Plumbing Diagram is there is Docs.
Please have a look.
The Async in the interface names stands for asynchronous. There's a reason you have to make those interfaces taking a callback rather than use the synchronous interfaces that just return a value. That reason is they're synchronous, aka non blocking.
Related
I'm currently checking out the following guide: https://developer.android.com/topic/libraries/architecture/guide.html
The networkBoundResource class:
// ResultType: Type for the Resource data
// RequestType: Type for the API response
public abstract class NetworkBoundResource<ResultType, RequestType> {
// Called to save the result of the API response into the database
#WorkerThread
protected abstract void saveCallResult(#NonNull RequestType item);
// Called with the data in the database to decide whether it should be
// fetched from the network.
#MainThread
protected abstract boolean shouldFetch(#Nullable ResultType data);
// Called to get the cached data from the database
#NonNull #MainThread
protected abstract LiveData<ResultType> loadFromDb();
// Called to create the API call.
#NonNull #MainThread
protected abstract LiveData<ApiResponse<RequestType>> createCall();
// Called when the fetch fails. The child class may want to reset components
// like rate limiter.
#MainThread
protected void onFetchFailed() {
}
// returns a LiveData that represents the resource
public final LiveData<Resource<ResultType>> getAsLiveData() {
return result;
}
}
I'm a bit confused here about the use of threads.
Why is #MainThread applied here for networkIO?
Also, for saving into the db, #WorkerThread is applied, whereas #MainThread for retrieving results.
Is it bad practise to use a worker thread by default for NetworkIO and local db interaction?
I'm also checking out the following demo (GithubBrowserSample): https://github.com/googlesamples/android-architecture-components
This confuses me from a threading point of view.
The demo uses executors framework, and defines a fixed pool with 3 threads for networkIO, however in the demo only a worker task is defined for one call, i.e. the FetchNextSearchPageTask. All other network requests seem to be executed on the main thread.
Can someone clarify the rationale?
It seems you have a few misconceptions.
Generally it is never OK to call network from the Main (UI) thread but unless you have a lot of data it might be OK to fetch data from DB in the Main thread. And this is what Google example does.
1.
The demo uses executors framework, and defines a fixed pool with 3 threads for networkIO, however in the demo only a worker task is defined for one call, i.e. the FetchNextSearchPageTask.
First of all, since Java 8 you can create simple implementation of some interfaces (so called "functional interfaces") using lambda syntax. This is what happens in the NetworkBoundResource:
appExecutors.diskIO().execute(() -> {
saveCallResult(processResponse(response));
appExecutors.mainThread().execute(() ->
// we specially request a new live data,
// otherwise we will get immediately last cached value,
// which may not be updated with latest results received from network.
result.addSource(loadFromDb(),
newData -> result.setValue(Resource.success(newData)))
);
});
at first task (processResponse and saveCallResult) is scheduled on a thread provided by the diskIO Executor and then from that thread the rest of the work is scheduled back to the Main thread.
2.
Why is #MainThread applied here for networkIO?
and
All other network requests seem to be executed on the main thread.
This is not so. Only result wrapper i.e. LiveData<ApiResponse<RequestType>> is created on the main thread. The network request is done on a different thread. This is not easy to see because Retrofit library is used to do all the network-related heavy lifting and it nicely hides such implementation details. Still, if you look at the LiveDataCallAdapter that wraps Retrofit into a LiveData, you can see that Call.enqueue is used which is actually an asynchronous call (scheduled internally by Retrofit).
Actually if not for "pagination" feature, the example would not need networkIO Executor at all. "Pagination" is a complicated feature and thus it is implemented using explicit FetchNextSearchPageTask and this is a place where I think Google example is done not very well: FetchNextSearchPageTask doesn't re-use request parsing logic (i.e. processResponse) from RepoRepository but just assumes that it is trivial (which it is now, but who knows about the future...). Also there is no scheduling of the merging job onto the diskIO Executor which is also inconsistent with the rest of the response processing.
I have a webapp in which I have to return the results from a mongodb find() to the front-end from my java back-end.
I am using the Async Java driver, and the only way I think I have to return the results from mongo is something like this:
public String getDocuments(){
...
collection.find(query).map(Document::toJson)
.into(new HashSet<String>(), new SingleResultCallback<HashSet<String>>() {
#Override
public void onResult(HashSet<String> strings, Throwable throwable) {
// here I have to get all the Json Documents in the set,
// make a whole json string and wake the main thread
}
});
// here I have to put the main thread to wait until I get the data in
// the onResult() method so I can return the string back to the front-end
...
return jsonString;
}
Is this assumption right or thereĀ“s another way to do it?
Asynchronous APIs (any API based on callbacks, not necessarily MongoDB) can be a true blessing for multithreaded applications. But to really benefit from them, you need to design your whole application architecture in an asynchronous fashion. This is not always feasible, especially when it is supposed to fit into a given framework which isn't built on callbacks.
So sometimes (like in your case) you just want to use an asynchronous API in a synchronous fashion. In that case, you can use the class CompletableFuture.
This class provides (among others) two methods <T> get() and complete(<T> value). The method get will block until complete is called to provide the return value (should complete get called before get, get returns immediately with the provided value).
public String getDocuments(){
...
CompletableFuture<String> result = new CompletableFuture<>(); // <-- create an empty, uncompleted Future
collection.find(query).map(Document::toJson)
.into(new HashSet<String>(), new SingleResultCallback<HashSet<String>>() {
#Override
public void onResult(HashSet<String> strings, Throwable throwable) {
// here I have to get all the Json Documents in the set and
// make a whole json string
result.complete(wholeJsonString); // <--resolves the future
}
});
return result.get(); // <-- blocks until result.complete is called
}
The the get()-method of CompletableFuture also has an alternative overload with a timeout parameter. I recommend using this to prevent your program from accumulating hanging threads when the callback is not called for whatever reason. It will also be a good idea to implement your whole callback in a try { block and do the result.complete in the finally { block to make sure the result always gets resolved, even when there is an unexpected error during your callback.
Yes, you're right.
That's the correct behaviour of Mongo async driver (see MongoIterable.into).
However, Why don't you use sync driver in this situation? Is there any reason to use async method?
I have a Play framework 2 application that also uses Akka. I have an Actor that receives messages from a remote system, the amount of such messages can be very huge. After a message is received, i log it into the database (using the built-in Ebean ORM) and then continue to process it. I don't care, how fast this database logging works, but it definitely should not block the further processing. Here is a simplified code sample:
public class MessageReceiver extends UntypedActor {
#Override
public void onReceive(Object message) throws Exception {
if (message instanceof ServerMessage) {
ServerMessage serverMessage = (ServerMessage) message;
ServerMessageModel serverMessageModel = new ServerMessageModel(serverMessage);
serverMessageModel.save();
//now send the message to another actor for further processing
} else {
unhandled(message);
}
}
}
As i understand, database inserting is blocking in this realization, so it does not meet my needs. But i can't figure out how to make it unblocking. I've read about the Future class, but i can't get it to work, since it should return some value, and serverMessageModel.save(); returns void.I understand that writing a lot of messages one-by-one into the database is unefficient, but that is not the issue at the moment.
Am i right that this implementation is blocking? If it is, how can i make it run asynchronously?
Future solution seems good to me. I haven't used Futures from Java, but you can just return arbitrary Integer or String if you definitely need some return value.
Other option is to send that message to some other actor which would do the saving to the DB. Then you should make sure that the mailbox of that actor would not overfill.
Have you considered akka-persistence for this? Maybe that would suit your use-case.
If you wish to use Future - construct an Akka Future with a Callable (anonymous class), whose apply() will actually implement the db save code. You can actually put all of this (future creation and apply()) in your ServerMessageModel class -- maybe call it asynchSave(). Your Future maybe Future where status is the result of asynchSave...
public Future<Status> asyncSave(...) { /* should the params be ServerMessageModel? */
return future(new Callable<Status>() {
public Status call() {
/* do db work here */
}
}
In your onReceive you can go ahead with tell to the other actor. NOTE: if you want to make sure that you are firing the tell to the other actor after this future returns, then you could use Future's onSuccess.
Future<Status> f = serverMessageModel.asyncSave();
f.onSuccess(otherActor.tell(serverMessage, self());
You can also do failure handling... see http://doc.akka.io/docs/akka/2.3.4/java/futures.html for further details.
Hope that helps.
Persist actor state with Martin Krassers akka-persistence extension and my jdbc persistence provider akka persistence jdbc https://github.com/dnvriend/akka-persistence-jdbc
I'm working in an Spring application that downloads data from different APIs. For that purpose I need a class Fetcher that interacts with an API to fetch the needed data. One of the requirements of this class is that it has to have a method to start the fetching and a method to stop it. Also, it must download all asynchronously because users must be able to interact with a dashboard while fetching data.
Which is the best way to accomplish this? I've been reading about task executors and the different annotations of Spring to schedule tasks and execute them asynchronously but this solutions don't seem to solve my problem.
Asynchronous task execution is what you're after and since Spring 3.0 you can achieve this using annotations too directly on the method you want to run asyncrhonously.
There are two ways of implementing this depending whether you are interested in getting a result from the async process:
#Async
public Future<ReturnPOJO> asyncTaskWithReturn(){
//..
return new AsyncResult<ReturnPOJO>(yourReturnPOJOInstance);
}
or not:
#Async
public void asyncTaskNoReturn() {
//..
}
In the former method the result of your computation conveyed by yourReturnPOJOInstance object instance, is stored in an instance of org.springframework.scheduling.annotation.AsyncResult<V> which in return implements the java.util.concurrent.Future<V> that the caller can use to retrieve the result of the computation later on.
To activate the above functionality in Spring you have to add in your XML config file:
<task: annotation-driven />
along with the needed task namespace.
The simplest way to do this is to use the Thread class. You supply a Runnable object that performs the fetching functionality in the run() method and when the Thread is started, it invokes the run method in a separate thread of execution.
So something like this:
public class Fetcher implements Runnable{
public void run(){
//do fetching stuff
}
}
//in your code
Thread fetchThread = new Thread(new Fetcher());
fetchThread.start();
Now, if you want to be able to cancel, you can do that a couple of ways. The easiest (albeit most violent and nonadvisable way to do it is to interrupt the thread:
fetchThread.interrupt();
The correct way to do it would be to implement logic in your Fetcher class that periodically checks a variable to see whether it should stop doing whatever it's doing or not.
Edit To your question about getting Spring to run it automatically, if you wanted it to run periodically, you'll need to use a scheduling framework like Quartz. However, if you just want it to run once what you could do is use the #PostConstruct annotation. The method annotated with #PostConstruct will be executed after the bean is created. So you could do something like this
#Service
public class Fetcher implements Runnable{
public void run(){
//do stuff
}
#PostConstruct
public void goDoIt(){
Thread trd = new Thread(this);
trd.start();
}
}
Edit 2 I actually didn't know about this, but check out the #Async discussion in the Spring documentation if you haven't already. Might also be what you want to do.
You might only need certain methods to run on a separate thread rather than the entire class. If so, the #Async annotation is so simple and easy to use.
Simply add it to any method you want to run asynchronously, you can also use it on methods with return types thanks to Java's Future library.
Check out this page: http://www.baeldung.com/spring-async
I'm integrating Akka in an existing software, mainly to make things asynchronous where they shouldn't be synchronous.
I've a service that is making some database calls, at the moment, everything is synchronous, the calling thread is just sitting here and waiting for the result...
My idea is to replace the DAO interface to have Future<T> (Akka's) as results instead of actual result types, thus, my DAO implementation is actually transforming those call in messages and routes them to appropriate actors (local and/or remote).
Now I'm a bit puzzled when it comes to how to return a Future<T> when I call the actor. Is there any other way than using Patterns.ask() ? Is it the best solution performance-wise (without rewriting everything using actors) ?
Using Patterns.ask(), how could I return an error without waiting for the timeout ? If the actor I call simply tells back the error, it would trigger a success, when I want to trigger a failure.
Edits
I'm using Java.
Right now, I came up with a construct like the one below, but, it implies my actor has to tell() the exception back to the sender.
final Future<Object> f = Patterns.ask(..., ..., ...);
f.flatMap(new Mapper<Object, Future<List<Element>>>() {
public Future<List<Element>> apply(Object response) {
if (response instanceof SuccessfulResult) {
return Futures.successful(response, f.executor());
} else if (response instanceof Throwable) {
return Futures.failed((Throwable) response, f.executor());
} else {
return Futures.failed(..., f.executor());
}
}
To differentiate between success or failure you would use scala.Either. So the answer type could look something like this:
type Result = Future[Either[SQLException, MyDataType]]