Wonder
An Erlang/Elixir inspired actor library for Rust
Requirements
- stable/nightly Rust
Quick Start
Define your actor
;
Implement the GenServer trait
Start your actor
use actor;
GenServer Trait
To create a GenServer actor you need to create a struct (perhaps a unit-like struct?) and implement the GenServer trait.
struct MyActor;
Associated Types
To implement the GenServer trait you need to define 3 associated types
T
- A public enum type for messages to be sent to and from the GenServer.S
- The state which the actor will own and maintain.()
can be provided in the case of an actor who will manage no state.E
- A public enum type for errors to be returned by your GenServer.
note: It is required for both the custom error and message enums to derive the Debug trait.
Callbacks
The GenServer trait exposes 4 callbacks; one of which is required while the remaining three have default implementations making them optional to implement.
init/3 -> InitResult<E>
analogous to GenServer:init/1
Handles initialization of the newly created actor. As with proccess initialization in Elixir/Erlang, this is a blocking call. This function will be called once while the actor is starting.
The init function must returns an InitResult
which is either Ok(Option<u64>)
or Err(E)
where E is your custom error type. The optional u64
is the timeout value (in milliseconds) for the actor.
Parameters
atx
- Channel sender for the running actor. This is equivalent to sending to "self" in Elixir/Erlang.state
- A mutable reference to the state that the running actor owns.
note:
InitResult
is analogous to the return tuple for theinit/1
callback in Elixir; ie.{:ok, state}
or{:stop, reason}
handle_call/5 -> HandleResult<T>
(optional)
analogous to GenServer:handle_call/3
Handles synchronous messages sent to the running actor.
Parameters
tx
- Channel sender for the caller who started the actor. This is equivalent to sending to the caller's PID in Elixir/Erlang.atx
- Same asinit/3
.state
- Same asinit/3
.
note:
HandleResult
is analogous to the return tuple for thehandle_call/3
callback in Elixir/Erlang.
handle_cast/4 -> HandleResult<T>
(optional)
analogous to GenServer:handle_cast/2
Handles asynchronous messages sent to the running actor.
Parameters
atx
- Same asinit/3
state
- Same asinit/3
note:
HandleResult
is analogous to the return tuple for thehandle_cast/2
callback in Elixir/Erlang.
handle_timeout/3 -> HandleResult<T>
(optional)
analogous to matching
handle_info(:timeout, _state)
in Elixir
Called when a timeout is set and the required amount of time has elapsed. A timeout can be set by including a timeout value in a HandleResult
or InitResult
returned by one of the GenServer callbacks.
The timeout can be used for various reason, but a great example is a pattern to perform late initialization. If your actor has a long running initialization period you can timeout immediately and perform initialization within the handle_timeout
callback.
Parameters
atx
- Same asinit/3
state
- Same asinit/3
note:
HandleResult
is analogous to the return tuple for thehandle_info/2
callback in Elixir/Erlang.
Authors
Jamie Winsor (jamie@vialstudios.com)