question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

An actor doesn't stop after return Stop effect

See original GitHub issue
open Akka.FSharp
open Akka.Actor

let actorSystem = System.create "NotificationWorker" (Configuration.defaultConfig())

let pnm3 =
    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 ())
                
                
pnm3.Tell("stop", ActorRefs.Nobody)
pnm3.Tell("", ActorRefs.Nobody)

I would expect after telling “stop”, the actor would be stopped, but it still accepts messages.

> 
stop
123
val it : unit = ()

> 
123
val it : unit = ()

The second 123 should not print, should it?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
Horusiathcommented, Dec 15, 2020

@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.

2reactions
Horusiathcommented, Dec 28, 2020

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Solved: My actor does not seem to stop - NI Community
Typically when an actor doesn't stop it's because a helper loop is stuck doing something else or isn't receiving a Stop command like...
Read more >
Actor lifecycle - Documentation - Akka
A child actor can be forced to stop after it finishes processing its current message by using the stop stop method of the...
Read more >
Function does not stop executing after return statement
This function is recursive, so it will call itself (and disregard the return value) though.
Read more >
What would happen if a TV star refused to keep acting on ...
The Office had Micheal Scott, Kelly Kapur, and Ryan leave before the end for various reasons. Kelly just disappeared at the end of...
Read more >
What happens if an actor wants to stop playing in a ...
Most actors will wait until at or near the end of their contract to announce that they are no longer interested in returning....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found