MCPcopy Index your code
hub / github.com/Effect-TS/effect / ResourceMap

Class ResourceMap

packages/cluster/src/internal/resourceMap.ts:10–89  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

8import * as Scope from "effect/Scope"
9
10export class ResourceMap<K, A, E> {
11 constructor(
12 readonly lookup: (key: K, scope: Scope.Scope) => Effect.Effect<A, E>,
13 readonly entries: MutableHashMap.MutableHashMap<K, {
14 readonly scope: Scope.CloseableScope
15 readonly deferred: Deferred.Deferred<A, E>
16 }>,
17 readonly isClosed: MutableRef.MutableRef<boolean>
18 ) {}
19
20 static make = Effect.fnUntraced(function*<K, A, E, R>(lookup: (key: K) => Effect.Effect<A, E, R>) {
21 const scope = yield* Effect.scope
22 const context = yield* Effect.context<R>()
23 const isClosed = MutableRef.make(false)
24
25 const entries = MutableHashMap.empty<K, {
26 scope: Scope.CloseableScope
27 deferred: Deferred.Deferred<A, E>
28 }>()
29
30 yield* Scope.addFinalizerExit(
31 scope,
32 (exit) => {
33 MutableRef.set(isClosed, true)
34 return Effect.forEach(entries, ([key, { scope }]) => {
35 MutableHashMap.remove(entries, key)
36 return Effect.exit(Scope.close(scope, exit))
37 }, { concurrency: "unbounded", discard: true })
38 }
39 )
40
41 return new ResourceMap(
42 (key, scope) => Effect.provide(lookup(key), Context.add(context, Scope.Scope, scope)),
43 entries,
44 isClosed
45 )
46 })
47
48 get(key: K): Effect.Effect<A, E> {
49 return Effect.withFiberRuntime((fiber) => {
50 if (MutableRef.get(this.isClosed)) {
51 return Effect.interrupt
52 }
53 const existing = MutableHashMap.get(this.entries, key)
54 if (Option.isSome(existing)) {
55 return Deferred.await(existing.value.deferred)
56 }
57 const scope = Effect.runSync(Scope.make())
58 const deferred = Deferred.unsafeMake<A, E>(fiber.id())
59 MutableHashMap.set(this.entries, key, { scope, deferred })
60 return Effect.onExit(this.lookup(key, scope), (exit) => {
61 if (exit._tag === "Success") {
62 return Deferred.done(deferred, exit)
63 }
64 MutableHashMap.remove(this.entries, key)
65 return Deferred.done(deferred, exit)
66 })
67 })

Callers

nothing calls this directly

Calls 8

lookupFunction · 0.85
contextMethod · 0.65
makeMethod · 0.65
setMethod · 0.65
removeMethod · 0.65
closeMethod · 0.65
provideMethod · 0.65
addMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…