Horusiath / Akkling

Experimental F# typed API for Akka.NET
Apache License 2.0
225 stars 44 forks source link

SupervisionStrategy is ignored when set on a routee #74

Open object opened 6 years ago

object commented 6 years ago

I noticed that Akkling behaves differently comparing to Akka.FSharp API when it comes to specifying supervision strategy for routers.

Let's say I want to set the following strategy to manage exceptions on router children:

let routeeStrategy () = Strategy.OneForOne((fun ex -> Console.WriteLine("Invoking routee strategy") Console.WriteLine("Restarting actor") Directive.Restart)

So when creating a router I pass this strategy: spawn mailbox.UntypedContext actorId { props workerActor with Router = Some routerConfig; SupervisionStrategy = Some <| routeeStrategy() } |> ignore

I also set a strategy on the higher level actor (router supervisor):

let routerStrategy () = Strategy.OneForOne(fun ex -> Console.WriteLine("Invoking router strategy") Console.WriteLine("Resuming actor") Directive.Resume)

and create a supervisor: let supervisor = spawn system "runner" <| { props supervisingActor with SupervisionStrategy = Some <| routerStrategy() }

What happens is that the first (routee) strategy is never applied: whenever exception occurs at a routee level, the routerStrategy is applied and the actor is always resumed.

But if I set routeeStrategy when creating a supervisor, then the router itself will be restarted (with all routees). And I only want to restart the single child.

So I am bit lost right now: how do I set two different strategies for the router and its children. Am I overlooking something?

object commented 6 years ago

To summarize in short, it looks like in the statement

{ props workerActor with Router = Some routerConfig; SupervisionStrategy = Some <| routeeStrategy() }

the SupervisionStrategy property is never used when the Router is not None.

object commented 6 years ago

... and it works if I specify SupervisionStrategy like this:

let routerConfig = FromConfig.Instance.WithSupervisorStrategy(routeeStrategy()) :> RouterConfig

Then the question: shouldn't it also work if SupervisionStrategy is set like in the example above? Otherwise it's just ignored.

Horusiath commented 6 years ago

Is it the case only for routers or for all kinds of actors?

object commented 6 years ago

No this happens only with routers. Since I have now both working and not working scenarios I can look more into this and hopefully come with a PR.

Horusiath commented 6 years ago

I've added a test that confirms the issue. However it looks like the supervisor strategy is correctly attached to props, it just doesn't get triggered for some reason.

object commented 6 years ago

That's weird. Because it gets triggered for the original F# API.