TxDeferred
Transactional deferred values for coordinating Effect transactions.
A TxDeferred<A, E> is a write-once cell whose completion is a
Result<A, E> stored in transactional state. Readers can wait for the value
from inside a transaction: while the cell is empty the transaction retries,
and when another transaction completes the deferred the waiting transaction
can resume with either the success value or the typed failure.
Constructors
Creates a new empty TxDeferred.
When to use
Use to create a transactional deferred that can be completed exactly once.
Signature
declare function make<A, E = never>(): Effect<TxDeferred<A, E>>Example
(Creating a transactional deferred)
import { Effect, Option, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<string, Error>() return yield* TxDeferred.poll(deferred)})
await Effect.runPromise(program) // => Option.none()Getters
Reads the deferred value. Retries the transaction if the deferred has not been completed yet.
Signature
declare function await<A, E>(self: TxDeferred<A, E>): Effect<A, E>Example
(Awaiting a deferred value)
import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<number>() yield* TxDeferred.succeed(deferred, 42) return yield* TxDeferred.await(deferred)})
await Effect.runPromise(program) // => 42Reads the current state of the deferred without retrying. Returns None if
not yet completed.
When to use
Use to inspect a TxDeferred without retrying when it is not completed yet.
Signature
declare function poll<A, E>(self: TxDeferred<A, E>): Effect<Option<Result<A, E>>>Example
(Polling a deferred)
import { Effect, Option, Result, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<number>() const before = yield* TxDeferred.poll(deferred)
yield* TxDeferred.succeed(deferred, 42) const after = yield* TxDeferred.poll(deferred) return [before, after]})
await Effect.runPromise(program) // => [Option.none(), Option.some(Result.succeed(42))]Guards
isTxDeferred
Determines if the provided value is a TxDeferred.
When to use
Use to narrow an unknown value before treating it as a transactional deferred.
Signature
declare function isTxDeferred(u: unknown): u is TxDeferred<unknown, unknown>Example
(Checking transactional deferreds)
import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<number>() return [TxDeferred.isTxDeferred(deferred), TxDeferred.isTxDeferred("not a deferred")]})
await Effect.runPromise(program) // => [true, false]Models
TxDeferred interface
A transactional deferred is a write-once cell readable within transactions.
Readers block (retry the transaction) until a value is committed, and writers
succeed only on the first call; subsequent writes return false.
When to use
Use to coordinate transaction-local readers and one-time completion with a success or failure result.
Signature
interface TxDeferred<in out A, in out E = never> extends Inspectable, Pipeable { readonly "~effect/transactions/TxDeferred": "~effect/transactions/TxDeferred"; readonly ref: TxRef<Option<Result<A, E>>>;}Example
(Completing a transactional deferred)
import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<number>()
// Complete the deferred const first = yield* TxDeferred.succeed(deferred, 42)
// Second write is a no-op const second = yield* TxDeferred.succeed(deferred, 99)
// Read the value const value = yield* TxDeferred.await(deferred) return [first, second, value]})
await Effect.runPromise(program) // => [true, false, 42]Mutations
Completes the deferred with a Result. Returns true if this was the first
completion, false if already completed.
When to use
Use to complete a TxDeferred with an already computed Result.
Signature
declare const done: { <A, E>(result: Result<A, E>): (self: TxDeferred<A, E>) => Effect<boolean>; <A, E>(self: TxDeferred<A, E>, result: Result<A, E>): Effect<boolean>;}Example
(Completing with a result)
import { Effect, Result, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<number, string>() const first = yield* TxDeferred.done(deferred, Result.succeed(42)) const second = yield* TxDeferred.done(deferred, Result.succeed(99)) return [first, second]})
await Effect.runPromise(program) // => [true, false]Completes the deferred with a failure. Returns true if this was the first
completion, false if already completed.
When to use
Use to complete a TxDeferred with a typed failure value.
Signature
declare const fail: { <E>(error: E): <A>(self: TxDeferred<A, E>) => Effect<boolean>; <A, E>(self: TxDeferred<A, E>, error: E): Effect<boolean>;}Example
(Completing with a failure)
import { Cause, Effect, Exit, Option, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<number, string>() const first = yield* TxDeferred.fail(deferred, "boom") const second = yield* TxDeferred.fail(deferred, "boom2") const exit = yield* Effect.exit(TxDeferred.await(deferred)) return [first, second, exit, Exit.getCause(exit)]})
await Effect.runPromise(program) // => [true, false, Exit.fail("boom"), Option.some(Cause.fail("boom"))]Completes the deferred with a success value. Returns true if this was the
first completion, false if already completed.
When to use
Use to complete a TxDeferred with a successful value.
Signature
declare const succeed: { <A>(value: A): <E>(self: TxDeferred<A, E>) => Effect<boolean>; <A, E>(self: TxDeferred<A, E>, value: A): Effect<boolean>;}Example
(Completing with a success value)
import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() { const deferred = yield* TxDeferred.make<number>() const first = yield* TxDeferred.succeed(deferred, 42) const second = yield* TxDeferred.succeed(deferred, 99) return [first, second]})
await Effect.runPromise(program) // => [true, false]