Hyperlinkv0.8.0-beta.28

Cache

Cache.getOptionconsteffect/Cache.ts:551
<Key, A>(key: Key): <E, R>(
  self: Cache<Key, A, E, R>
) => Effect.Effect<Option.Option<A>, E>
<Key, A, E, R>(self: Cache<Key, A, E, R>, key: Key): Effect.Effect<
  Option.Option<A>,
  E
>

Reads an existing cache entry without invoking the lookup function.

Details

Returns Option.none() when the key is missing or expired, and Option.some when a cached lookup has succeeded. If the entry is still pending, waits for it to complete. If the cached or pending lookup fails, this effect fails with the same error.

Example (Reading cached values without lookup)

import { Cache, Effect } from "effect"

const program = Effect.gen(function*() {
  const cache = yield* Cache.make({
    capacity: 10,
    lookup: (key: string) => Effect.succeed(key.length)
  })

  // No value in cache yet - returns None without lookup
  const empty = yield* Cache.getOption(cache, "hello")
  console.log(empty) // Option.none()

  // Populate cache using get
  yield* Cache.get(cache, "hello")

  // Now getOption returns the cached value
  const cached = yield* Cache.getOption(cache, "hello")
  console.log(cached) // Option.some(5)

  return { empty, cached }
})

Example (Skipping expired entries)

import { Cache, Effect } from "effect"
import { TestClock } from "effect/testing"

// Expired entries return None
const program = Effect.gen(function*() {
  const cache = yield* Cache.make({
    capacity: 10,
    lookup: (key: string) => Effect.succeed(key.length),
    timeToLive: "1 hour"
  })

  // Add value to cache
  yield* Cache.get(cache, "hello")

  // Value exists before expiration
  const beforeExpiry = yield* Cache.getOption(cache, "hello")
  console.log(beforeExpiry) // Option.some(5)

  // Simulate time passing
  yield* TestClock.adjust("2 hours")

  // Value expired - returns None
  const afterExpiry = yield* Cache.getOption(cache, "hello")
  console.log(afterExpiry) // Option.none()
})

Example (Waiting for pending lookups)

import { Cache, Deferred, Effect, Fiber } from "effect"

// Waits for ongoing computation to complete
const program = Effect.gen(function*() {
  const deferred = yield* Deferred.make<void>()
  const cache = yield* Cache.make({
    capacity: 10,
    lookup: (_key: string) => Deferred.await(deferred).pipe(Effect.as(42))
  })

  // Start lookup in background
  const getFiber = yield* Effect.forkChild(Cache.get(cache, "key"))

  // getOption waits for ongoing computation
  const optionFiber = yield* Effect.forkChild(Cache.getOption(cache, "key"))

  // Complete the computation
  yield* Deferred.succeed(deferred, void 0)

  const result = yield* Fiber.join(optionFiber)
  console.log(result) // Option.some(42)

  const value = yield* Fiber.join(getFiber)
  console.log(value) // 42
})
combinators
Source effect/Cache.ts:55111 lines
export const getOption: {
  <Key, A>(key: Key): <E, R>(self: Cache<Key, A, E, R>) => Effect.Effect<Option.Option<A>, E>
  <Key, A, E, R>(self: Cache<Key, A, E, R>, key: Key): Effect.Effect<Option.Option<A>, E>
} = dual(
  2,
  <Key, A, E, R>(self: Cache<Key, A, E, R>, key: Key): Effect.Effect<Option.Option<A>, E> =>
    core.withFiber((fiber) => {
      const entry = getImpl(self, key, fiber)
      return entry ? effect.asSome(Deferred.await(entry.deferred)) : effect.succeedNone
    })
)