Expand description
§serviceless
A small async actor library: each Service runs on a single mailbox, handlers are
async, and callers interact through ServiceAddress (typed messages) and optional
topic pub/sub (Topic, TopicEndpoint). See the docs module for how to use the
actor model, runtime expectations, and topic semantics.
§Features
- Async actors — Each
Serviceruns a mailbox loop; hooks andHandlermethods areasync(viaasync_trait::async_trait). - Typed messages — Implement
MessageandHandlerfor compile-time dispatch instead of manual routing for your own message types. callandsend—ServiceAddress::callawaitsM::Result;ServiceAddress::sendenqueues work and drops the handler return value.- Preferred call path — Set
Message::IS_PERFERREDto dispatchServiceAddress::callviaHandler::handle_preferredandReplyHandlewhen you need custom reply timing. - Topics (pub/sub-style) —
Topic,RoutedTopic, andTopicEndpointfor one-shot subscribe / publish flows still serialized through the actor mailbox. - External envelope streams —
Context::with_streammerges anotherfutures_core::StreamofEnvelopes with the internal mailbox on the same single-consumer path. - Typed narrowing —
ServiceAddress::into_addressbuilds anAddressfor one message type plus a forwarding future you spawn alongside the mainrunfuture. - Bring your own runtime — The crate returns a
runfuture; you spawn it on Tokio or any other executor. There are no optional Cargo[features]on this crate today: the API surface is always enabled.
§Quick start
- Implement
Servicefor your actor state (pickEmptyStreamif you do not merge an external envelope stream). - Implement
Message+Handlerfor request/reply or fire-and-forget work. - Build a
Context, callService::start_by_context, then spawn the returned future on your async runtime. - Use the returned
ServiceAddressforServiceAddress::call,ServiceAddress::send, and optionallyServiceAddress::subscribe(topic key +Resultof a one-shot future) for topics.
use async_trait::async_trait;
use serviceless::{Context, EmptyStream, Handler, Message, Service};
#[derive(Default)]
struct Greeter;
#[async_trait]
impl Service for Greeter {
type Stream = EmptyStream<Self>;
}
struct Hello(pub String);
impl Message for Hello {
type Result = String;
}
#[async_trait]
impl Handler<Hello> for Greeter {
async fn handle(
&mut self,
msg: Hello,
_ctx: &mut Context<Self, Self::Stream>,
) -> String {
format!("Hello, {}", msg.0)
}
}
#[tokio::main]
async fn main() {
let (addr, run) = Greeter::default().start_by_context(Context::new());
tokio::spawn(run);
let reply = addr.call(Hello("Ada".into())).await.expect("reply");
assert_eq!(reply, "Hello, Ada");
addr.close_service();
}Longer explanations, caveats, and pub/sub details live under docs.
Modules§
- docs
- User guide
Structs§
- Address
- Address for specific message type
- Context
- Context to run service
- Envelope
- Type-erased mailbox item for service
S: a typed message dispatch or a topic operation. - Reply
Handle - Service
Address - Address of Service
- Topic
Endpoint - A single-shot broadcast endpoint.
Enums§
- Error
- Error
Traits§
- Handler
- Handler message on service
- Message
- Message
- Routed
Topic - Bind a topic to a concrete endpoint field on a service.
- Service
- A service is an running like thread
- Topic
- A typed pub/sub topic.
Type Aliases§
- Empty
Stream Emptystream ofEnvelopeforContext::newwhen there is no extra envelope source.- Result
- Result