Hi Andrey,

Thanks for your email, I've attempted to elucidate the current semantics
but there may definitely be room for improvements.

On 10 Feb 2015 17:23, "Andrey" <andrewkor...@hotmail.com> wrote:
>
> 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.

it is only the catchall (NonFatal) that considers it fatal, if you expect
it [NCDFE] in your code, you can/should surround it with a try catch and
promote it to a non fatal exception or otherwise deal with the "normal"
case. "Generic" NCDFEs are definitely not recoverable as they typically
signal that the classpath/application is broken.

>
> 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.

In the face of a fatal error no guarantees can be made as to the
consistency of the JVM nor the data within it, as such we recommend to
forcibly shut down the JVM.

>Please note that the siblings of the failed actor (as well as all other
unrelated actors) do get their postStop() invoked.

Since `postStop` is invoked in the -instance- that produced a fatal failure
I guess there's the philosophical argument to be had whether it can attempt
to stop itself or not.

>
> 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.

That is not a guarantee that can be made nor kept on the JVM as thread
interruption is cooperative and thread stop is undefined.

>
> 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 akka-user+unsubscr...@googlegroups.com.
> To post to this group, send email to akka-user@googlegroups.com.
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.

-- 
>>>>>>>>>>      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 akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
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