Мне необходимо было создать актор (аля таймер), который установит задачу в планировщике перед запуском (или при). Сначала использовал actor {}
, но потом решил переписать на actorOf2
, после чего обнаружил неадеквтаное с моей точки зрения поведение.
actorOf2
не производил вычислений, пока в него не приходило какое-нибудь сообщение (т.к. сообшение должно было присылаться из Scheduler-а, в который никто ничего не поставил, актор вообще не работал). Чередой экспериментов удалось сузить вопсроизводимый случай до:
open Akkling
let system = System.create "my-system" <| Configuration.defaultConfig()
let builder () =
props <| fun context ->
let rec loop () = actor {
let! message = context.Receive()
message |> printfn "Message : %i"
return! loop ()
}
printfn "builder"
// In my case: context.Schedule ...
loop ()
let typedActorOf2 () =
actorOf2 <| fun cotnext ->
let rec loop message =
message |> printfn "Message : %i"
loop |> become
printfn "typed actorOf2"
// In my case: context.Schedule ...
loop
|> props
let untypedActorOf2 () : Props<obj> =
actorOf2 <| fun context ->
let rec loop (message : obj) =
message
|> tryUnbox
|> Option.iter (printfn "Message : %i")
loop |> become
printfn "untyped actorOf2"
// In my case: context.Schedule ...
loop
|> props
Если вызвать следующий код, то можно обнаружить, что "типизированный" actorOf2
отсутствует. // typed actorOf2
builder () |> spawnAnonymous system
typedActorOf2 () |> spawnAnonymous system
untypedActorOf2 () |> spawnAnonymous system
()
>
builder
untyped actorOf2
val it : unit = ()
Но если после создания в актор направить сообщение, то "инициализация" произойдет.
builder () |> spawnAnonymous system <! 1
typedActorOf2 () |> spawnAnonymous system <! 1
untypedActorOf2 () |> spawnAnonymous system |> retype <! 1
()
>
builder
Message : 1
typed actorOf2
Message : 1
untyped actorOf2
Message : 1
val it : unit = ()
actorOf
подобной проблемы не имеет. Обращаю внимание, что в моей задаче мне нужен был context
. И здесь он не используется лишь для того, чтобы подчеркнуть общность задачи.
Подозреваю, что нетипизированный актор работает из-за того, что в него посылается PreStart
.
Я только зарываюсь в akkling (и akka), как и в акторные системы вообще, и не могу сказать, является ли подобное поведение ошибочным. Однако на мой взгляд и typed
, и untyped
должны работать одинакого.