boson (uf-boson on crates.io)
Main crate — re-exports core types, runtime, optional backends, and the #[task] macro.
The crates.io package is uf-boson (boson is already taken). With [lib] name = "boson",
imports stay use boson::….
Source of truth: cargo doc -p uf-boson --features mem,axum --open — guided get-started with
Embedded and
Remote worker.
Published docs: https://docs.rs/uf-boson
Role
task—#[task]macro and typedsend_withBoson/BosonBuilder— worker boot- Feature-gated backends:
mem,sqlite,postgres,axum,telemetry-console - Fleet backends:
boson-backend-redis,boson-backend-nats prelude— common re-exports
Cargo features
| Feature | Enables |
|---|---|
mem |
MemQueueBackend and bootstrap helpers |
sqlite |
SqliteQueueBackend and bootstrap helpers |
postgres |
PostgresQueueBackend and bootstrap helpers |
telemetry-console |
ConsoleOpsLog (always available via re-export) |
axum |
HTTP admin router and state types |
This crate ships with no default features (default = []).
How to run examples
Navigational index: examples/README.md (when-to-use ladder, host-mount sketches, success checks).
Canonical teaching path (start here). Topology docs: Embedded / Remote worker.
1. Embedded — task_macro (standalone)
One process, in-memory backend. No external services.
Success: stdout prints greet world (actor=…).
2. Remote worker — SQLite (multi-process — run as a set)
Enqueue host and workers share one database file. They are not useful alone.
| Rule | Detail |
|---|---|
| Shared env | Same BOSON_SQLITE_PATH on every process |
| Start order | Worker(s) first, then enqueue |
| Workers | Each needs a unique BOSON_WORKER_ID; lease_ttl_secs > 0 (default 30 in the example) |
| Stop | Ctrl-C on each worker (or set BOSON_WORKER_RUN_SECS for scripted smoke) |
Local SQLite — 1–2 workers + enqueue:
# Terminal 1 — worker A
BOSON_WORKER_ID=worker-a
# Terminal 2 — worker B (optional)
BOSON_WORKER_ID=worker-b
# Terminal 3 — enqueue
3. Remote worker — Postgres (multi-process — run as a set)
Same pattern against a shared database URL (production-shaped durable backend).
| Rule | Detail |
|---|---|
| Shared env | Same DATABASE_URL (or BOSON_POSTGRES_URL) on every process |
| Start order | Worker(s) first, then enqueue |
| Workers | Unique BOSON_WORKER_ID; positive lease TTL |
# Terminal 1 — worker A
BOSON_WORKER_ID=worker-a
# Terminal 2 — worker B (optional)
BOSON_WORKER_ID=worker-b
# Terminal 3 — enqueue
Stop with Ctrl-C on each worker. Real apps put #[task] handlers in a shared crate and
use my_tasks as _; from the worker binary.
Docker quickstart (no local Postgres install): the repo ships a Compose stack at
infra/postgres/.
&&
Then run the worker/enqueue pair above from the repo root. Stop with
docker compose -f infra/postgres/docker-compose.yml down.
4. Remote worker — Redis fleet (multi-process — run as a set)
Broker-backed fleet backend — same split shape, many enqueue hosts and workers sharing Redis.
Not a uf-boson feature — depends on
boson-backend-redis directly (a path dev-dependency in
this crate; production apps add it to [dependencies]).
| Rule | Detail |
|---|---|
| Shared env | Same BOSON_REDIS_URL on every process (default redis://127.0.0.1:6379) |
| Start order | Worker(s) first, then enqueue |
| Workers | Unique BOSON_WORKER_ID; positive lease TTL |
# Terminal 1 — worker A
BOSON_WORKER_ID=worker-a
# Terminal 2 — enqueue
5. Remote worker — NATS WorkQueue (multi-process — run as a set)
Broker-backed fleet backend on NATS JetStream WorkQueue streams via
connect_auto
with BOSON_NATS_QUEUE_MODE=workqueue. Not a uf-boson feature — depends on
boson-backend-nats directly.
| Rule | Detail |
|---|---|
| Shared env | Same BOSON_NATS_URL and BOSON_NATS_QUEUE_MODE=workqueue on every process |
| Start order | Worker(s) first, then enqueue |
| Workers | Unique BOSON_WORKER_ID; positive lease TTL; pin BOSON_WORKER_POOLS — WorkQueue pool discovery is per-process, so cross-process workers cannot auto-discover pools (#[task] default pool is global) |
# Terminal 1 — worker A
BOSON_WORKER_POOLS=global BOSON_WORKER_ID=worker-a
# Terminal 2 — enqueue
Other examples
| Example | Topology | Features | Notes |
|---|---|---|---|
minimal_enqueue |
Embedded | mem |
Manual registry + Boson::enqueue |
idempotency_and_rate_limit |
Embedded | mem |
Idempotency key + max_in_flight |
axum_admin |
Embedded + HTTP admin | mem,axum |
Nest /api/boson; BOSON_EXAMPLE_SERVE=1 to listen |
admin_auth_policy |
Embedded + HTTP admin | mem,axum |
Fail-closed axum_admin: proves 401 without a token, 200 with one |
Production: Boson does not authenticate /api/boson/* by itself. Install host
AdminAuth and prefer
BOSON_REQUIRE_ADMIN_AUTH=1 — see repository SECURITY.md.
Boot a worker (embedded)
[]
= { = "uf-boson", = "0.1.1", = ["mem"] }
= { = "1", = ["rt-multi-thread", "macros"] }
use Arc;
use ;
async
let boson = builder
.queue_backend
.execution_context_factory
.auto_registry
.build?;
configure;
With HTTP admin: features = ["mem", "axum"]. Full walkthrough: crate rustdoc Getting started and
task_macro.
Define handlers and enqueue
After boot, add handlers with #[task] and enqueue with <TaskName>::send_with(...). See
boson-macros for policy attributes.
Configuration precedence
| Layer | Resolution order |
|---|---|
| Worker settings | BosonBuilder field → env var → default |
| Task config at enqueue | Persisted backend config → macro/descriptor defaults |
| Idempotency mode | Per-task override → runtime builder default |
| Queue backend | Explicit queue_backend() → global router |
| Ops log | Builder ops_log() → NoOpsLog; or ops_log_from_env() |
| Fleet URLs (Redis/NATS) | BOSON_*_POOL_ROUTING → BOSON_*_URLS |
Related crates
boson-macros—#[boson::task]proc macroboson-runtime— worker runtime and builderboson-core— shared types andQueueBackendtraitboson-axum— HTTP admin API