orbit-pool
Who has a free one, and may I have it: fleet-wide leases over Orbit shared memory.
One worker holds a warm connection and another needs it. The second asks
the pool, which knows every connection registered under that key across
the fleet, how loaded each is and who owns it; it reserves one unit of the
chosen connection's capacity with a single compare-and-swap and gets a
lease. It brings the lease to the owner, the owner accepts it, does the
work, and gives the unit back when the work is over. Nothing moves between
processes but numbers: the connection stays where it is. Applications
normally use it through orbitive::pool.
Bringing the lease to its owner is the one step every consumer shares and
every consumer can get wrong, so the stream feature owns it:
open_session reaches the owner over an orbit-stream stream you supply,
accept_session reads the lease and accepts it exactly once before a byte
of your payload is trusted, and what crosses afterwards is yours alone.
use Arc;
use Duration;
use ;
use Fleet;
let fleet = new;
// One value per process life, from whoever supervises processes.
let pool = new?;
// The caller's digest of "what this is usable for": an origin plus
// everything that forbids reuse across contexts.
let key = new;
let limits = Limits ;
match pool.acquire?
# Ok::
What the pool is
A resource is something one process owns and others may use through it. Its owner registers it under a key with a capacity: one for an exclusive thing such as an HTTP/1 connection, more for one that admits several users at once such as HTTP/2 streams. The table then shows it to the fleet as a candidate: owner, capacity, how many units are reserved and how many are being executed, whether it is live or draining.
A lease is one unit of that capacity, reserved by any process with one
compare-and-swap; a snapshot that showed room is not a lease. The lease is
plain data: the resource's address, a fence that grows with every
reservation on that resource, and who holds it. The owner accepts it,
which takes that fence out of the resource's pending reservations exactly
once and turns the unit into an active one; the returned Execution guard
gives the unit back when dropped or completed. A lease accepted twice, or
after the owner aged it out, is refused.
That guard is the only way capacity returns. A caller that gives up, times
out or dies frees nothing, because only the owner knows when the resource
is idle again; a reservation the owner never received is aged out by the
owner's reconcile, with a grace it chooses, and never by a caller's
clock. Caller cancellation and owner completion are two different events.
A creation claim keeps a fleet from overshooting: claim_create
counts live resources and claims in progress together against the
caller's max_live, so forty workers that all see an empty key do not
each open a connection. Dropping the permit returns the claim.
acquire runs the loop for one request: snapshot, ask the policy,
reserve or claim what it chose, retry a lost race with a fresh snapshot,
and hand back a committed Plan: LocalReuse, RemoteReuse, Create,
Wait or Reject. LocalFirst and LocalOnly are the policies shipped;
a Policy is a trait, and no cost figure from any benchmark is built in.
Whether reusing a remote resource beats creating a local one is a
measurement the embedder makes and expresses in its own policy.
What it is not
The pool decides and counts. It does not execute anything, and it carries
no bytes: the input and output of a remote use travel over an
orbit-stream stream that the caller opens to the owner, with the lease
in its first bytes or in any setup message the application prefers. A
local use goes nowhere: no stream, no shared-memory hop. HTTP, health,
load-balancing weights and retry rules live above it.
Waiting and death
wait_capacity(key, version) parks a thread until the key changes: a
completion, an unregister, a closed resource, a returned claim.
poll_capacity does the same for a task through one driver thread per
process, as orbit-stream does. Nothing here knows whether a process is
alive: the embedder reports a confirmed death with node_dead(node, incarnation), and every resource that life of the process owned is
closed and its creation claims returned; leases it held on other owners'
resources are those owners' to complete, which they do when the stream
that carried them ends.
Geometry is compile-time: ORBIT_POOL_KEY_CAPACITY (keys per epoch,
default 256) and ORBIT_POOL_RESOURCE_LANE_CAPACITY (resources per node,
default 256). reset_all empties the table during quiescent boot and
starts a new epoch.