Trait lunatic_twitchax_patch::ap::AbstractProcess
source · pub trait AbstractProcess: Sizedwhere
Self::Serializer: CanSerialize<Self::Arg> + CanSerialize<Result<(), StartupError<Self>>> + CanSerialize<ShutdownMessage<Self::Serializer>> + CanSerialize<()> + CanSerialize<(Process<Result<(), StartupError<Self>>, Self::Serializer>, Tag, Self::Arg)> + CanSerialize<ProtocolCapture<(Process<Result<(), StartupError<Self>>, Self::Serializer>, Tag, Self::Arg)>>,{
type State;
type Serializer;
type Arg;
type Handlers: Handlers<Self>;
type StartupError: Debug;
// Required method
fn init(
config: Config<Self>,
arg: Self::Arg
) -> Result<Self::State, Self::StartupError>;
// Provided methods
fn terminate(_state: Self::State) { ... }
fn handle_link_death(_state: State<'_, Self>, _tag: Tag) { ... }
fn start(arg: Self::Arg) -> Result<ProcessRef<Self>, StartupError<Self>> { ... }
fn start_as<N: ProcessName>(
name: &N,
arg: Self::Arg
) -> Result<ProcessRef<Self>, StartupError<Self>> { ... }
fn link() -> AbstractProcessBuilder<'static, Self> { ... }
fn link_with(tag: Tag) -> AbstractProcessBuilder<'static, Self> { ... }
fn configure(config: &ProcessConfig) -> AbstractProcessBuilder<'_, Self> { ... }
fn on_node(node: u64) -> AbstractProcessBuilder<'static, Self> { ... }
}Expand description
Building block for processes that act as a server of a client-server relation.
An AbstractProcess is like any other process in lunatic, it can hold
state, receive messages and so on. Their main advantage is that they
provide a type-safe interface for dealing with requests.
Startup
AbstractProcesses can be started using the Self::start function, or
Self::start_as for a named process. Calls to these functions will block
until the process is started and the Self::init function finishes. A
custom return error can be specified using the Self::StartupError type.
If the init function panics, the start functions will return a
StartupError::InitPanicked error.
Handlers
Handlers are used to define the types of messages that can be handled by
abstract processes. Handlers are defined using the traits
MessageHandler, RequestHandler and DeferredRequestHandler.
MessageHandler are used to handle asynchronous messages sent to the
abstract process. This means that the sender doesn’t wait for an answer.
The following example shows a Counter abstract process that is able to
handle Increment messages. During the handling of a message the handler
has access to the internal state of the abstract process.
#[derive(serde::Serialize, serde::Deserialize)]
struct Increment;
impl MessageHandler<Increment> for Counter {
fn handle(mut state: State<Self>, _: Increment) {
state.0 += 1;
}
}RequestHandler and DeferredRequestHandler expect a return value and
the requests are made synchronous, this means that the sender waits for a
response.
#[derive(serde::Serialize, serde::Deserialize)]
struct Count;
impl RequestHandler<Count> for Counter {
type Response = u32;
fn handle(state: State<Self>, _: Count) -> Self::Response {
state.0
}
}In case of a DeferredRequestHandler, the response doesn’t need to be
immediate and can be even delegated to a 3rd process.
impl DeferredRequestHandler<Count> for Counter {
type Response = u32;
fn handle(_: State<Self>, _: String, dr: DeferredResponse<Self::Response, Self>) {
dr.send_response(u32);
}
}It is not enough just to define the handlers, they also need to be
associated with the AbstractProcess using the Self::Handlers type:
type Handlers = (Message<Increment>, Request<Count>, DeferredRequest<Count>);Shutdown
An abstract process can be shut down using the ProcessRef::shutdown
call. This function will block, until the Self::terminate function
finishes.
Required Associated Types§
sourcetype Serializer
type Serializer
The serializer used for all messages sent to and responses sent from the abstract process.
sourcetype Arg
type Arg
The argument received by the init function.
This argument is sent from the parent to the child and needs to be
serializable by Self::Serializer.
sourcetype Handlers: Handlers<Self>
type Handlers: Handlers<Self>
Handlers for incoming messages, requests and deferred requests.
They are defined as a tuple and wrapped into Message, Request and
DeferredRequest wrappers.
type Handlers = (Message<Handler1>, Message<Handler2>, Request<Handler3>);Even if there is only one handler, it needs to be defined as a tuple.
type Handlers = (Message<Handler1>,);sourcetype StartupError: Debug
type StartupError: Debug
Errors that can be returned from the init call to the spawner.
Required Methods§
sourcefn init(
config: Config<Self>,
arg: Self::Arg
) -> Result<Self::State, Self::StartupError>
fn init( config: Config<Self>, arg: Self::Arg ) -> Result<Self::State, Self::StartupError>
Entry function of the new process.
This function is executed inside the new process. It will receive the
arguments passed to the start or
start_as function by the parent. And
will return the starting state of the newly spawned process.
The parent will block on the call of start or start_as until this
function finishes. This allows startups to be synchronized.
Provided Methods§
sourcefn handle_link_death(_state: State<'_, Self>, _tag: Tag)
fn handle_link_death(_state: State<'_, Self>, _tag: Tag)
This function will be called if another linked process dies.
sourcefn start(arg: Self::Arg) -> Result<ProcessRef<Self>, StartupError<Self>>
fn start(arg: Self::Arg) -> Result<ProcessRef<Self>, StartupError<Self>>
Starts a new AbstractProcess and returns a reference to it.
This call will block until the init function finishes. If the init
function returns an error, it will be returned as
StartupError::Custom(error). If the init function panics during
execution, it will return StartupError::InitPanicked.
sourcefn start_as<N: ProcessName>(
name: &N,
arg: Self::Arg
) -> Result<ProcessRef<Self>, StartupError<Self>>
fn start_as<N: ProcessName>( name: &N, arg: Self::Arg ) -> Result<ProcessRef<Self>, StartupError<Self>>
Starts the process and registers it under name. If another process is
already registered under the same name, it will return a
Err(StartupError::NameAlreadyRegistered(proc)) with a reference to the
existing process.
This call will block until the init function finishes. If the init
function returns an error, it will be returned as
StartupError::Custom(error). If the init function panics during
execution, it will return StartupError::InitPanicked.
If used in combination with the on_node option, the
name registration will be performed on the local node and not the remote
one.
sourcefn link() -> AbstractProcessBuilder<'static, Self>
fn link() -> AbstractProcessBuilder<'static, Self>
Links the to be spawned process to the parent.
sourcefn link_with(tag: Tag) -> AbstractProcessBuilder<'static, Self>
fn link_with(tag: Tag) -> AbstractProcessBuilder<'static, Self>
Links the to be spawned process to the parent with a specific Tag.
sourcefn configure(config: &ProcessConfig) -> AbstractProcessBuilder<'_, Self>
fn configure(config: &ProcessConfig) -> AbstractProcessBuilder<'_, Self>
Allows for spawning the process with a specific configuration.