Expand description
§Murmer — A distributed actor framework for Rust
Murmer provides typed, location-transparent actors that communicate through
message passing. Whether an actor lives in the same process or on a remote
node across the network, you interact with it through the same
Endpoint<A> API.
§Core concepts
| Concept | Type | Purpose |
|---|---|---|
| Actor | Actor | Stateful message processor. Holds no state itself — state lives in an associated State type. |
| Message | Message | Defines a request and its response type. |
| RemoteMessage | RemoteMessage | A message that can cross the wire (serializable + TYPE_ID). |
| Endpoint | Endpoint<A> | Opaque send handle. Abstracts local vs remote — callers never know which. |
| Receptionist | Receptionist | Type-erased actor registry. Start, lookup, and subscribe to actors. |
| Router | Router<A> | Distributes messages across a pool of endpoints (round-robin, broadcast). |
| Listing | Listing<A> | Async stream of endpoints matching a ReceptionKey. |
§Quick start
ⓘ
use murmer::prelude::*;
// 1. Define your actor
#[derive(Debug)]
struct Greeter;
struct GreeterState { greeting: String }
impl Actor for Greeter {
type State = GreeterState;
}
// 2. Implement handlers — macro auto-generates message structs,
// Handler impls, RemoteDispatch, and a GreeterExt extension trait
#[handlers]
impl Greeter {
#[handler]
fn greet(&mut self, _ctx: &ActorContext<Self>, state: &mut GreeterState, name: String) -> String {
format!("{}, {}!", state.greeting, name)
}
}
// 3. Start and use
#[tokio::main]
async fn main() {
let system = System::local();
let endpoint = system.start("greeter/main", Greeter, GreeterState {
greeting: "Hello".into(),
});
// Call via auto-generated extension trait
let reply = endpoint.greet("world".into()).await.unwrap();
assert_eq!(reply, "Hello, world!");
}§Location transparency
The key design principle: Endpoint<A> hides whether the actor is local or remote.
- Local actors use the envelope pattern — zero serialization cost, direct in-memory dispatch through a type-erased trait object.
- Remote actors serialize messages with bincode, send them over QUIC streams, and deserialize responses on return.
The caller’s code is identical in both cases:
ⓘ
let result = endpoint.send(Increment { amount: 5 }).await?;§Actor discovery
The Receptionist is the central registry for actor discovery:
- Labels identify actors with path-like strings (
"cache/user","worker/0"). - Typed lookup via
receptionist.lookup::<MyActor>("label")returnsOption<Endpoint<A>>. - Reception keys group actors by type for subscription-based discovery.
- Listings provide async streams of endpoints as actors register and deregister.
§Supervision
Actors are managed by supervisors that handle lifecycle and crash recovery:
RestartPolicy::Temporary— never restart (default)RestartPolicy::Transient— restart only on panicRestartPolicy::Permanent— always restart
Restart limits and exponential backoff are configured via RestartConfig.
§Clustering
The cluster module provides multi-node actor systems over QUIC:
- SWIM protocol membership via
focafor failure detection - mDNS discovery for zero-configuration LAN clustering
- OpLog replication with version vectors for consistent registry views
- Per-actor QUIC streams — one multiplexed connection per node pair
Re-exports§
pub use actor::Actor;pub use actor::ActorContext;pub use actor::ActorRef;pub use actor::AsyncHandler;pub use actor::DispatchError;pub use actor::Handler;pub use actor::Message;pub use actor::MigratableActor;pub use actor::RemoteDispatch;pub use actor::RemoteMessage;pub use endpoint::Endpoint;pub use lifecycle::ActorFactory;pub use lifecycle::ActorTerminated;pub use lifecycle::BackoffConfig;pub use lifecycle::RestartConfig;pub use lifecycle::RestartPolicy;pub use lifecycle::TerminationReason;pub use listing::Listing;pub use listing::ListingEvent;pub use listing::ReceptionKey;pub use listing::WatchedListing;pub use node::run_node_receiver;pub use oplog::Op;pub use oplog::OpType;pub use oplog::VersionVector;pub use ready::ReadyHandle;pub use receptionist::ActorEvent;pub use receptionist::Receptionist;pub use receptionist::ReceptionistConfig;pub use router::PoolRouter;pub use router::Router;pub use router::RoutingStrategy;pub use system::System;pub use wire::DispatchRequest;pub use wire::RemoteInvocation;pub use wire::RemoteResponse;pub use wire::ReplySender;pub use wire::ResponseRegistry;pub use wire::SendError;
Modules§
- __
reexport - Re-export dependencies so generated code can reference them without the user needing them in their Cargo.toml.
- actor
- Core actor traits and types.
- cluster
- endpoint
- Endpoint — the user-facing send handle that abstracts local vs remote actors.
- lifecycle
- Lifecycle and restart types for actor supervision.
- listing
- Reception keys and listings for subscription-based actor discovery.
- node
- Node receiver — routes incoming remote invocations to local actors.
- oplog
- OpLog — operation log for distributed receptionist replication.
- prelude
- Convenience prelude — import everything you need for typical actor definitions.
- ready
- ReadyHandle — deferred actor startup.
- receptionist
- Receptionist — type-erased actor registry with typed lookup.
- router
- Router — distribute messages across a pool of actor endpoints.
- supervisor
- Supervisor — runs an actor, processing both local and remote messages.
- system
- System — unified entry point for local and clustered actor systems.
- wire
- Wire types for remote message dispatch.
Structs§
- Type
Registry Entry - An entry for auto-registration of an actor type in the cluster’s
cluster::sync::TypeRegistry.
Statics§
- ACTOR_
TYPE_ ENTRIES - Distributed slice populated by
#[handlers]macro expansions across all crates.
Attribute Macros§
- handlers
- Re-export proc macros from
murmer-macros(enabled by themacrosfeature, on by default).
Derive Macros§
- Message
- Re-export proc macros from
murmer-macros(enabled by themacrosfeature, on by default).