Hyperlinkv0.8.0-beta.28

RcMap

RcMap.getconsteffect/RcMap.ts:326
<K>(key: K): <A, E>(
  self: RcMap<K, A, E>
) => Effect.Effect<A, E, Scope.Scope>
<K, A, E>(self: RcMap<K, A, E>, key: K): Effect.Effect<A, E, Scope.Scope>

Gets the resource for a key, acquiring it with the map's lookup function when the key is not already cached.

When to use

Use to acquire or retain the resource for a key within the current scope.

Details

The resource's reference count is incremented for the current Scope, and a release finalizer is added to that scope. When the current scope closes, the reference is released; the resource is closed when the last reference is released, subject to the map's idle time-to-live setting.

Example (Acquiring a resource)

import { Effect, RcMap } from "effect"

Effect.gen(function*() {
  const map = yield* RcMap.make({
    lookup: (key: string) =>
      Effect.acquireRelease(
        Effect.succeed(`Resource: ${key}`),
        () => Effect.log(`Released ${key}`)
      )
  })

  // Get a resource - it will be acquired on first access
  const resource = yield* RcMap.get(map, "database")
  console.log(resource) // "Resource: database"
}).pipe(Effect.scoped)
combinatorsmakeinvalidate
Source effect/RcMap.ts:32649 lines
export const get: {
  <K>(key: K): <A, E>(self: RcMap<K, A, E>) => Effect.Effect<A, E, Scope.Scope>
  <K, A, E>(self: RcMap<K, A, E>, key: K): Effect.Effect<A, E, Scope.Scope>
} = dual(
  2,
  <K, A, E>(self: RcMap<K, A, E>, key: K): Effect.Effect<A, E, Scope.Scope> =>
    Effect.uninterruptibleMask((restore) => {
      if (self.state._tag === "Closed") {
        return Effect.interrupt
      }
      const state = self.state
      const parent = Fiber.getCurrent()!
      const o = MutableHashMap.get(state.map, key)
      let entry: State.Entry<A, E>
      if (o._tag === "Some") {
        entry = o.value
        entry.refCount++
      } else if (Number.isFinite(self.capacity) && MutableHashMap.size(self.state.map) >= self.capacity) {
        return Effect.fail(
          new Cause.ExceededCapacityError(`RcMap attempted to exceed capacity of ${self.capacity}`)
        ) as Effect.Effect<never>
      } else {
        entry = {
          deferred: Deferred.makeUnsafe(),
          scope: Scope.makeUnsafe(),
          idleTimeToLive: self.idleTimeToLive(key),
          finalizer: undefined as any,
          fiber: undefined,
          expiresAt: 0,
          refCount: 1
        }
        ;(entry as any).finalizer = release(self, key, entry)
        MutableHashMap.set(state.map, key, entry)
        const context = new Map(self.context.mapUnsafe)
        parent.context.mapUnsafe.forEach((value, key) => {
          context.set(key, value)
        })
        context.set(Scope.Scope.key, entry.scope)
        self.lookup(key).pipe(
          Effect.runForkWith(Context.makeUnsafe(context)),
          Fiber.runIn(entry.scope)
        ).addObserver((exit) => Deferred.doneUnsafe(entry.deferred, exit))
      }
      const scope = Context.getUnsafe(parent.context, Scope.Scope)
      return Scope.addFinalizer(scope, entry.finalizer).pipe(
        Effect.andThen(restore(Deferred.await(entry.deferred)))
      )
    })
)
Referenced by 3 symbols