Managing actor's lifecycle - Horusiath/Akkling GitHub Wiki

Akkling provides a way to directly hookup to Akka.NET actor lifecycle through using predefined events API:

  • PreStart event is fired, once actor is created due to spawn or restart. You may handle it to initialize an actor if necessary.
  • PostStop event is fired, once actor has been stopped due to termination or restart. It's a good place to handle i.e. any disposable resources.
  • PreRestart of cause : exn * message : obj event is fired specifically before actor incarnation is killed due to restart. It also contains message and exact exception, that caused a restart.
  • PostRestart of cause : exn event is fired on new actor incarnation, but only if it was instantiated because of restart triggered by exception in provided parameter.

Example:

let ref = spawnAnonymous system (props <| fun ctx ->
    let resource = initDisposableResource()
    let rec loop () = actor {
        let! msg = ctx.Receive ()
        match msg with
        | LifecycleEvent e -> 
            match e with
            | PostStop ->
                resource.Dispose()        
                return! loop ()
            | _ -> return Unhandled
        | other -> ...
    }
    loop ())

See more examples here.

Monitoring actors

Actors may be used to monitor lifetime of other actors. This is done by monitor/demonitor functions:

  • monitor (watcher : #ICanWatch) (subject : IActorRef) : IActorRef - starts monitoring a referred actor.
  • demonitor (watcher : #ICanWatch) (subject : IActorRef) : IActorRef - stops monitoring of the previously monitored actor. Monitored actors will automatically send a Terminated message to their watchers when they die.

In this case, when actor will die permanently, it will send Terminated message to all of it's watchers. Example:

let watcher = spawnAnonymous client (props <| fun context ->    
    monitor context actorRef |> ignore
    let rec loop() = actor {
        let! msg = context.Receive()
        match msg with 
        | Terminated(ref, existenceConfirmed, addressTerminated) -> return! loop()
        | _ -> return Unhandled        
    }
    loop ())