【问题标题】:Why isn't my actor stopped on exception in akka.net with F#为什么我的演员在使用 F# 的 akka.net 中没有因异常而停止
【发布时间】: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 |&gt; ignore 会抛出,() 不会。不过,在那里使用failwithraise 可能会更好。
  • @GuyCoder,我确实知道相当多的 F#。我只是在几分钟内设置了一个小样本。出于好奇,你想到了什么错误。
  • @TeaDrivenDev, 1/0 只是我强迫和错误。当然其他两个选项更好:)
  • 我只是快速看了一下代码,看到了1/0 |&gt; ignore。每当我看到|&gt; ignore 时,我都会专注于它。如果它与具有副作用的 C# 相关,那么它更有可能是正确的,但如果它与纯 F# 相关,那么我真的仔细看看。看到|&gt; ignore,然后识别出1/0,这是另一个危险信号。这段代码中1\0 |&gt; ignore 的明显替换是()。单元类型() 是 F# 的基本部分,不使用它是一个很大的危险信号。

标签: f# akka.net


【解决方案1】:
  1. 您的createChild 函数不会将actor 创建为监视器的子级。这是由于您已将 actor 系统传递给 spawnOpt 函数这一事实造成的 - 这意味着,生成的 actor 将是顶级的(直接存在于 actor 系统内核下)。您需要将其更改为 spawnOpt parent 才能将其创建为父母的孩子。
  2. 监督策略选项意味着,拥有它的演员会将其应用于其孩子。因此,您需要为监视器设置它,而不是为孩子设置。

【讨论】:

  • 谢谢。回到电脑前我会试试的。将系统发送给孩子只是我复制了错误版本的代码,我已经更新了代码。当然,策略是针对监视器的,因为所有的孩子都应该遵循相同的规则。我应该意识到自己,但可能有点累了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 2014-09-30
相关资源
最近更新 更多