1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
//! Manage the lifecycle of an actix actor with its address.
//!
//! If you want to stop/terminate an actor, you call [`ActorContext::stop`](actix::ActorContext::stop) or
//! [`ActorContext::terminate`](actix::ActorContext::terminate) within its execution context.
//!
//! However, sometimes you have access to its address only. This crate adds a bunch of methods to the address so that
//! you may [stop](AddrSignalExt::stop) or [terminate](AddrSignalExt::terminate) the actor outside its running context.
//!
//! *Minimum supported rust version: 1.50.0*
//!
//! # Example
//!
//! ```
//! use actix::{Actor, Context};
//! use actix_signal::{AddrSignalExt, SignalHandler};
//! # use actix_signal_derive::SignalHandler;
//!
//! #[derive(SignalHandler)]
//! struct MyActor;
//!
//! impl Actor for MyActor {
//! type Context = Context<Self>;
//! }
//!
//! # #[actix_rt::test]
//! # async fn test() {
//! let actor = MyActor;
//! let addr = actor.start();
//!
//! addr.stop(); // Stop the actor
//! addr.terminate(); // Terminate the actor
//! # }
//! ```
//!
//! You may also implement handlers by hand if you don't want to use the proc macro or need custom behaviors.
//!
//! ```
//! use actix::{Actor, Context, Handler, ActorContext};
//! use actix_signal::{AddrSignalExt, StopSignal, TerminateSignal};
//!
//! struct MyActor;
//!
//! impl Actor for MyActor {
//! type Context = Context<Self>;
//! }
//!
//! impl Handler<StopSignal> for MyActor {
//! type Result = ();
//!
//! fn handle(&mut self, _msg: StopSignal, ctx: &mut Self::Context) -> Self::Result {
//! ctx.stop();
//! }
//! }
//!
//! impl Handler<TerminateSignal> for MyActor {
//! type Result = ();
//!
//! fn handle(&mut self, _msg: TerminateSignal, ctx: &mut Self::Context) -> Self::Result {
//! ctx.terminate();
//! }
//! }
//!
//! # #[actix_rt::test]
//! # async fn test() {
//! let actor = MyActor;
//! let addr = actor.start();
//!
//! addr.stop(); // Stop the actor
//! addr.terminate(); // Terminate the actor
//! # }
//! ```
//!
//! # Feature flags
//!
//! `derive` - Provide `#[derive(SignalHandler)]` proc-macro.
#[cfg(feature = "actix-signal-derive")]
#[macro_use]
extern crate actix_signal_derive;
use actix::dev::ToEnvelope;
use actix::{Actor, Handler};
#[cfg(feature = "actix-signal-derive")]
pub use actix_signal_derive::*;
pub use addr::*;
pub use signals::*;
mod addr;
mod private;
pub mod signals;
/// Actors that are able to handle signals.
///
/// This trait is sealed and automatically implemented for actors implementing `Handler`s for [`signals`](signals).
/// See top-level document for instructions on implementing these traits.
pub trait SignalHandler: Handler<StopSignal> + Handler<TerminateSignal> + private::Sealed {}
impl<T> SignalHandler for T where T: Handler<StopSignal> + Handler<TerminateSignal> {}
/// Execution contexts that are able to handle signals.
///
/// This trait is sealed and automatically implemented for contexts of which the associated actors implement `Handler`s
/// for [`signals`](signals).
/// See top-level document for instructions on implementing these traits.
pub trait ToSignalEnvelope<A>:
ToEnvelope<A, StopSignal> + ToEnvelope<A, TerminateSignal> + private::Sealed
where
A: Actor + SignalHandler,
<A as Actor>::Context: ToSignalEnvelope<A>,
{
}
impl<A, T> ToSignalEnvelope<A> for T
where
A: Actor<Context = T> + SignalHandler,
T: ToEnvelope<A, StopSignal> + ToEnvelope<A, TerminateSignal>,
<A as Actor>::Context: ToEnvelope<A, StopSignal> + ToEnvelope<A, TerminateSignal>,
{
}