Serviceless
Serviceless is a small async actor library for Rust, inspired by Actix-style APIs but kept
minimal: one mailbox per [Service], fully async handlers, and addresses for typed messaging plus
optional topic notifications.
The implementation of this crate does not use unsafe.
Features
- Async actors — Each service runs a mailbox loop;
started/stoppedhooks andHandler::handleareasync(use theasync_traitcrate). - Typed messages — Implement
MessageandHandlerfor your own types instead of manual routing tables. callandsend—ServiceAddress::callawaitsM::Result;sendenqueues work and drops the handler return value.- Topics (pub/sub-style) —
Topic,RoutedTopic, andTopicEndpointfor one-shot subscribe / publish flows, still serialized through the actor mailbox. - External envelope streams —
Context::with_streammerges another stream ofEnvelopes with the internal mailbox. - Typed narrowing —
ServiceAddress::into_addressbuilds a single-message-typeAddressplus a forwarding future you spawn next to the main run future. - Bring your own runtime — The library returns a
runfuture; you spawn it (examples use Tokio). There are no optional Cargo[features]on this crate: the full API is always available.
Documentation
- Run
cargo doc --open -p servicelessfor full API reference. - Narrative guide (actor usage, caveats, pub/sub): see the
serviceless::docsmodule in the generated docs (overview, services, messaging, pub/sub, runtime).
Usage
Service
A Service is your actor type. You must set the associated Stream type (often
EmptyStream<Self> when
you only use the built-in mailbox).
use async_trait;
use ;
;
Starting and stopping
Build a Context, start the
service, then spawn the returned run future on your async runtime. Until that future is polled,
mailbox work will not run.
use Context;
# use async_trait;
# use ;
# ;
#
let actor = default;
let ctx = new;
let = actor.start_by_context;
spawn;
Stop from inside the actor with Context::stop,
or from outside with
ServiceAddress::close_service.
Message and handler
Declare a Message (with
type Result) and implement Handler
for your service.
use async_trait;
use ;
;
;
Address: call, send, and topics
ServiceAddress is
cloneable and is how other tasks talk to the actor.
call—async; waits forM::Result. If the service has stopped, you getError::ServiceStoped.send— synchronous for the caller; still returnsResultand drops the handler return value.- Preferred dispatch —
callandsenddispatch throughHandler::handle_preferred. The defaulthandle_preferredimplementation callshandle, then usesReplyHandlefor replies. You can overridehandle_preferredto spawn a task and reply later so the current handler path does not block mailbox progress (seeactor/examples/preferred.rs). subscribe— synchronous enqueue with a topic key argument; returnsResultof aFutureyou await for the next matching publication (seeserviceless::docs::pubsubandexamples/topic.rs).
Examples
Runnable examples live under actor/examples/ (e.g. topic.rs, single.rs, external_stream.rs,
preferred.rs).