为什么我的演员在akka.net中使用F#

时间:2016-02-28 22:01:48

标签: f# akka.net

我正在玩akka.net并试图理解监督。我以为我得到了它,但它并没有像我期望的那样工作。

我尝试使用监视器和子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

1 个答案:

答案 0 :(得分:5)

  1. 您的createChild函数不会将actor设置为监视器的子级。这是因为你已经将actor系统传递给了spawnOpt函数 - 这意味着,生成的actor将是顶级的(直接生活在actor系统内核下)。您需要将其更改为spawnOpt parent才能将其创建为父母的孩子。
  2. 监督策略选项意味着拥有它的演员将其应用于其子女。因此,您需要为显示器而不是孩子设置它。