This file orients an agent (or a new contributor) to the shove crate. For the
human build/test/lint workflow see CONTRIBUTING.md.
shove is a type-safe, async pub/sub library over six message backends. The
entire public surface hangs off a single generic Broker<B>: you parameterize
it with a backend marker type B, and one consistent API (publish, consume,
consumer groups, topology, autoscaling) works across every backend.
- Generic layer lives directly in
src/:broker.rs,publisher.rs,consumer.rs,consumer_group.rs,consumer_supervisor.rs,autoscaler.rs,topology.rs,topology_declarer.rs. These are backend-agnostic wrappers aroundBroker<B>. - Per-backend implementations live in
src/backends/<name>/. Each backend has the same file layout:backend.rs,client.rs,consumer.rs,consumer_group.rs,publisher.rs,topology.rs,autoscaler.rs, plusconstants.rs/headers.rs. - The sealed
Backendtrait (src/backend/mod.rs) binds, for each marker type, that backend's client / publisher / consumer / topology / registry types. Being sealed means external crates cannot add backends.
| Backend | Feature flag | Marker type |
|---|---|---|
| RabbitMQ | rabbitmq |
RabbitMq |
| AWS SNS+SQS | aws-sns-sqs (publisher-only: pub-aws-sns) |
Sqs |
| NATS JetStream | nats |
Nats |
| Apache Kafka | kafka (+ kafka-ssl, kafka-msk-iam, kafka-schema-registry) |
Kafka |
| Redis/Valkey Streams | redis-streams |
Redis |
| In-process | inmemory |
InMemory |
Other add-on features: audit, metrics, protobuf, rabbitmq-transactional.
- Kafka, RabbitMQ, NATS, InMemory, and Redis implement
HasCoordinatedGroupsand exposeBroker::consumer_group. - SQS does not implement
HasCoordinatedGroups— callingconsumer_group()onBroker<Sqs>is a compile error. SQS usesConsumerSupervisor(src/consumer_supervisor.rs) instead.
- Typed-topic macros
define_topic!/define_sequenced_topic!— insrc/macros.rs(re-exported fromsrc/lib.rs). - Outcome / retry semantics —
src/outcome.rs(theOutcomeenum:Ack/Retry/Reject/Defer) andsrc/retry.rs. - Per-backend retry/DLQ routing — each backend's
src/backends/<name>/consumer.rs::route_outcome(RabbitMQ also hassrc/backends/rabbitmq/router.rs). This is where a delivery-semantics decision is turned into ack/commit/publish/DLQ mechanics.
- Fast path (no Docker, no secrets):
cargo nextest run --no-default-featuresruns unit + in-memory tests. (CI usescargo test --no-default-features; this repo's convention iscargo nextest run.) - Integration tests require Docker (real brokers via
testcontainers). The AWS/MSK tests additionally requireLOCALSTACK_AUTH_TOKEN, supplied viadotenvx run -- cargo nextest run --features <set>. SeeCONTRIBUTING.mdfor per-backend feature sets. - Lint gates CI enforces:
cargo fmt -- --checkcargo clippy --all-features -- -D warningscargo clippy --no-default-features -- -D warnings
- Never run tests with plain
cargo testif you can usecargo nextest run; do not pass-q/--quiettonextest(it rejects it).
- Cross-backend consistency: a delivery-semantics bug (retry boundary, DLQ
routing, defer handling) usually must be fixed in all backends'
route_outcome, not just one. The git history shows recurring "cross-backend consistency" commits because a fix landed in one backend and was missed in the others. When you touch retry/DLQ logic, check every backend. - Conventional Commits for commit messages. No CHANGELOG — releases are
release: vX.Y.Zcommits. - Do not add
Co-Authored-Bytrailers to commits.