A scoped version of Retainer that coordinates retains and drains independently for each scope.
A scope consists of one or more values that identify a resource or context to retain or drain. Draining one scope does not affect other scopes.
import {ScopedRetainer, sleep} from "lifecycle-utils";const retainer = new ScopedRetainer<[clientId: string]>();async function useClient(clientId: string) { using handle = retainer.tryRetain([clientId], () => new Error(clientId + " is draining")); console.log("using " + clientId); await sleep(1000); console.log("done using " + clientId);}async function drainClient(clientId: string) { console.log("awaiting drain for " + clientId); using drain = await retainer.acquireDrain([clientId]); // no retained usages for this client are active while the drain handle is held console.log("drain started for " + clientId); await sleep(1000);}const usePromise = useClient("client1");const drainPromise = drainClient("client1");await useClient("client1").catch(console.log);await useClient("client2");await Promise.all([usePromise, drainPromise]);// using client1// awaiting drain for client1// Error: client1 is draining// using client2// done using client1// drain started for client1// done using client2 Copy
import {ScopedRetainer, sleep} from "lifecycle-utils";const retainer = new ScopedRetainer<[clientId: string]>();async function useClient(clientId: string) { using handle = retainer.tryRetain([clientId], () => new Error(clientId + " is draining")); console.log("using " + clientId); await sleep(1000); console.log("done using " + clientId);}async function drainClient(clientId: string) { console.log("awaiting drain for " + clientId); using drain = await retainer.acquireDrain([clientId]); // no retained usages for this client are active while the drain handle is held console.log("drain started for " + clientId); await sleep(1000);}const usePromise = useClient("client1");const drainPromise = drainClient("client1");await useClient("client1").catch(console.log);await useClient("client2");await Promise.all([usePromise, drainPromise]);// using client1// awaiting drain for client1// Error: client1 is draining// using client2// done using client1// drain started for client1// done using client2
A scoped version of Retainer.acquireDrain.
the scope to acquire the drain for
Optional
an optional abort signal to abort the drain acquisition
Get the number of active retains for a given scope
scope
A scoped version of Retainer.tryRetain
the scope to create the retain for
an error to be thrown if a drain is active or pending for the scope. When a function is provided, its result is thrown instead.
A scoped version of Retainer that coordinates retains and drains independently for each scope.
A scope consists of one or more values that identify a resource or context to retain or drain. Draining one scope does not affect other scopes.
Example