caravan-rpc (Rust)
Runtime SDK for the Caravan application-definition compiler.
Status: 0.1.1. Functional runtime with #[wagon] proc-macro, axum HTTP server adapter, Lambda Function URL client + server adapters, CARAVAN_RPC_PEERS env-var dispatch, peer-mode self-call guard, and Caravan-shipped resource adapters (BlobStore, MessageQueue) for S3 / Redis / RabbitMQ / SQS.
What is Caravan?
Caravan is an application-definition compiler. The same source code deploys across packaging (inproc / container / lambda) × placement (compose / Fargate / Lambda) × composition (oss-local / cloud-managed) axes by yaml-line changes alone — no source-code edits.
Read the thesis and the PoC RPC SDK spec.
Install
[]
= "0.1.1"
Optional feature gates (off by default for WASM-friendly builds):
= { = "0.1.1", = ["client", "server"] }
# Resource-adapter extras (each pulls in its backend libs only when enabled):
# resources-aws — boto-like S3BlobStore + SqsQueue via aws-sdk-rust
# resources-redis — RedisStreamQueue via redis crate
# resources-rabbit — RabbitMQQueue via lapin
# resources-all — convenience meta-feature
Three-point structural contract
User code interacts with Caravan through three SDK entry points; everything else is compiler-managed:
use Arc;
use ;
// 1. `#[wagon]` declares a trait as a Caravan seam — a synchronous
// abstraction boundary that yaml can flip between inproc / HTTP /
// Lambda dispatch per target.
// 2. `provide` registers a concrete impl at process startup.
// 3. `client` dispatches a call — inproc, HTTP, or Lambda per the
// `CARAVAN_RPC_PEERS` env var the compiler emits per target.
async
run_or_serve — fourth contract point for entry mains
Peer containers reuse the consumer entry's image; CARAVAN_RPC_ROLE=peer-<Interface> (injected by Caravan) tells the SDK to serve that interface instead of running the user app:
async
When CARAVAN_RPC_ROLE=peer-Embedder is set, run_or_serve discovers the macro-emitted server adapter for Embedder from inventory, builds the axum router, and serves on 0.0.0.0:8080. When AWS_LAMBDA_RUNTIME_API is also set (AWS Lambda runtime), the same router is handed to lambda_http::run instead of binding TCP.
Dispatch modes
CARAVAN_RPC_PEERS is a per-deploy-unit JSON map the compiler emits:
inproc→client::<dyn T>()returns the registered local impl directly (zero overhead).http→ returns an<Trait>HttpClientthat POSTs to/_caravan/rpc/<iface>/<method>with a Bearer token.lambda→ SigV4-signed POST to the Lambda Function URL.
Peer-mode self-call guard: when CARAVAN_RPC_ROLE=peer-<T> matches the served interface, try_client::<dyn T>() bypasses the HTTP factory and returns the local impl — peer containers share the consumer's CARAVAN_RPC_PEERS, so without this guard the macro-emitted router would loop back over HTTP to itself.
Resource adapters
Caravan-shipped impls of common resource seams (gated by feature flags so users only pull in the backends they need):
use ;
use client;
Backend selection is driven by explicit Caravan-emitted markers:
CARAVAN_BLOB_BACKEND=s3+S3_BUCKETset →S3BlobStore(real AWS or MinIO viaS3_ENDPOINT_URL).CARAVAN_BLOB_BACKEND=local-fs→LocalFsBlobStorerooted atLOCAL_FS_BLOB_PATH(or yaml fallbackblob_storage.base_path).- Marker unset → consult
yaml_fallback. Non-caravan local-dev path.
CARAVAN_BLOB_BACKEND=s3 with no S3_BUCKET loud-fails at startup (catches the "user forgot to populate .env.hybrid from tofu output" footgun).
Versions
- 0.1.1: peer-mode self-call guard;
CARAVAN_BLOB_BACKENDexplicit marker;try_client::<T>()skips the HTTP factory when serving aspeer-<T>. SDK version bumped alongside Python 0.1.1 for matching wire-protocol semantics. - 0.1.0: first functional release.
#[wagon]proc-macro, axum HTTP adapter, Lambda Function URL client + server (M7), resource adapters (M4-cloud),run_or_serveentry contract (M2 Path B). - 0.0.x: crates.io name reservation placeholders.
See development_plan.md for the full milestone history.
License
Apache-2.0. See LICENSE.