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?
Related
My project needs a lot of asynchronous programming so I choose the AKKA platform as with the actor model one can implement asynchronous system just like writing synchronous code without worrying about thread issues. Everything works alright till I meet the following issue(demo code):
import akka.actor.AbstractActor;
import akka.japi.pf.ReceiveBuilder;
import java.util.concurrent.locks.ReentrantLock;
public class TestActor extends AbstractActor {
private final ReentrantLock lock = new ReentrantLock();
#Override
public Receive createReceive() {
return ReceiveBuilder.create()
.matchEquals("lock", s -> lock.lock())
.matchEquals("unlock", s -> lock.unlock())
.build();
}
}
first a "lock" message is send, then a "unlock" message is send, in trying to unlock upon receiving the send message, a IllegalMonitorStateException is thrown, I found out that this is due different messages are actually handled by different threads, s -> lock.lock() and s -> lock.unlock() are executed in different threads so IllegalMonitorStateException is thrown.
My previous assumption is that all actions of an actor is executed in one thread so it is totally thread safe, one dose not have to worry about thread issues. As I use AKKA extensively in my project, now I'm quite concerned and unclear as to when dose one needs to consider thread issue in using AKKA. For example, in following demo code:
public class TestActor1 extends AbstractActor {
private int count = 0;
private Map<Integer, Integer> map = new HashMap<>();
#Override
public Receive createReceive() {
return ReceiveBuilder.create()
.matchEquals("action1", s -> count++)
.matchEquals("action2", s -> getSender().tell(count, getSelf()))
.matchEquals("action3", s -> map.put(3, 2))
.matchEquals("action4", s -> getSender().tell(map.get(3), getSelf()))
.build();
}
}
is the way count and map are used thread safe? Do I need to use volatile for count and use ConcurrentHashMap for map?
ps ======================
The following demo code demonstrates why I need lock in actor, basically I'm implementing a pipeline with back pressure control, once an actor receives too much tasks from upstream actor, it sends an backPressureHi message to the upstream actor to stall the upstream actor execution loop till the back pressure returns to normal and sends a backPressureNormal to resume:
public class PipeLineActor extends AbstractActor {
private final ReentrantLock stallLock = new ReentrantLock();
private Thread executionLoop = new Thread(() -> {
while (true){
stallLock.lock();
stallLock.unlock();
// issue tasks to down stream actors
}
});
#Override
public Receive createReceive() {
return ReceiveBuilder.create()
// down stream actor send "backPressureHi" when back pressure is high to stall the executionLoop
.matchEquals("backPressureHi", s -> stallLock.lock())
// down stream actor send "backPressureNormal" when back pressure resumed normal to resume the executionLoop
.matchEquals("backPressureNormal", s -> stallLock.unlock())
.build();
}
}
Akka is designed to be thread safe. And there is never a need for a locking or synchronisation within an actor. It should not be done.
Akka achieves thread safety by processing a single message at a time. An actor cannot process multiple messages simultaneously. But messages may and will be processed within different threads. (this is the default behaviour but can be changed with a pin dispatcher for example).
From documentation
No concurrency guards such as synchronized or AtomicInteger are needed
since an actor instance processes one message at a time.
To your final questions,
is the way count and map are used thread safe?
Yes, it is thread safe.
Do I need to use volatile for count and use ConcurrentHashMap for map?
No there is no need to do it. See Akka and the Java Memory Model
In layman’s terms this means that changes to internal fields of the
actor are visible when the next message is processed by that actor. So
fields in your actor need not be volatile or equivalent.
Lately I tried to write some unit tests for akka actors to test actors messages flow. I observed some strange behaviour in my tests:
Fields:
private TestActorRef<Actor> sut;
private ActorSystem system;
JavaTestKit AnotherActor;
JavaTestKit YetAnotherActor;
System and actors are created in #Before annotated method:
#Before
public void setup() throws ClassNotFoundException {
system = ActorSystem.apply();
AnotherActor = new JavaTestKit(system);
YetAnotherActor = new JavaTestKit(system);
Props props = MyActor.props(someReference);
this.sut = system.of(props, "MyActor"); }
Next
#Test
public void shouldDoSth() throws Exception {
// given actor
MyActor actor = (MyActor) sut.underlyingActor();
// when
SomeMessage message = new SomeMessage(Collections.emptyList());
sut.tell(message, AnotherActor.getRef());
// then
YetAnotherActor.expectMsgClass(
FiniteDuration.apply(1, TimeUnit.SECONDS),
YetSomeMessage.class);
}
In my code I have:
private void processMessage(SomeMessage message) {
final List<Entity> entities = message.getEntities();
if(entities.isEmpty()) {
YetAnotherActor.tell(new YetSomeMessage(), getSelf());
// return;
}
if (entities > workers.size()) {
throw new IllegalStateException("too many tasks to be started !");
}
}
Basically, sometimes (very rarely) such test fails (on another OS), and the exception from processMessage method is thrown (IllegalStateException due to business logic).
Mostly test pass as YetSomeMessage message is received by YetAnotherActor despite the fact that the IllegateStateException error is thrown as well and logged in stack trace.
As I assume from akka TestActorRef documentation:
This special ActorRef is exclusively for use during unit testing in a single-threaded environment. Therefore, it
overrides the dispatcher to CallingThreadDispatcher and sets the receiveTimeout to None. Otherwise,
it acts just like a normal ActorRef. You may retrieve a reference to the underlying actor to test internal logic.
my system is using only single thread to process messages received by actor. Could someone explain my why despite proper assertion, the test fails ?
Of course returning after sending YetSomeMessage in proper code would be done but I do not understand how another thread processing can lead to test faiulre.
Since you are using TestActorRef, you are basically doing synchronous testing. As a general rule of thumb, don't use TestActorRef unless you really need to. That thing uses the CallingThreadDispatcher, i.e. it will steal the callers thread to execute the actor. So the solution to your mystery is that the actor runs on the same thread as your test and therefore the exception ends up on the test thread.
Fortunately, this test-case of yours do not need the TestActorRef at all. You can just create the actor as an ordinary one, and everything should work (i.e. the actor will be on a proper separate thread). Please try to do everything with the asynchronous test support http://doc.akka.io/docs/akka/2.4.0/scala/testing.html#Asynchronous_Integration_Testing_with_TestKit
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 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
My multi-threaded application has a main class that creates multiple threads. The main class will wait after it has started some threads. The runnable class I created will get a file list, get a file, and remove a file by calling a web service. After the thread is done it will notify the main class to run again. My problem is it works for a while but possibly after an hour or so it will get to the bottom of the run method from the output I see in the log and that is it. The Java process is still running but it does not do anything based on what I am looking at in the log.
Main class methods:
Main method
while (true) {
// Removed the code here, it was just calling a web service to get a list of companies
// Removed code here was creating the threads and calling the start method for threads
mainClassInstance.waitMainClass();
}
public final synchronized void waitMainClass() throws Exception {
// synchronized (this) {
this.wait();
// }
}
public final synchronized void notifyMainClass() throws Exception {
// synchronized (this) {
this.notify();
// }
}
I originally did the synchronization on the instance but changed it to the method. Also no errors are being recorded in the web service log or client log. My assumption is I did the wait and notify wrong or I am missing some piece of information.
Runnable Thread Code:
At the end of the run method
// This is a class member variable in the runnable thread class
mainClassInstance.notifyMainClass();
The reason I did a wait and notify process because I do not want the main class to run unless there is a need to create another thread.
The purpose of the main class is to spawn threads. The class has an infinite loop to run forever creating and finishing threads.
Purpose of the infinite loop is for continually updating the company list.
I'd suggest moving from the tricky wait/notify to one of the higher-level concurrency facilities in the Java platform. The ExecutorService probably offers the functionality you require out of the box. (CountDownLatch could also be used, but it's more plumbing)
Let's try to sketch an example using your code as template:
ExecutorService execSvc = Executors.newFixedThreadPool(THREAD_COUNT);
while (true) {
// Removed the code here, it was just calling a web service to get a list of companies
List<FileProcessingTask> tasks = new ArrayList<FileProcessingTask>();
for (Company comp:companyList) {
tasks.add(new FileProcessingTask(comp));
}
List<Future<FileProcessingTask>> results = execSvc.invokeAll(tasks); // This call will block until all tasks are executed.
//foreach Future<FileProcessingTask> in results: check result
}
class FileProcessingTask implements Callable<FileResult> { // just like runnable but you can return a value -> very useful to gather results after the multi-threaded execution
FileResult call() {...}
}
------- edit after comments ------
If your getCompanies() call can give you all companies at once, and there's no requirement to check that list continuously while processing, you could simplify the process by creating all work items first and submit them to the executor service all at once.
List<FileProcessingTask> tasks = new ArrayList<FileProcessingTask>();
for (Company comp:companyList) {
tasks.add(new FileProcessingTask(comp));
}
The important thing to understand is that the executorService will use the provided collection as an internal queue of tasks to execute. It takes the first task, gives it to a thread of the pool, gathers the result, places the result in the result collection and then takes the next task in the queue.
If you don't have a producer/consumer scenario (cfr comments), where new work is produced at the same time that task are executed (consumed), then, this approach should be sufficient to parallelize the processing work among a number of threads in a simple way.
If you have additional requirements why the lookup of new work should happen interleaved from the processing of the work, you should make it clear in the question.