This page is no longer maintained — Please continue to the home page at www.scala-lang.org

actors and uncaught exceptions

6 replies
J Robert Ray
Joined: 2008-12-18,
User offline. Last seen 3 years 16 weeks ago.

Given this sample code:

val a = actor {
loop {
react {
case "die" => throw new RuntimeException
case x => println(x)
}
}
}

After executing

a ! "die"

"a" becomes a lifeless actor. I can send messages to it, and see its
mailboxSize increase, but it no longer processes messages.
Tangentially, I see that I can "a.start" to bring it back to life, but
I don't see a way to ask it if it is alive.

I find myself adding try {} blocks to all my actor code within react
to log uncaught exceptions and prevent the loop from unraveling.

My question to the list is if this behavior is part of the design of
the actor library, and wouldn't it be worthwhile for the actor library
to catch these uncaught exceptions to prevent these zombie actor
conditions.

I have begun using java Executors in my application as well as actors,
and I noticed that uncaught exceptions do not disable the Executor.

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: actors and uncaught exceptions
Robert,

For better or worse, the Scala Actor library mirrors the Erlang Actor library.  Uncaught exceptions cause the Actor to exit.  If the Actor is linked to another Actor, the linkee will receive a notification.  I've built a class called ActorWatcher:

object ActorWatcher extends Actor {
  def act = loop {
    react {
      case Exit(actor: Actor, why: Throwable) =>
        failureFuncs.foreach(f => f(actor, why))
 
      case _ =>
    }
  }

  private def startAgain(a: Actor, ignore: Throwable) {
    a.start
    a ! RelinkToActorWatcher
  }

  private def logActorFailure(actor: Actor, why: Throwable) {
    Log.error("The ActorWatcher restarted "+actor+" because "+why, why)
  }

  /**
   * If there's something to do in addition to starting the actor up, pre-pend the
   * actor to this List
   */
  var failureFuncs: List[(Actor, Throwable) => Unit] = logActorFailure _ ::
  startAgain _ :: Nil

  this.start
  this.trapExit = true
}

case object RelinkToActorWatcher

in your Actor:

class MyActor extends Actor {

  def act = loop {
      react {
        case RelinkToActorWatcher => link(ActorWatcher)
      }
  }

  this ! RelinkToActorWatcher
}

I agree it's not the best mixing of metaphors, but at least you can deal with it.

Thanks,

David

On Mon, Jan 26, 2009 at 4:37 PM, J Robert Ray <jrobertray [at] gmail [dot] com> wrote:
Given this sample code:

val a = actor {
 loop {
   react {
     case "die" => throw new RuntimeException
     case x => println(x)
   }
 }
}

After executing

a ! "die"

"a" becomes a lifeless actor. I can send messages to it, and see its
mailboxSize increase, but it no longer processes messages.
Tangentially, I see that I can "a.start" to bring it back to life, but
I don't see a way to ask it if it is alive.

I find myself adding try {} blocks to all my actor code within react
to log uncaught exceptions and prevent the loop from unraveling.

My question to the list is if this behavior is part of the design of
the actor library, and wouldn't it be worthwhile for the actor library
to catch these uncaught exceptions to prevent these zombie actor
conditions.

I have begun using java Executors in my application as well as actors,
and I noticed that uncaught exceptions do not disable the Executor.



--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Tony Morris
Joined: 2008-12-19,
User offline. Last seen 30 weeks 4 days ago.
Re: actors and uncaught exceptions

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

There is an alternative actor library in Functional Java (with some
Scala sugar on top) that handles failures using Either which
alleviates much of this problem.

J Robert Ray wrote:
> Given this sample code:
>
> val a = actor { loop { react { case "die" => throw new
> RuntimeException case x => println(x) } } }
>
> After executing
>
> a ! "die"
>
> "a" becomes a lifeless actor. I can send messages to it, and see
> its mailboxSize increase, but it no longer processes messages.
> Tangentially, I see that I can "a.start" to bring it back to life,
> but I don't see a way to ask it if it is alive.
>
> I find myself adding try {} blocks to all my actor code within
> react to log uncaught exceptions and prevent the loop from
> unraveling.
>
> My question to the list is if this behavior is part of the design
> of the actor library, and wouldn't it be worthwhile for the actor
> library to catch these uncaught exceptions to prevent these zombie
> actor conditions.
>
> I have begun using java Executors in my application as well as
> actors, and I noticed that uncaught exceptions do not disable the
> Executor.
>
>
>

- --
Tony Morris
http://tmorris.net/

S, K and I ought to be enough for anybody.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkl+WwUACgkQmnpgrYe6r62RbACfaOXlhOG04WfHsyAZ/a9RoaXP
YmkAn1jAmN3wTPR3w56c17lOhaIGJ11i
=gWXj
-----END PGP SIGNATURE-----

Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: actors and uncaught exceptions
This probably isn't much help to you, but I've been working on refactoring actors.  The version I have dies when an exception is thrown and not handled, but it enters a "UnhandledThrowable" state where you can retrieve the throwable that caused the actor to die.  Also, terminated actors throw exceptions when you try to send them messages.
The code is here:http://bitbucket.org/eengbrec/scala-enhancements/src/2502a5041010/
I wrote about it here if you'd like more information: http://erikengbrecht.blogspot.com/2009/01/refactoring-scala-actors.html


On Mon, Jan 26, 2009 at 7:37 PM, J Robert Ray <jrobertray [at] gmail [dot] com> wrote:
Given this sample code:

val a = actor {
 loop {
   react {
     case "die" => throw new RuntimeException
     case x => println(x)
   }
 }
}

After executing

a ! "die"

"a" becomes a lifeless actor. I can send messages to it, and see its
mailboxSize increase, but it no longer processes messages.
Tangentially, I see that I can "a.start" to bring it back to life, but
I don't see a way to ask it if it is alive.

I find myself adding try {} blocks to all my actor code within react
to log uncaught exceptions and prevent the loop from unraveling.

My question to the list is if this behavior is part of the design of
the actor library, and wouldn't it be worthwhile for the actor library
to catch these uncaught exceptions to prevent these zombie actor
conditions.

I have begun using java Executors in my application as well as actors,
and I noticed that uncaught exceptions do not disable the Executor.



--
http://erikengbrecht.blogspot.com/
J Robert Ray
Joined: 2008-12-18,
User offline. Last seen 3 years 16 weeks ago.
Re: actors and uncaught exceptions

On Mon, Jan 26, 2009 at 5:20 PM, Erik Engbrecht
wrote:
> This probably isn't much help to you, but I've been working on refactoring
> actors. The version I have dies when an exception is thrown and not
> handled, but it enters a "UnhandledThrowable" state where you can retrieve
> the throwable that caused the actor to die. Also, terminated actors throw
> exceptions when you try to send them messages.
> The code is here:
> http://bitbucket.org/eengbrec/scala-enhancements/src/2502a5041010/

Hi Erik,

interesting work, thanks for your post.

I think you may have a bug on line 1628 of Actors.scala:

- rs.detachAndWaitFor(f, msec)
+ rs.detachAndWaitFor(pf, msec)

Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: actors and uncaught exceptions
Good eye......and that just re-emphasizes the need for more test cases...
Although I think the pf there is actually an artifact of an early attempt to make loop/loopWhile work and no longer necessary...in fact I think I might be able to get rid of the ReactionComplete signal altogether even though it is currently used....hmmm.....

On Mon, Jan 26, 2009 at 9:28 PM, J Robert Ray <jrobertray [at] gmail [dot] com> wrote:
On Mon, Jan 26, 2009 at 5:20 PM, Erik Engbrecht
<erik [dot] engbrecht [at] gmail [dot] com> wrote:
> This probably isn't much help to you, but I've been working on refactoring
> actors.  The version I have dies when an exception is thrown and not
> handled, but it enters a "UnhandledThrowable" state where you can retrieve
> the throwable that caused the actor to die.  Also, terminated actors throw
> exceptions when you try to send them messages.
> The code is here:
> http://bitbucket.org/eengbrec/scala-enhancements/src/2502a5041010/

Hi Erik,

interesting work, thanks for your post.

I think you may have a bug on line 1628 of Actors.scala:

- rs.detachAndWaitFor(f, msec)
+ rs.detachAndWaitFor(pf, msec)



--
http://erikengbrecht.blogspot.com/
robey
Joined: 2008-12-24,
User offline. Last seen 1 year 21 weeks ago.
Re: actors and uncaught exceptions
On 26 Jan 2009, at 17:20, Erik Engbrecht wrote:
This probably isn't much help to you, but I've been working on refactoring actors.  The version I have dies when an exception is thrown and not handled, but it enters a "UnhandledThrowable" state where you can retrieve the throwable that caused the actor to die.  Also, terminated actors throw exceptions when you try to send them messages.
The code is here:http://bitbucket.org/eengbrec/scala-enhancements/src/2502a5041010/
I wrote about it here if you'd like more information: http://erikengbrecht.blogspot.com/2009/01/refactoring-scala-actors.html

This is very cool.
My instinct is that this library should be pulled into its own (non-scala.*) package where we can play with it, and if it fulfills its promise, we should consider swapping it in to the scala distribution in a later release. (Putting it in its own package also makes it easier to try out, without having to rebuild the whole scala distro.)
I'm very interested in trying this out in kestrel and smile.
robey

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland