InMemoryLease
InMemoryLease ist die Dev-/Test-Implementierung des
Lease-Interfaces. Sie hält den
Lease-State im Prozessspeicher — mehrere InMemoryLease-Instanzen,
die denselben name teilen, schließen sich also korrekt aus,
aber nur innerhalb eines Prozesses.
import { InMemoryLease } from 'actor-ts/coordination';
const lease = new InMemoryLease({ name: 'my-singleton', owner: 'instance-1', ttlMs: 30_000,});
await lease.acquire(); // → true (erstes Acquire)Wann du sie einsetzt
Abschnitt betitelt „Wann du sie einsetzt“- Unit Tests für Actors, die einen
Lease-Parameter bekommen — übergibInMemoryLease, um Lease-Verhalten ohne echtes Backend zu verifizieren. - Dev für Code, der einen Lease braucht, aber du willst Kubernetes oder etcd nicht lokal aufsetzen.
- MultiNodeSpec-Tests — jeder “Node” läuft in einem Prozess, also schließt sich ein über die Test-Nodes geteiltes InMemoryLease korrekt aus.
Wann du sie NICHT einsetzt
Abschnitt betitelt „Wann du sie NICHT einsetzt“Das Registry teilen
Abschnitt betitelt „Das Registry teilen“Um denselben Lease über mehrere InMemoryLease-Instanzen innerhalb
eines Prozesses zu nutzen, müssen sie das Registry teilen:
import { InMemoryLeaseRegistry } from 'actor-ts/coordination';
const registry = new InMemoryLeaseRegistry();
const leaseA = new InMemoryLease({ name: 'singleton-x', owner: 'node-a', ttlMs: 30_000, registry,});
const leaseB = new InMemoryLease({ name: 'singleton-x', // gleicher Name owner: 'node-b', ttlMs: 30_000, registry, // gleiches Registry → schließen sich aus});
await leaseA.acquire(); // → trueawait leaseB.acquire(); // → false (leaseA hält ihn)Das ist das MultiNodeSpec-Muster — jeder simulierte Node
bekommt ein InMemoryLease gegen ein gemeinsames Registry, und
sie kämpfen um den Lease, wie es echte verteilte Peers tun
würden.
Ohne explizites registry bekommt jedes InMemoryLease sein
eigenes privates Registry — effektiv kein gegenseitiger
Ausschluss.
Verhaltensdetails
Abschnitt betitelt „Verhaltensdetails“Die Implementierung:
acquire()CAS-t den Registry-Slot atomar. Gibttruezurück, wenn sie ihn beansprucht hat;false, wenn ein anderer Owner ihn hält.- TTL-Ablauf — wenn der Halter nicht innerhalb von
ttlMsrenewt, gibt das Registry automatisch frei (eine setTimeout-getriebene Bereinigung). onLostfeuert, wenn ein anderer Halter übernimmt (via TTL-Ablauf-Mechanismus) oder wenn das Registry forciert geleert wird.- Renewal läuft auf einem
setIntervalzumrenewalIntervalMs(Defaultttl / 3).
Für deterministische Tests willst du vielleicht einen
ManualScheduler in das Registry
injizieren — das InMemoryLease des Frameworks nutzt aber
aktuell echte Timer. Für sehr-deterministische
Lease-Timing-Tests mocke Date.now() und manipuliere das
Registry direkt.
Beispiel: ein Singleton-Test
Abschnitt betitelt „Beispiel: ein Singleton-Test“import { describe, it, expect } from 'bun:test';import { TestKit, InMemoryLease, InMemoryLeaseRegistry } from 'actor-ts/testkit';import { ClusterSingletonManager, Props } from 'actor-ts';
describe('SingletonManager mit Lease', () => { it('nur ein Halter spawnt den Singleton', async () => { const tk1 = TestKit.create('node-1'); const tk2 = TestKit.create('node-2'); const registry = new InMemoryLeaseRegistry();
const lease1 = new InMemoryLease({ name: 'singleton', owner: 'n1', ttlMs: 30_000, registry, }); const lease2 = new InMemoryLease({ name: 'singleton', owner: 'n2', ttlMs: 30_000, registry, });
// (Cluster-Verdrahtung ausgelassen)
tk1.system.spawn( ClusterSingletonManager.props({ cluster: cluster1, typeName: 's', singletonProps: ..., lease: lease1, }), 'singleton-manager-s', );
tk2.system.spawn( ClusterSingletonManager.props({ cluster: cluster2, typeName: 's', singletonProps: ..., lease: lease2, }), 'singleton-manager-s', );
// Nur einer sollte je das Singleton-Actor-Child haben. // ... per Probes asserten ... });});Diese Art Test verifiziert die Lease-Integration, ohne von einer echten K8s-API abzuhängen.
Wohin als Nächstes
Abschnitt betitelt „Wohin als Nächstes“- Koordination im Überblick — das Gesamtbild.
- Lease-API — der Vertrag,
den
InMemoryLeaseimplementiert. - KubernetesLease — die Produktions-Alternative.
- MultiNodeSpec — das Multi-Node-Test-Harness, das dazu passt.