【发布时间】:2016-02-28 22:01:47
【问题描述】:
我正在玩 akka.net 并试图了解监督。我以为我明白了,但它并没有像我期望的那样工作。
我尝试获取一个带有监视器和子actor的小样本,监视器应该在子actor出现异常时重新启动子actor。似乎孩子正在重新启动,但我不明白为什么,因为代码似乎没有执行我的SupervisorStrategy。我将策略更改为返回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
【问题讨论】:
-
如果你不介意我问你知道多少/很少的 F#?代码中有非常基本的错误。
-
1/0 |> ignore会抛出,()不会。不过,在那里使用failwith或raise可能会更好。 -
@GuyCoder,我确实知道相当多的 F#。我只是在几分钟内设置了一个小样本。出于好奇,你想到了什么错误。
-
@TeaDrivenDev,
1/0只是我强迫和错误。当然其他两个选项更好:) -
我只是快速看了一下代码,看到了
1/0 |> ignore。每当我看到|> ignore时,我都会专注于它。如果它与具有副作用的 C# 相关,那么它更有可能是正确的,但如果它与纯 F# 相关,那么我真的仔细看看。看到|> ignore,然后识别出1/0,这是另一个危险信号。这段代码中1\0 |> ignore的明显替换是()。单元类型()是 F# 的基本部分,不使用它是一个很大的危险信号。