Hello,

I have Akka configured not to exit JVM on fatal errors by setting the 
"akka.jvm-exit-on-fatal-error" property to "off". In such case, it's 
expected to shutdown the actor system. (As a side note, I find Scala's 
opinion as to which java.lang.Error are to be treated as fatal and 
non-fatal to be mildly peculiar. One example would be the OSGi environment 
where NoClassDefFoundError is not a fatal exception, but on the contrary, 
is very much recoverable without a JVM restart. Scala disagrees.)

Anyway, back to the problem, Akka seems to recognize the setting correctly 
and doesn't halt the JVM process. However, when later I call a shutdown() 
followed by an awaitTermination() on the instance of the actor system whose 
actor has just "fatally" failed, the awaitTermination() call never returns 
(blocks forever). Also, neither the actor that has thrown the Error, nor 
its parents (up the supervision tree) get called postStop(). It looks 
almost like if Akka forgets to stop the failed actor and its immediate 
parent is left waiting forever unable to proceed with its own shutdown. 
Please note that the siblings of the failed actor (as well as all other 
unrelated actors) do get their postStop() invoked. 

Although I could not find anything relevant in Akka documentation, my 
expectation is that postStop() of all actors is always invoked during actor 
system shutdown.

Below is a simple unit test that demonstrates the problem.

Thanks you for your help.
Andrey

package example;

import java.util.concurrent.TimeUnit;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;
import com.google.common.util.concurrent.SettableFuture;
import com.typesafe.config.ConfigFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import scala.concurrent.duration.Duration;

public class AkkaUtilTest {
    ActorSystem akka;

    @Before
    public void setUp() throws Exception {
        akka = ActorSystem.create("test",
                ConfigFactory.parseString("akka.jvm-exit-on-fatal-error=off"
));
    }

    @After
    public void tearDown() throws Exception {
        akka.shutdown();
        // This call never returns.
        akka.awaitTermination(Duration.create(5000, TimeUnit.MILLISECONDS));
    }

    @Test(timeout = 2000)
    public void testError() throws Exception {
        SettableFuture<?> result = SettableFuture.create();
        ActorRef actorRef = akka.actorOf(Props.create(ThrowingActor.class, 
result));

        actorRef.tell(new Object(), ActorRef.noSender());

        // The get() call never returns and the test times out.
        result.get();
    }

    static class ThrowingActor extends UntypedActor {
        final SettableFuture<?> stopped;

        ThrowingActor(SettableFuture<?> stopped) {
            this.stopped = stopped;
        }

        @Override
        public void onReceive(Object message) throws Exception {
            // These cause postStop() never called on this actor and the 
actor system can't be
            // gracefully shutdown.

            //throw new OutOfMemoryError("oh, my!");
            throw new NoClassDefFoundError("no-class-def");

            // These work just fine:
            // throw new AssertionError("assertion");
            // throw new Error("error");
        }

        @Override
        public void postStop() throws Exception {
            // Never called.
            stopped.set(null);
        }
    }
}



-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to