"The Actor's API is available in the 'self' member variable ... Here you also find fields like ... trapExit"
"Links an other actor to this actor. Links are unidirectional and means that a the linking actor will receive a notification if the linked actor has crashed.If the 'trapExit' member field of the 'faultHandler' has been set to at contain at least one exception class then it will 'trap' these exceptions and automatically restart the linked actors according to the restart strategy defined by the 'faultHandler'."
class Worker extends Actor {protected def receive = {case s : Symbol => sys.error("AAIIIE! " + s + " from actor " + System.identityHashCode(this))case p => println(p + " from " + System.identityHashCode(this))}}class Supervisor extends Actor {self.faultHandler = akka.config.Supervision.OneForOneStrategy(List(classOf[java.io.IOException]), 5, 1000)protected def receive = {case p => println("Super " + p) ;}}import Actor._val s = actorOf[Supervisor]s.start()val w = actorOf(new Worker)w.start()s link w //I'll swap thesew ! "Hello"w ! 'foow ! 3.4
Hello from 381531395[ERROR] [22/06/11 15:59] [akka:event-driven:dispatcher:global-1] [LocalActorRef] 'foojava.lang.RuntimeException: AAIIIE! 'foo from actor 381531395at scala.sys.package$.error(package.scala:27)
Hello from 3815313953.4 from 381531395[ERROR] [22/06/11 16:00] [akka:event-driven:dispatcher:global-1] [LocalActorRef] 'foojava.lang.RuntimeException: AAIIIE! 'foo from actor 381531395at scala.sys.package$.error(package.scala:27)
Hello from 17297479903.4 from 591786211[ERROR] [22/06/11 16:02] [akka:event-driven:dispatcher:global-1] [LocalActorRef] 'foojava.lang.RuntimeException: AAIIIE! 'foo from actor 1729747990at scala.sys.package$.error(package.scala:27)
> This prints:
>
> Hello from 381531395
> [ERROR] [22/06/11 15:59] [akka:event-driven:dispatcher:global-1] [LocalActorRef] 'foo
> java.lang.RuntimeException: AAIIIE! 'foo from actor 381531395
> at scala.sys.package$.error(package.scala:27)
>
> So it doesn't look like any message has been passed to the supervisor, although it's clear that the exception has killed the worker.
A message is sent to the supervisor but it is handled automatically.
From the docs:
"If a linked Actor is failing and throws an exception then an “Exit(deadActor, cause)’ message will be sent to the supervisor (however you should never try to catch this message in your own message handler, it is managed by the runtime)."
http://akka.io/docs/akka/1.1.2/scala/fault-tolerance.html#the-supervising-actor-s-side-of-things
The receiving of this message is here:
https://github.com/jboner/akka/blob/v1.1.2/akka-actor/src/main/scala/akka/actor/Actor.scala#L484
And the logic of what to do is here:
https://github.com/jboner/akka/blob/v1.1.2/akka-actor/src/main/scala/akka/actor/ActorRef.scala#L880
Since the exception is not covered and there is no supervisor (of the supervisor) to pass up to, the actor is simply stopped.
> However, when I swap "s link w" to "w link s" I get this:
>
> Hello from 381531395
> 3.4 from 381531395
> [ERROR] [22/06/11 16:00] [akka:event-driven:dispatcher:global-1] [LocalActorRef] 'foo
> java.lang.RuntimeException: AAIIIE! 'foo from actor 381531395
> at scala.sys.package$.error(package.scala:27)
>
> So it looks like in this case, the worker has been restarted (although the supervisor has not received anything, again) - but it is the same underlying "Worker" instance.
In this case the worker doesn't have a supervisor so the lifecycle of the actor is considered. The default is permanent and so it simply resumes (the same instance of the actor and the exception is just logged).
See here:
https://github.com/jboner/akka/blob/v1.1.2/akka-actor/src/main/scala/akka/actor/ActorRef.scala#L1035
> My third change was to switch back to "s link w" but specify that I want to restart on any exception:
>
> Hello from 1729747990
> 3.4 from 591786211
> [ERROR] [22/06/11 16:02] [akka:event-driven:dispatcher:global-1] [LocalActorRef] 'foo
> java.lang.RuntimeException: AAIIIE! 'foo from actor 1729747990
>
> at scala.sys.package$.error(package.scala:27)
>
> So in this instance, it seems as though akka has indeed restarted my actor (with a new instance of the Worker)
Yes, this time it's restarted by the supervisor.
>
> Any help here?
> • How can I get *some* callback for an actor exiting with an unexpected exception? (is "postStop" the only mechanism?)
The supervisor hierarchy approach is to have the unexpected exception go to the supervisor's supervisor, and so on up the hierarchy, until it can be handled.
> • Why if I switch round "supervisor link worker" to "worker link supervisor" does the worker not die on throwing an Exception?
It's determined by the lifecycle of the actor in this case.
Hope that helps,
Peter
Thanks Peter - this makes sense. Except for one further question! I
f the "Exit" message callbacks are passed up the supervisor hierarchy
but *I* am not supposed to handle them, I'm still confused about how/
where to put a hook in my program where I would call this method:
def kaboom(msg : Any) = { println("unexpected actor exit " + msg);
sys.exit(-1) }
> It's determined by the lifecycle of the actor in this case.
>
> Hope that helps,
>
> Peter
--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.
Ok that fixed it so that it called the worker's lifecycle messages.
However, it appears that the Supervisor still isn't notified. I
believe that one of the earlier e-mails said that one was not supposed
to capture the Exit message. Is that correct? If so, it would be
nice to have the ability to have additional methods on the supervisor
called:
// this one would be called on the supervisor after the dead actor's
preRestart
def onLinkedActorDeath(deadActor:ActorRef, error:Throwable) : Unit
// this one would be called on the supervisor after the new actor's
postRestart invocation
def onLinkedActorRestart(newActor:ActorRef) : Unit
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
The actor reference you have is still valid on a restarted actor. So in essence, what you're saying, "I need to know which one replaced it" is odd. Nothing "replaces" anything from your perspective.
If you have:
val a = actorOf[SomeActor].start
and that instance dies when it gets a "CommitSuicide" message, then the supervisor restarts it and you're good to go. Like this:
a ! CommitSuicide
a ! DoSomethingNice
The "DoSomethingNice" message is handled just fine. I don't need to, somehow, figure out what the new "a" would be.
In truth, your actor under the covers is recreated, yes, but the actor reference (i.e. "a") is still perfectly fine. That's kinda the beauty of it.
________________________________________
From: akka...@googlegroups.com [akka...@googlegroups.com] On Behalf Of Garry [ga...@dynafocus.com]
Sent: Thursday, June 23, 2011 11:32 AM
To: Akka User List
Subject: [akka-user] Re: Linking actors and trapping exit in akka 1.1.2
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.
---------------------------------------------------------------------
This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful.
Thanks
--
On Thursday, June 23, 2011 at 6:17 PM, Garry wrote:
Would it be like this?
val supervisor = Supervisor(
SupervisorConfig(
AllForOneStrategy(List(classOf[Exception]), 3, 1000),
Supervise(
actorOf(new SomeActor("127.0.0.1")),
Permanent) ::
Supervise(
actorOf[MyActor2],
Permanent) ::
Nil))
If so I didn't realize that the actorOf(...) lazily instantiated the
new actor.
If that is true, I am happy with this scenario, and this discussion
has been a good learning tool for me. I apologize to anyone if I
annoyed you.
Thanks
Garry
How do I specify that? I am new to akka/scala so I may have missed it
somewhere (more likely don't understand it).
Thanks
On Jun 23, 12:03 pm, Derek Wyatt <dwy...@rim.com> wrote:
What you're saying still works. The parameter "new SomeActor("127.0.0.1")" is a factory method. As such, when the actor is recreated, the same factory method will be used. It gets recreated /in exactly the same way as it was created originally/. You don't need a config map.
________________________________________
From: akka...@googlegroups.com [akka...@googlegroups.com] On Behalf Of Garry [ga...@dynafocus.com]
Sent: Thursday, June 23, 2011 11:59 AM
To: Akka User List
Subject: [akka-user] Re: Linking actors and trapping exit in akka 1.1.2
Ok I understand that ActorRef does not change, however it does build a
new SomeActor that extends Actor. The problem is I want to do thisval a = actorOf(new SomeActor("127.0.0.1")).startOR if I could specify parameters to pass to the thing in the fault
handler configuration that get called to the preStart() is all I wantval config = Map("ipAddress", "127.0.0.1")
self.faultHandler =
Supervision.OneForOneStrategy(List(classOf[Exception]), 5, 1000,
config)
Thanks
...
read more »
--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.
> Thanks Peter - this makes sense. Except for one further question! I
>
> f the "Exit" message callbacks are passed up the supervisor hierarchy
> but *I* am not supposed to handle them, I'm still confused about how/
> where to put a hook in my program where I would call this method:
>
> def kaboom(msg : Any) = { println("unexpected actor exit " + msg);
> sys.exit(-1) }
You can use the postStop callback on an actor that shouldn't be stopped - since a supervised actor that can't be "handled" is stopped.
If you don't want your actor to know about this, you can move it up one level to the supervisor. If the supervisor doesn't cover the exception it will pass it up a level, and if the super-supervisor doesn't cover it then it will stop the supervisor.
Here's an example, based on your original example:
import akka.actor._
import akka.config.Supervision.OneForOneStrategy
class Worker extends Actor {
def receive = {
case int: Int => throw new java.io.IOException("Yuk.")
case symbol: Symbol => sys.error("AAIIIE!")
case message => println(message)
}
}
class Supervisor extends Actor {
self.faultHandler = OneForOneStrategy(List(classOf[java.io.IOException]), 5, 1000)
def receive = { case _ => () }
override def postStop = {
println("That was unexpected!"); sys.exit(-1)
}
}
class Top extends Actor {
self.faultHandler = OneForOneStrategy(Nil, 5, 1000)
def receive = { case _ => () }
}
val top = Actor.actorOf[Top].start()
val supervisor = Actor.actorOf[Supervisor].start()
val worker = Actor.actorOf[Worker].start()
top link supervisor
supervisor link worker
worker ! "Hello"
worker ! 123
worker ! 'boom
I think the OP (maybe, maybe not) was sort of asking that with Scala
standard actors one can link actor S to W, and via setting trapExit, S
can become aware of and "explicitly" handle a failure in W. However,
Akka actors seem structured to preclude S from ever learning of W's
failure and gaining explicit handling of the situation.
I hit this when doing a minimal quick and dirty conversion from Scala
actors to Akka where in several cases I was handling a trapExit
explicitly. And still want to.
Accept for the moment that there are times when this is desirable,
though granted in the majority of cases having the restart(s) done
implicitly by the runtime is superior, then this appears to be "a"
way. I have no clue if it is "the" way.
import akka.actor.{Actor, ActorRef}
--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.
Second, regarding the explicit supervisor fault-handling. It is something that we have so far decided to not support. I believe that the essence of the let-it-crash model is to declaratively configure fault handling then delegate the management and enforcement of it to the runtime.
However, I understand that some people want more control.
We have recently discussed richer way of interacting with the fault-management. It is implemented now according to this ticket: https://www.assembla.com/spaces/akka/tickets/955-allow-passing-of-actor-state-to-the-new-instance-on-restart
Take a look to see if it solves your problem or if we need to think of another solution.
Only using Akka actors for something like 24 hrs so I hesitate...On Mon, Jul 4, 2011 at 4:03 AM, Jonas Bonér <jo...@jonasboner.com> wrote:
....Second, regarding the explicit supervisor fault-handling. It is something that we have so far decided to not support. I believe that the essence of the let-it-crash model is to declaratively configure fault handling then delegate the management and enforcement of it to the runtime.Understand completely.However, I understand that some people want more control.We have recently discussed richer way of interacting with the fault-management. It is implemented now according to this ticket: https://www.assembla.com/spaces/akka/tickets/955-allow-passing-of-actor-state-to-the-new-instance-on-restartThe faulted actor may take explicit control in the minting of its replacement. Slightly dangerous, but with great power comes great responsibility. As the general approach remains to use the initial actor factory method, seems fine.Take a look to see if it solves your problem or if we need to think of another solution.There were 2 specific points.1) Anyone attempting a naive quick and dirty port from current Scala Actors to Akka will hit the explicit Exit (_,_) issue. Definitely an FAQ in the "Porting Scala to Akka Actors Guide". With the bug fixed, then declaring the appropriate restart strategy policy and handling the MaximumNumberOfRetriesWithTimeRange offers similar semantics for "rapid" porting.2) The open question was not necessarily the degree of explicit control granted in a faulted actors reincarnation, it is the degree of explicit awareness of the supervising actor that a supervised worker has faulted and been successfully reincarnated. Given that a reincarnated actor is both aware of its rebirth and the cause of its predecessors demise it can always inform any interested party explicitly of its resurrection. I don't know if say a standardized Reborn message should be issued to the supervising actor by the declarative restart system. Currently the supervising actor's behavior is autonomic and performed in blissful ignorance.
On Jul 5, 2011, at 4:38, Ray Racine <ray.r...@gmail.com> wrote:Only using Akka actors for something like 24 hrs so I hesitate...On Mon, Jul 4, 2011 at 4:03 AM, Jonas Bonér <jo...@jonasboner.com> wrote:
....Second, regarding the explicit supervisor fault-handling. It is something that we have so far decided to not support. I believe that the essence of the let-it-crash model is to declaratively configure fault handling then delegate the management and enforcement of it to the runtime.Understand completely.However, I understand that some people want more control.We have recently discussed richer way of interacting with the fault-management. It is implemented now according to this ticket: https://www.assembla.com/spaces/akka/tickets/955-allow-passing-of-actor-state-to-the-new-instance-on-restartThe faulted actor may take explicit control in the minting of its replacement. Slightly dangerous, but with great power comes great responsibility. As the general approach remains to use the initial actor factory method, seems fine.Take a look to see if it solves your problem or if we need to think of another solution.There were 2 specific points.1) Anyone attempting a naive quick and dirty port from current Scala Actors to Akka will hit the explicit Exit (_,_) issue. Definitely an FAQ in the "Porting Scala to Akka Actors Guide". With the bug fixed, then declaring the appropriate restart strategy policy and handling the MaximumNumberOfRetriesWithTimeRange offers similar semantics for "rapid" porting.2) The open question was not necessarily the degree of explicit control granted in a faulted actors reincarnation, it is the degree of explicit awareness of the supervising actor that a supervised worker has faulted and been successfully reincarnated. Given that a reincarnated actor is both aware of its rebirth and the cause of its predecessors demise it can always inform any interested party explicitly of its resurrection. I don't know if say a standardized Reborn message should be issued to the supervising actor by the declarative restart system. Currently the supervising actor's behavior is autonomic and performed in blissful ignorance.This is probably where Viktor’s idea of lifecycle observers comes into play: while the automatisms stay in place for the actual restarting, anyone may register himself to receive Started/Restarted/Stopped messages. Maybe as an “optimization” the
supervisor could get the Restarted directly after processing the Exit without queuing again.
On 5 July 2011 07:18, Roland Kuhn <goo...@rkuhn.info> wrote:On Jul 5, 2011, at 4:38, Ray Racine <ray.r...@gmail.com> wrote:Only using Akka actors for something like 24 hrs so I hesitate...On Mon, Jul 4, 2011 at 4:03 AM, Jonas Bonér <jo...@jonasboner.com> wrote:
....Second, regarding the explicit supervisor fault-handling. It is something that we have so far decided to not support. I believe that the essence of the let-it-crash model is to declaratively configure fault handling then delegate the management and enforcement of it to the runtime.Understand completely.However, I understand that some people want more control.We have recently discussed richer way of interacting with the fault-management. It is implemented now according to this ticket: https://www.assembla.com/spaces/akka/tickets/955-allow-passing-of-actor-state-to-the-new-instance-on-restartThe faulted actor may take explicit control in the minting of its replacement. Slightly dangerous, but with great power comes great responsibility. As the general approach remains to use the initial actor factory method, seems fine.Take a look to see if it solves your problem or if we need to think of another solution.There were 2 specific points.1) Anyone attempting a naive quick and dirty port from current Scala Actors to Akka will hit the explicit Exit (_,_) issue. Definitely an FAQ in the "Porting Scala to Akka Actors Guide". With the bug fixed, then declaring the appropriate restart strategy policy and handling the MaximumNumberOfRetriesWithTimeRange offers similar semantics for "rapid" porting.2) The open question was not necessarily the degree of explicit control granted in a faulted actors reincarnation, it is the degree of explicit awareness of the supervising actor that a supervised worker has faulted and been successfully reincarnated. Given that a reincarnated actor is both aware of its rebirth and the cause of its predecessors demise it can always inform any interested party explicitly of its resurrection. I don't know if say a standardized Reborn message should be issued to the supervising actor by the declarative restart system. Currently the supervising actor's behavior is autonomic and performed in blissful ignorance.This is probably where Viktor’s idea of lifecycle observers comes into play: while the automatisms stay in place for the actual restarting, anyone may register himself to receive Started/Restarted/Stopped messages. Maybe as an “optimization” theYeah.supervisor could get the Restarted directly after processing the Exit without queuing again.Sounds good.
--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/ZH59Lg1ipsAJ.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.