Closed ingted closed 3 years ago
According to the wiki,
Stop will cause current actor to immediately stop. It will send Terminated message to all monitoring actors. All messages waiting in actor mailbox or stash will be lost.
PS. What's the difference between
Akkling.Spawn.spawn actorSystem "procs-node-mon3" (
Akkling.Props.props <|
fun (mb:Akkling.Actors.Actor<string>) ->
Akkling.ComputationExpressions.actor {
let! msg = mb.Receive ()
if msg = "stop" then
printfn "stop"
return Akkling.Actors.Stop
printfn "123"
})
and
Akkling.Spawn.spawn actorSystem "procs-node-mon3" (
Akkling.Props.props <|
fun (mb:Akkling.Actors.Actor<string>) ->
let rec loop0 () = Akkling.ComputationExpressions.actor {
let! msg = mb.Receive ()
if msg = "stop" then
printfn "stop"
return Akkling.Actors.Stop
printfn "123"
}
loop0 ())
or
Akkling.Spawn.spawn actorSystem "procs-node-mon3" (
Akkling.Props.props <|
fun (mb:Akkling.Actors.Actor<string>) ->
let rec loop0 () = Akkling.ComputationExpressions.actor {
let! msg = mb.Receive ()
if msg = "stop" then
printfn "stop"
return Akkling.Actors.Stop
printfn "123"
return! loop0 ()
}
loop0 ())
All of them could tell again and again...?!
But for Akka.FSharp
let pnm =
spawn actorSystem "procs-node-mon" <|
fun (mb:Actor<string>) ->
let rec loop0 () = actor {
let! _ = mb.Receive ()
printfn "123"
return! loop0 ()
}
loop0 ()
could tell again and agin (every tell would print 123) but
let pnm =
spawn actorSystem "procs-node-mon" <|
fun (mb:Actor<string>) ->
let rec loop0 () = actor {
let! _ = mb.Receive ()
printfn "123"
}
loop0 ()
could only tell once (only one 123 would be printed)
For the first question, I found that
Akkling.Spawn.spawn actorSystem ("procs-node-mon3" + System.Guid.NewGuid().ToString()) (
Akkling.Props.props <|
fun (mb:Akkling.Actors.Actor<string>) ->
let loop0 () = Akkling.ComputationExpressions.actor {
let! msg = mb.Receive ()
printfn "s: %s" msg
if msg = "stop" then
printfn "stop"
//return Akkling.Actors.ActorEffect.Stop
return Akkling.Actors.Stop
//else
printfn "123"
}
loop0 ())
This would make stop unable to work
Akkling.Spawn.spawn actorSystem ("procs-node-mon3" + System.Guid.NewGuid().ToString()) (
Akkling.Props.props <|
fun (mb:Akkling.Actors.Actor<string>) ->
let loop0 () = Akkling.ComputationExpressions.actor {
let! msg = mb.Receive ()
printfn "s: %s" msg
if msg = "stop" then
printfn "stop"
//return Akkling.Actors.ActorEffect.Stop
return Akkling.Actors.Stop
else
printfn "123"
}
loop0 ())
This make stop works...
Seems like expressions following "return" offset the termination message of ActorEffect.Stop
@ingted When comparing Akka.FSharp and Akkling, your computation expressions are not equivalent:
// Akka.FSharp
let pnm =
spawn actorSystem "procs-node-mon" <| fun (mb:Actor<string>) ->
let rec loop0 () = actor {
let! _ = mb.Receive ()
printfn "123" }
loop0 ()
Here, there's no loop, it's just catching a message and finishing (no tail recursion occurs).
// Akkling
spawn actorSystem ("procs-node-mon3" + System.Guid.NewGuid().ToString()) (props <| fun (mb:Actor<string>) ->
let loop0 () = actor {
let! msg = mb.Receive ()
printfn "s: %s" msg
if msg = "stop" then
printfn "stop"
return Stop
//else
printfn "123" }
loop0 ())
Here, since else
is commented out, it means, that if
is not expression but the statement - which means that it doesn't return any value. And since F# doesn't have early returns, it means that Stop effect will be implicitly ignored. Why return
is even allowed in this scope, I have no idea, looks like the issue with F# compiler.
Hi @Horusiath,
Thanks for the answers! (I learned it!)
The return! question is still not answered, would you mind talk a little more?
Akkling.Spawn.spawn actorSystem "procs-node-mon3" (
Akkling.Props.props <|
fun (mb:Akkling.Actors.Actor<string>) ->
let rec loop0 () = Akkling.ComputationExpressions.actor {
let! msg = mb.Receive ()
printfn "123"
return! loop0 ()
}
loop0 ())
Akkling.Spawn.spawn actorSystem "procs-node-mon3" (
Akkling.Props.props <|
fun (mb:Akkling.Actors.Actor<string>) ->
let rec loop0 () = Akkling.ComputationExpressions.actor {
let! msg = mb.Receive ()
printfn "123"
//return! loop0 ()
}
loop0 ())
Both these two could tell again and again(always print)... (even the return! commented)
. . . . . .
========================================================
spawn actorSystem "procs-node-mon" <| fun (mb:Actor<string>) ->
let rec loop0 () = actor {
let! _ = mb.Receive ()
printfn "123" }
loop0 ()
And with Akka.FSharp spawn, without return! loop0(), it could only tell once (the tell after the first one will not print)
If I remember correctly actor {..}
computation expression in Akka.FSharp either has not Zero
member defined, so it must always return something at some point, or uses Zero
as default returned value, in which case loop will just stop executing.
Unlike Akka.FSharp, Akkling operates on effects as return types, and Akkling's actor
computation expression defines Zero
member as ignored effect - meaning, nothing will change and the last loop roll will be used for the next received message.
Totally understood!! Thank you!
I would expect after telling "stop", the actor would be stopped, but it still accepts messages.
The second 123 should not print, should it?