@rivus/agent-kit-collab/lease
createLeaseManager, LeaseRepository, sqliteLeaseRepository, fileLeaseRepository, memoryLeaseRepository — Effect
Functions
createLeaseManager()
function createLeaseManager(config: LeaseConfig): Effect<LeaseManager, LeaseConfigInvalid,
| PlatformService
| LeaseRepository>;Validates config and builds a manager over the LeaseRepository and the platform in context.
Parameters
config
LeaseConfig
Returns
Effect<LeaseManager, LeaseConfigInvalid,
| PlatformService
| LeaseRepository>
fileLeaseRepository()
function fileLeaseRepository(options: FileLeaseRepositoryOptions): Layer<LeaseRepository, never, PlatformService>;The fallback repository for platforms without SQLite: one JSON record per key, <key>.lease.json, replaced with
writeAtomic. Every save holds the key's guard (<key>.lease.guard) while it reads, compares and writes, and
reports busy when the guard stays held longer than a second; fence holds <key>.lease.fence. Both are process
locks, so without SQLite they are lock files whose dead holders are reclaimed one reclaimer at a time, with the
gaps acquireProcessLock documents. A record with an unknown schemaVersion or shape is refused and never
overwritten.
Parameters
options
FileLeaseRepositoryOptions
Returns
Layer<LeaseRepository, never, PlatformService>
memoryLeaseRepository()
function memoryLeaseRepository(): Layer<LeaseRepository>;A repository for one process, such as tests or a host whose leases never cross a process boundary. Each Layer build starts empty.
Returns
Layer<LeaseRepository>
sqliteLeaseRepository()
function sqliteLeaseRepository(options: SqliteLeaseRepositoryOptions): Layer<LeaseRepository, LeaseRepositoryFailure, PlatformService>;The lease repository for one machine: one row per key in a SQLite database. save runs in a BEGIN IMMEDIATE
transaction, which takes SQLite's write lock (an fcntl lock) before reading the revision, so processes sharing the
file compare and write atomically. The lock is released when its process exits, so neither a crashed writer nor a
reused pid can leave the repository stuck. Fails to build with unavailable when the platform has no SQLite, and
with unsupported-schema for a database written by a newer version.
Parameters
options
SqliteLeaseRepositoryOptions
Returns
Layer<LeaseRepository, LeaseRepositoryFailure, PlatformService>
Classes
LeaseRepository
The lease repository port; sqliteLeaseRepository, fileLeaseRepository and memoryLeaseRepository provide it.
Extends
LeaseRepositoryBase
Constructors
Constructor
new LeaseRepository(_: never): LeaseRepository;Parameters
_
never
Returns
Inherited from
LeaseRepositoryBase.constructor
Interfaces
Holder
The process that holds a lease, with the same shape as the Platform's ProcessIdentity. The start time tells a
reused pid apart from the holder; the boot id tells a process of an earlier boot apart.
Properties
bootId
readonly bootId: string;host
readonly host: string;pid
readonly pid: number;startTime
readonly startTime: number;LeaseConfigInvalid
A lease duration is out of range, or the heartbeat does not fit twice into the TTL.
Properties
_tag
readonly _tag: "LeaseConfigInvalid";message
readonly message: string;LeaseHandle
A held lease. It belongs to the Scope acquire ran in: closing the Scope stops the heartbeat and releases it.
Properties
key
readonly key: string;lost
readonly lost: Effect<never, LeaseLost>;Fails with LeaseLost once the heartbeat finds the lease taken over, released or missing, or cannot confirm a
renewal within the TTL; it never succeeds. Race other work against it to stop that work on loss.
token
readonly token: FencingTokenSnapshot;Methods
runFenced()
runFenced<A, E, R>(work: (token: FencingTokenSnapshot) => Effect<A, E, R>): Effect<A,
| LeaseRepositoryFailure
| LeaseLost
| E
| FenceRejected, Exclude<R, Scope>>;Runs work under the repository's per-key fence, after re-reading that this acquisition still holds the lease, and
passes it the fencing token for the writes it makes. Waiting for the fence stops when the lease is lost. When the
lease is lost while work runs, work is interrupted and the result fails with LeaseLost.
The fence is released when work's fiber has ended, so a successor's fenced work starts only after that. An
interrupted fiber ends at once, though, while a Promise it started (Effect.tryPromise) keeps running: put a
write that cannot be cancelled in Effect.uninterruptible, which keeps the fence until the write settles, or pass
it the AbortSignal tryPromise provides and settle only after the write has stopped. A resource that can compare
atomically should also store the highest generation per token key and reject smaller generations in that write.
Type Parameters
A
A
E
E
R
R
Parameters
work
(token: FencingTokenSnapshot) => Effect<A, E, R>
Returns
Effect<A,
| LeaseRepositoryFailure
| LeaseLost
| E
| FenceRejected, Exclude<R, Scope>>
LeaseHeld
Another acquisition holds the lease and is alive and renewing, as far as the observer can tell.
Properties
_tag
readonly _tag: "LeaseHeld";generation
readonly generation: number;holder
readonly holder: Holder;holderId
readonly holderId: string;key
readonly key: string;LeaseLost
This acquisition no longer holds the lease: another one took it over or released it, the record vanished, or no renewal could be confirmed within the TTL.
Properties
_tag
readonly _tag: "LeaseLost";generation
readonly generation: number;key
readonly key: string;reason
readonly reason: "missing" | "taken-over" | "released" | "expired";LeaseManager
Methods
acquire()
acquire(key: string, options?: AcquireOptions): Effect<LeaseHandle,
| LeaseRepositoryFailure
| LeaseHeld, Scope>;Takes the lease for key in the caller's Scope and keeps renewing it there. Fails with LeaseHeld while a live
holder keeps it fresh; a dead holder (same host) is taken over at once, a silent one after the TTL. Throws an
AgentKitError (as a defect) for an empty key.
Parameters
key
string
options?
AcquireOptions
Returns
Effect<LeaseHandle,
| LeaseRepositoryFailure
| LeaseHeld, Scope>
read()
read(key: string): Effect<LeaseSnapshot | undefined, LeaseRepositoryFailure>;Parameters
key
string
Returns
Effect<LeaseSnapshot | undefined, LeaseRepositoryFailure>
LeaseRepositoryFailure
The repository could not read or write a record; the lease's state is unknown, not changed.
Properties
_tag
readonly _tag: "LeaseRepositoryFailure";cause?
readonly cause?: unknown;key
readonly key: string;message
readonly message: string;reason
readonly reason: "busy" | "io" | "invalid-record" | "unsupported-schema" | "unavailable";busy: other writers kept the repository locked; invalid-record: a stored record is unreadable or breaks the
invariants, or its next generation cannot be represented, and it is left as it is;
unsupported-schema: the repository was written by a newer version;
unavailable: the platform lacks what the repository needs; io: any other failure.
LeaseSnapshot
A lease record as stores keep it. A released lease stays as a tombstone with no holder.
Properties
generation
readonly generation: number;The fencing token: +1 on every acquisition, unchanged by renewals and release.
holder
readonly holder: Holder | null;holderId
readonly holderId: string | null;Names one acquisition, so that two acquisitions by the same process are told apart.
key
readonly key: string;renewedAt
readonly renewedAt: number;Wall-clock time of the last write, for diagnostics; expiry is judged with the observer's monotonic clock.
revision
readonly revision: number;+1 on every write; stores compare it to write only over the record a caller read.