I have a layered architecture in a Java web application. The UI layer is just Java, services are typed Akka actors and external service calls (WS, DB etc.) are wrapped in Hystrix commands.
THe UI calls the service and the service returns an Akka future. It's an Akka future because I want to make UI coding simpler with the onComplete and onFailure callbacks that Akka futures provide. The service then creates the future that does some mapping etc. and wraps a call to a HystrixCommand that returns a Java future.
So in pseudocode:
UI
AkkaFuture future = service.getSomeData();
Service
public AkkaFuture getSomeData() {
return future {
JavaFuture future = new HystrixCommand(mapSomeData()).queue()
//what to do here, currently just return future.get()
}
}
The problem is that I would like to free up the thread the service actor is using and just tie up the threads that Hystrix uses. But the java future prevents that because I have to block on it's completion. The only option I can think of (which I'm not sure I like) is to poll the Java future(s) constantly and complete the Akka future when the Java future finishes.
Note: the question isn't really related to Hystrix per se, but I decided to mention it if somebody comes up with a solution specifically related to Hystrix.
I'm marking the answer by #Hbf as a solution, since I ended up doing an Akka poller as explained in How do I wrap a java.util.concurrent.Future in an Akka Future?. For reference I also tried:
Creating a HystrixCommandExcutionHook and extending HystrixCommand to allow callbacks. That didn't work because the hook wasn't called at the right time.
Using Guavas listenable future by having a decorated executor create the futures inside Hystrix and then casting the futures from the commands. Doesn't work because Hystrix uses a ThreadPoolExecutor which can't be decorated.
EDIT: I'm adding the Akka poller code below, since the original answer was in Scala and it hangs if the Java future doesn't cancel nicely. The solution below always walks away from threads after a timeout.
protected Future wrapJavaFutureInAkkaFuture(final java.util.concurrent.Future javaFuture, final Option maybeTimeout, final ActorSystem actorSystem) {
final Promise promise = Futures.promise();
if (maybeTimeout.isDefined()) {
pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, Option.option(maybeTimeout.get().fromNow()), actorSystem);
} else {
pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, Option. none(), actorSystem);
}
return promise.future();
}
protected void pollJavaFutureUntilDoneOrCancelled(final java.util.concurrent.Future javaFuture, final Promise promise, final Option maybeTimeout, final ActorSystem actorSystem) {
if (maybeTimeout.isDefined() && maybeTimeout.get().isOverdue()) {
// on timeouts, try to cancel the Java future and simply walk away
javaFuture.cancel(true);
promise.failure(new ExecutionException(new TimeoutException("Future timed out after " + maybeTimeout.get())));
} else if (javaFuture.isDone()) {
try {
promise.success(javaFuture.get());
} catch (final Exception e) {
promise.failure(e);
}
} else {
actorSystem.scheduler().scheduleOnce(Duration.create(50, TimeUnit.MILLISECONDS), new Runnable() {
#Override
public void run() {
pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeTimeout, actorSystem);
}
}, actorSystem.dispatcher());
}
}
Java futures are known to be inferior in design compared to something like Scala futures. Take a look at the discussion "How do I wrap a java.util.concurrent.Future in an Akka Future", for example.
But: Maybe, instead of polling (as suggested in the above discussion), Hystrix offers some kind of onComplete callback? I do not know the library at all but stumbled upon an onComplete in the Hystrix API. Maybe it helps?
As of Hystrix 1.3 it now also supports true non-blocking callbacks and that will fit much better into Akka/Scala Future behavior that is non-blocking and composable: https://github.com/Netflix/Hystrix/wiki/How-To-Use#wiki-Reactive-Execution
Related
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 using Retrofit to return rxjava Observable's for my async network calls.
I find myself repeating the following invocation:
someApiCall().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
Seems like I'm always subscribing on the IO thread and observing on the Android main thread. This seems to be the best practice that all the resources I found advocate. Perhaps other than long-running computations, I don't quite understand when we would want to deviate from this pattern.
Is there a way to remove this boilerplate by defaulting the subscribeOn and observeOn threads?
Is this a use case for rxjava plugins? (I can't find many examples of their use.)
Can I set the default threads at the network boundary by messing with the retrofit executors?
For Observable responses, Retrofit currently sets the subscribeOn as the HTTP executor of the RestAdapter (either provided or the default). This was done to shim RxJava support into the existing behavior.
The plan for 2.0 is to provide the ability to set defaults for both subscribeOn and observeOn explicitly (whether it be both, only one, or neither).
A reason you wouldn't want always want observation on the main thread is if you needed to chain multiple API calls together, for example.
The Change Log of Retrofit Version 2.0.0-beta2 (2015-09-28) shows subscribeOn() is required for running in the background.
Fix: Observable and Single-based execution of requests now behave synchronously (and thus requires subscribeOn() for running in the background).
Yes, it's possible to remove both calls.
Here is the retrofit adapter class that automatically schedules both subscribeOn and observedOn to remove the need for the boilerplate calls in each invocation:
public class RxThreadingCallAdapterFactory extends CallAdapter.Factory {
private final RxJava2CallAdapterFactory original;
private RxThreadingCallAdapterFactory() {
// Always call on background thread
original = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io());
}
public static CallAdapter.Factory create() {
return new RxThreadingCallAdapterFactory();
}
#Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new RxCallAdapterWrapper(original.get(returnType, annotations, retrofit));
}
private static class RxCallAdapterWrapper implements CallAdapter<Observable<?>> {
private final CallAdapter<?> wrapped;
public RxCallAdapterWrapper(CallAdapter<?> wrapped) {
this.wrapped = wrapped;
}
#Override
public Type responseType() {
return wrapped.responseType();
}
#Override
public <R> Observable<?> adapt(Call<R> call) {
Observable observable = (Observable) wrapped.adapt(call);
// Always handle result on main thread
return observable.observeOn(AndroidSchedulers.mainThread());
}
}
}
Then use this adapter when configuring retrofit:
Retrofit.Builder()
.baseUrl(...)
.addCallAdapterFactory(RxThreadingCallAdapterFactory.create())
I wrote this blog post that goes into a lot of detail on exactly what's happening here.
This will remove both calls, which I consider boilerplate. I consider Jake's scenario of chaining together background calls to not really apply, because in this case I would do retrofit synchronous calls and not use schedulers at all.
it is not the full answer to what you are looking for, but this at least removes the burden of righting subscribeOn(Schedulers.io())
retrofit = new Retrofit
.Builder()
.baseUrl(app.getUrlBase())
.client(httpClient)
.addCallAdapterFactory(
RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()) // <-- default subscribeOn()
)
.addConverterFactory(jsonFactory)
.build();
I am reading about Scala’s actors, so say we have something like:
object Worker extends Actor {
def act() {
while(true) {
receive {
case "exit" => {
println("exiting...")
sender ! Exit
}
case s:String if s.startsWith("scp") => {
println("Starting scp")
Thread.sleep(2000)
sender ! Done(s)
}
case s:String => {
println("Starting " + s)
sender ! Done(s)
}
}
}
}
}
(http://www.naildrivin5.com/scalatour/wiki_pages/ActorsAndConcurrency)
What would the equivalent pattern be like with Java? I understand it is much more cumbersome to do this in Java.
Are there any performance implications with Scala’s actors? Sure it is way easier to both implement and understand from what I gather, but curious if there any tradeoffs.
Take a look in akka framework. With it you will have the power of Actor Model in Java.
As someone else mentioned Akka is probably the best candidate, as while it has been written in Scala, it has been done in such a way as to also make it very accessible from Java. As a side note to that the Akka implementation will replace the current implementation in the future.
Also the Scala actor implementation isn't a feature of the language itself, it's just that the standard library includes that implementation.
As far as the performance implications the current Scala implementation isn't that good anyway, so would be a bad example. I can't highly recommend the docs for the Akka one enough however: http://doc.akka.io/docs/akka/2.0.4/
Scala's actor (not to mix with akka's actor) is effectively a thread with an input queue, and its equivalent can be easily implemented in java:
interface Port<T>{
public void send(T msg);
}
class StringMessage {
String value;
Port sender;
}
class Worker extends Thread implements Port<StringMessage>{
ConcurrentLinkedQueue<StringMessage > q=new ConcurrentLinkedQueue<StringMessage >();
public send(StringMessage m) {
q.put(m);
}
public void run() {
while(true) {
StringMessage msg=q.take();
String s=msg.value;
if (s.equals("exit") {
println("exiting...");
msg.sender.send(Exit);
return;
} else if (s.startsWith("scp") {
println("Starting scp")
Thread.sleep(2000)
msg.sender.send(Exit);
} else {
println("Starting " + s)
msg.sender.send(Done(s));
}
}
}
}
This is only a sketch, to make it workable you have to develop contracts and protocols between communicating threads. Or you can take an existing actor framework for java (there are many).
To choose wisely, you have to answer following questions:
should actors be based on Threads or lightweight tasks executing on a thread pool? Threads consume much memory, but allow blocking operations. Most widely known Akka framework uses lightweight tasks.
is actor model enough for you? Classic actor have single input port, more broad dataflow model allow actor node to have several input ports, and the firing occurs when all input ports are not empty. This allow to construct "nested callbacks" as in another question. Java dataflow frameworks are rare, the only opensource library I know is mine df4j. It allows both thread-based and task-based actor nodes, and have subclass Actor with single input.
In Java, I've gotten used to working with Futures. Now I'm looking at Android, and AsyncTask implements almost all the same methods and covers similar lifecycles. But, if I want to be consistent and use Future all over my code, I have to wrap AsyncTask in a stupid wrapper, cause it doesn't actually implement Future.
All they'd need to add is an isDone() method, which seems like it would be trivial, then add implements Future<Result>. (added later: see my answer below for just how trivial it would be).
Any Android experts know some good reason / obscure bug it might cause why this hasn't been done?
From reading the actual code of AsyncTask.java it actually uses a Future task and then some more. A Future is a task that executes asynchronously on the go. An AsyncTask is scheduled on a queue for a single (or pool of) background thread(s).
An AsyncTask is actually more "superior" than a Future task. It does fancy scheduling and optimizations on top of Future's functionality. Just look at the API introduction levels. Future was introduced right from the start API 1.0. The AsyncTask object was introduced in API 3.
An AsyncTask has-a Future task, not is-a Future.
AsyncTask.java
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker) {
#Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
I'm still interested in the theoretical reasons "why" not to use AsyncTask for a Future.
But, for the record, I ended up creating my own little class (shown below). Just extend it instead of AsyncTask if you want a Future. IMO, a cleaner way than the #Eng.Fouad idea of accessing the private mFuture within the code. (But thanks for the idea, it got me looking into the source code a bit!) YMMV.
public abstract class FutureAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> implements Future<Result>{
#Override
public boolean isDone() {
return AsyncTask.Status.FINISHED == getStatus();
}
}
AsyncTask is too simple. It's intended for short tasks which may take a few seconds, but for which you don't want to lock up the UI thread. If you actually need a Future, your task is probably too complex for an AsyncTask anyway.
You can check the status of an AsyncTask by calling getStatus(). This will return an enum which can be one of Status.PENDING, Status.RUNNING or Status.FINISHED.
I'm using the Java API for Akka 2.0, and have a sinking feeling that I'm not using the ActorSystem correctly to start and/or/xor stop TypedActors. When the application shuts down, the java process doesn't terminate. Upon debugging, I see that the default dispatcher still has multiple running threads, and the scheduler is still running. Is there anything obvious I'm doing wrong in the example below?
Config akkaConf = ConfigFactory.load();
ActorSystem actorSystem = ActorSystem.create("myApp", akkaConf);
TypedProps<Actor1Impl> actor1TypedProps = new TypedProps<Actor1Impl>(Actor1Interface.class, new Creator<Actor1Impl>(
public Actor1Impl create() {
return new Actor1Impl(nonDefault, constructor, scalaIsSo, muchMoreElegant);
}
);
Actor1Interface a1 = TypedActor.get(actorSystem).typedActorOf(actor1TypedProps, "anA1Actor");
Unbeknownst to the readers (and for the sake of brevity), the Actor1Impl class implements TypedActor.PreStart and .PostStop. In PreStart, it schedules a Runnable task to execute periodically. I thought that could have been keeping the Scheduler active, but I've also saved off the returned Cancellable, which I believe I should cancel in a PostStop block. Which did not help terminate the Scheduler thread. Anyway, back to the story...
There are also a number of other actor types, each with a nonStandard constructor. Some of these register periodic Runnables with the scheduler, as did Actor1Impl above. And to compound the fun, some even require other Actors as constructor arguments, in order for the actors to register for callbacks, like so:
public Actor2Impl(Actor1Interface a1) {
a1.registerCallback(TypedActor.<Actor2Interface>self());
}
After it is determined that the app has outlived its usefulness, the following is performed:
TypedActor.get(actorSystem).stop(a1);
TypedActor.get(actorSystem).stop(a2);
...
TypedActor.get(actorSystem).stop(aN);
actorSystem.shutdown();
Is there anything I'm doing that is blatantly wrong which would keep the java process from terminating? Specifically, anything which would cause the scheduler and default dispatcher from shutting down?