Cellule is a framework embedded in an application process. It supplies Cell state, ownership, publication, recovery, typed capabilities, and node drain. Your service supplies product identity, public ingress and authorization, object-store credentials, endpoints, and deployment policy. Start with the local quickstart; its in-memory store and local owner show the mechanics without a serving fleet.
The visual overview shows a Cell, the component boundaries, and the path from declaration to a typed request.
| Concern | Cellule API | Service decision |
|---|---|---|
| Domain | CellApplication, CellModule, CellType |
Which modules, schemas, and stable IDs ship in this binary. |
| Storage | Store, CellStorageLayout, probe_storage |
Provider, credentials, bucket/prefix, capacity and readiness policy. |
| Node | CellNodeBuilder, CellNode |
Session identity, lease enrollment, facilities, task supervision. |
| Requests | ApplicationHandle, optional cellule-peer-http |
Public route, user authorization, peer receiver and admission policy. |
| Background work | Activity and Effect supervisors | Which runners to install, schedule, drain, and cancel. |
flowchart LR
Compile[Compile application] --> Probe[Probe provider]
Probe --> Build[Build CellNode]
Build --> Enroll[Enroll session and install lease]
Enroll --> Facilities[Install owned facilities and tasks]
Facilities --> Ready[Open service readiness]
Ready --> Drain[Stop admission and drain]
Drain --> Withdraw[Close log and withdraw session]
- Compile once. Register modules, migrations, operation IDs, and Cell
types.
CellApplication::compile(BuildDescriptor)produces the immutable descriptor and registry that the node and typed clients must share. The API guide explains the author contracts. - Construct and probe storage. The service chooses provider credentials
and scope. Build a
StoreandCellStorageLayout, then runcellule_store::probe_storageon a fresh private prefix before advertising readiness. Require conditional create, ETag update and stale-ETag rejection, and exact ranged reads; inspectStorageProbeReport::passedandfailed_checks. The host does not run a credentialed probe for you. - Build one host.
CellNodeBuilder::new(compiled_application)needs aSqlWorkerPool, retained-byte ceiling, LTX replica host, and nonzero node session. Set explicit disk and native-memory budgets for the environment.build()creates a lease-requiring serving node; its runtime is not ready merely because construction succeeded. - Enroll and install ownership. Publish the signed node session, install
its lease and a
CellNodeTaskGroup, and run lease renewal withspawn_lease_maintenance. Install every facility declared as required bywith_required_owned_components.CellNode::start()refuses readiness without the lease, healthy task group, and required owned components. - Serve through typed handles. Authorize a product request first. Bind a client to the compiled application, tenant, and application IDs, then select the Cell with a declared partition rule. A command returns a typed output and receipt only after its durability gate. A later query may require that receipt. The SQL example shows the local setup and invocation; serving products supply their own listener and routing.
build_unleased_for_maintenance() is a bounded, unadvertised offline path. It
is not a shortcut for serving readiness. The
host lifecycle guide lists the
installed components and drain behavior.
cellule-peer-http supplies owner routing, HTTP response classification, and
pinned mTLS transport using runtime peer contracts. It does not install a
public endpoint or authorize application users. The service owns the receiver:
- Authenticate the enrolled peer and verify the signed request.
- Enforce the application and target scope before dispatch.
- Apply the adapter's body, deadline, and admission semantics.
- Dispatch through
PeerDispatcher; return its classified response.
Use PeerTargetScope, LoadedPeerTls::load, and PeerHttpRoundTrip when
wiring a signed peer CellClient. Read the
transport guide, especially its
429/503 and timeout rules.
sequenceDiagram
participant Caller as Application caller
participant Gateway as Authorized ingress
participant Owner as Fenced Cell owner
Caller->>Gateway: Command with stable request ID
Gateway->>Owner: Signed owner-routed invocation
alt Result arrives
Owner-->>Gateway: Output and receipt
Gateway-->>Caller: Output and receipt
else Reply is lost
Gateway-->>Caller: Outcome unknown
Caller->>Gateway: Resolve original request ID
Gateway->>Owner: Read durable request outcome
Owner-->>Gateway: Recorded result or unresolved state
end
A lost or invalid response is an unknown outcome, not permission to issue a new request ID. Resolve the original mutation evidence; an owner change or expiry can leave it unresolved. See API outcome handling.
The host's read-replica manager admits immutable snapshots, refreshes them,
and evicts them under resource pressure. A typed handle can request
ReadPolicy::Replica; a missing or lagging reader fails with
ReplicaUnavailable or ReplicaBehind. It does not silently fall back to the
owner. Commands, mutation resolution, state streams, and lease validation
remain owner-ordered. Reserve native memory for snapshots separately from
writer capacity with SqlWorkerPool::with_native_memory_limit, and follow the
read-replica guide.
Workflow Activities and Effects perform work outside a Cell's SQLite transaction. Their runtime supervisors retain lease and retry rules, but the service installs and supervises the runners in its node task group. The service also decides external idempotency behavior at a destination. A schedule or effect intent in a module descriptor does not by itself launch a background worker.
CellNode owns exactly one runtime. Shutdown and scale-down serialize through
one drain lane. The node stops admission and work producers, drains accepted
work while lease maintenance is still live, closes the covered node log, then
stops renewal and withdraws the session. Finally it releases readers, slots,
tasks, and SQLite handles. Use shutdown_until(deadline) for a bounded owned
drain; the deadline bounds releases after entering the drain lane, not waiting
for that lane. Fleet movement pacing remains a service planner decision.
Keep public readiness and session withdrawal aligned with this lifecycle. A service should not announce readiness before provider probes and owned components pass, or remain ready after node admission closes. Read architecture for the publication and recovery contracts and qualification for evidence beyond the local quickstart.