Module heph::supervisor
source · [−]Expand description
The module with the supervisor and related types.
Supervisor
A supervisor supervises an actor and handles any errors it encounters. A supervisor generally does two things; logging of the error and deciding whether to stop or restart the actor. Its advised to keep a supervisor small and simple.
When encountering an error it usually means someone has to be notified (to fix it), something often done via logging.
Next the supervisor needs to decide if the actor needs to be stopped or
restarted. If the supervisor decides to restart the actor it needs to
provide the argument to create a new actor (used in calling the
NewActor::new
method).
The restarted actor will have the same message inbox as the old (stopped) actor. Note however that if an actor retrieved a message from its inbox, and returned an error when processing it, the new (restarted) actor won’t retrieve that message again (messages aren’t cloned after all).
Restarting or stopping?
Sometimes just restarting an actor is the easiest way to deal with errors.
Starting the actor from a clean slate will often allow it to continue
processing. However this is not possible in all cases, for example when a
new argument can’t be provided. For example the TcpServer
found in the
heph-rt. In those cases the supervisor should still log the error
encountered.
Actors and sync actors
As actors come in two flavours, regular/asynchronous actors and
synchronous actors, thus so do the supervisor traits, Supervisor
and
SyncSupervisor
.
Provided implementations
There are two Supervisor
implementations provided by Heph. First, the
NoSupervisor
can be used when the actor never returns an error (i.e.
Result<(), !>
or no return type) and thus doesn’t need supervision.
Second, the restart_supervisor!
macro, which can be used to easily
create a supervisor implementation that restarts the actor.
Examples
Supervisor that logs the errors of a badly behaving actor and stops it.
#![feature(never_type)]
use heph::actor;
use heph::supervisor::SupervisorStrategy;
use heph_rt::spawn::ActorOptions;
use heph_rt::{self as rt, ThreadLocal, Runtime};
use log::error;
fn main() -> Result<(), rt::Error> {
// Enable logging so we can see the error message.
std_logger::init();
let mut runtime = Runtime::new()?;
runtime.run_on_workers(|mut runtime_ref| -> Result<(), !> {
runtime_ref.spawn_local(supervisor, bad_actor as fn(_) -> _, (), ActorOptions::default());
Ok(())
})?;
runtime.start()
}
/// The error returned by our actor.
struct Error;
/// Supervisor that gets called if the actor returns an error.
fn supervisor(err: Error) -> SupervisorStrategy<()> {
error!("Actor encountered an error!");
SupervisorStrategy::Stop
}
/// Our badly behaving actor.
async fn bad_actor(_: actor::Context<!, ThreadLocal>) -> Result<(), Error> {
Err(Error)
}
Structs
A supervisor implementation for actors that never return an error.
A supervisor implementation that stops the actor and logs the error.
Enums
The strategy to use when handling an error from an actor.
Traits
The supervisor of an actor.
Supervisor for synchronous actors.