Skip to content

Instantly share code, notes, and snippets.

@kleidemos
Created April 24, 2018 07:31
Show Gist options
  • Save kleidemos/85f65850d98dbd48e4c3386413506245 to your computer and use it in GitHub Desktop.
Save kleidemos/85f65850d98dbd48e4c3386413506245 to your computer and use it in GitHub Desktop.

Неожидаемое поведение actorOf2

Мне необходимо было создать актор (аля таймер), который установит задачу в планировщике перед запуском (или при). Сначала использовал 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 должны работать одинакого.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment