为什么我的演员没有在 akka.net 中使用 F# 异常停止
Why isn't my actor stopped on exception in akka.net with F#
我正在研究 akka.net 并试图了解监督。我以为我明白了,但它没有像我期望的那样工作。
我尝试使用一个监视器和一个 child actor 获取一个小样本,其中监视器应该在 child 中出现异常时重新启动 child。 child 似乎正在重新启动,但我不明白为什么,因为代码似乎没有执行我的 SupervisorStrategy
。我将策略更改为 return Directive.Stop
以检查我是否可以阻止演员,但这也不起作用。所以现在看来我有一个不可阻挡的演员,这是一件好事,只要我不想杀死它:)。 运行 样本的代码如下:
open Akka
open Akka.Actor
open Akka.Tools
open Akka.FSharp
open System
type MonitorMessage =
| Create
type ChildMessage =
| Ping
| Kill
let test() =
let systemName = "my-system"
let system = System.create systemName (Configuration.load())
let handleChildMessage = function
| Ping ->
printfn "Received %A" Ping
printfn "Pong: %A" (DateTime.Now.Ticks)
| Kill ->
1/0 |> ignore
let createChild parent id =
spawnOpt parent (id.ToString()) (actorOf handleChildMessage)
[ SpawnOption.SupervisorStrategy (Strategy.OneForOne (fun error ->
match error with
| _ ->
printfn "%A" error
Directive.Stop
)) ]
let handleMonitorMessage (actor:Actor<MonitorMessage>) message =
match message with
| Create ->
let sender = actor.Sender()
sender <! createChild actor (Guid.NewGuid())
let monitor = spawn system "monitor" (actorOf2 handleMonitorMessage)
let child = monitor <? Create |> Async.RunSynchronously
child <! Ping
child <! Kill
child <! Ping
test()
Console.ReadLine() |> ignore
- 您的
createChild
函数不会创建演员作为监视器的 child。这是因为您已将 actor 系统传递给 spawnOpt 函数 - 这意味着,生成的 actor 将是顶级 actor(直接位于 actor 系统内核下)。您需要将其更改为 spawnOpt parent
,以便将其创建为 parent 的 child。
- 监督策略选项意味着,拥有它的参与者会将其应用于其 children。因此你需要为显示器设置它,而不是 children.
我正在研究 akka.net 并试图了解监督。我以为我明白了,但它没有像我期望的那样工作。
我尝试使用一个监视器和一个 child actor 获取一个小样本,其中监视器应该在 child 中出现异常时重新启动 child。 child 似乎正在重新启动,但我不明白为什么,因为代码似乎没有执行我的 SupervisorStrategy
。我将策略更改为 return Directive.Stop
以检查我是否可以阻止演员,但这也不起作用。所以现在看来我有一个不可阻挡的演员,这是一件好事,只要我不想杀死它:)。 运行 样本的代码如下:
open Akka
open Akka.Actor
open Akka.Tools
open Akka.FSharp
open System
type MonitorMessage =
| Create
type ChildMessage =
| Ping
| Kill
let test() =
let systemName = "my-system"
let system = System.create systemName (Configuration.load())
let handleChildMessage = function
| Ping ->
printfn "Received %A" Ping
printfn "Pong: %A" (DateTime.Now.Ticks)
| Kill ->
1/0 |> ignore
let createChild parent id =
spawnOpt parent (id.ToString()) (actorOf handleChildMessage)
[ SpawnOption.SupervisorStrategy (Strategy.OneForOne (fun error ->
match error with
| _ ->
printfn "%A" error
Directive.Stop
)) ]
let handleMonitorMessage (actor:Actor<MonitorMessage>) message =
match message with
| Create ->
let sender = actor.Sender()
sender <! createChild actor (Guid.NewGuid())
let monitor = spawn system "monitor" (actorOf2 handleMonitorMessage)
let child = monitor <? Create |> Async.RunSynchronously
child <! Ping
child <! Kill
child <! Ping
test()
Console.ReadLine() |> ignore
- 您的
createChild
函数不会创建演员作为监视器的 child。这是因为您已将 actor 系统传递给 spawnOpt 函数 - 这意味着,生成的 actor 将是顶级 actor(直接位于 actor 系统内核下)。您需要将其更改为spawnOpt parent
,以便将其创建为 parent 的 child。 - 监督策略选项意味着,拥有它的参与者会将其应用于其 children。因此你需要为显示器设置它,而不是 children.