TxReentrantLock
Coordinates shared access inside transactions with read and write locks.
A TxReentrantLock lets many fibers hold read locks at the same time, or one
fiber hold a write lock for exclusive access. Lock ownership is tracked by
fiber, so a fiber that already holds the lock can acquire it again and later
release each acquisition. Attempts that cannot proceed retry transactionally
until the lock becomes available. This module includes manual, scoped, and
wrapper-style operations for read and write locking.
Constructors
Creates a new TxReentrantLock.
Signature
declare function make(): Effect<TxReentrantLock>Example Creating a reentrant lock
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.locked(lock)})
await Effect.runPromise(program) // => falseGetters
Checks whether the lock is held by any fiber (read or write).
Signature
declare function locked(self: TxReentrantLock): Effect<boolean>Example Checking whether a lock is held
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.locked(lock)})
await Effect.runPromise(program) // => falseChecks whether any fiber holds a read lock.
Signature
declare function readLocked(self: TxReentrantLock): Effect<boolean>Example Checking whether a read lock is held
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.readLocked(lock)})
await Effect.runPromise(program) // => falseReturns the total number of read locks held across all fibers.
Signature
declare function readLocks(self: TxReentrantLock): Effect<number>Example Counting read locks
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() yield* TxReentrantLock.acquireRead(lock) const count = yield* TxReentrantLock.readLocks(lock) yield* TxReentrantLock.releaseRead(lock) return count})
await Effect.runPromise(program) // => 1Checks whether any fiber holds a write lock.
Signature
declare function writeLocked(self: TxReentrantLock): Effect<boolean>Example Checking whether a write lock is held
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.writeLocked(lock)})
await Effect.runPromise(program) // => falseReturns the number of write locks held (0 or the reentrant count).
Signature
declare function writeLocks(self: TxReentrantLock): Effect<number>Example Counting write locks
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.writeLocks(lock)})
await Effect.runPromise(program) // => 0Guards
Checks whether the given value is a TxReentrantLock.
Signature
declare function isTxReentrantLock(u: unknown): u is TxReentrantLockExample Checking for TxReentrantLock values
import { TxReentrantLock } from "effect"
const someValue: unknown = {}
TxReentrantLock.isTxReentrantLock(someValue) // => falseModels
TxReentrantLock
interfaceA TxReentrantLock provides a transactional read/write lock with reentrant semantics. Multiple readers can hold the lock concurrently, or a single writer can hold exclusive access. A fiber holding the write lock may acquire additional read/write locks (reentrancy).
Signature
interface TxReentrantLock extends Inspectable, Pipeable { readonly "~effect/TxReentrantLock": "~effect/TxReentrantLock";}Example Using read and write locks
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make()
// Multiple readers can proceed concurrently const read = yield* TxReentrantLock.withReadLock(lock, Effect.succeed("reading"))
// Writer gets exclusive access const write = yield* TxReentrantLock.withWriteLock(lock, Effect.succeed("writing")) return [read, write]})
await Effect.runPromise(program) // => ["reading", "writing"]Mutations
Acquires a read lock. Blocks if another fiber holds the write lock. If the current fiber already holds the write lock, the read lock is granted (reentrancy). Returns the current number of read locks held by this fiber.
Signature
declare function acquireRead(self: TxReentrantLock): Effect<number>Example Acquiring a read lock
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() const count = yield* TxReentrantLock.acquireRead(lock) yield* TxReentrantLock.releaseRead(lock) return count})
await Effect.runPromise(program) // => 1Acquires the write lock for the current fiber.
When to use
Use to enter an exclusive section manually when withWriteLock is not the
right shape.
Details
Blocks if any other fiber holds a read or write lock. If the current fiber already holds the write lock, the count is incremented. If the current fiber holds a read lock, the write lock is granted as an upgrade.
Returns the current number of write locks held by this fiber.
Signature
declare function acquireWrite(self: TxReentrantLock): Effect<number>Example Acquiring a write lock
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() const count = yield* TxReentrantLock.acquireWrite(lock) yield* TxReentrantLock.releaseWrite(lock) return count})
await Effect.runPromise(program) // => 1Acquires a read lock for the duration of the scope. The lock is automatically released when the scope closes.
Signature
declare function readLock(self: TxReentrantLock): Effect<number, never, Scope>Example Holding a scoped read lock
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make()
const held = yield* Effect.scoped( Effect.gen(function*() { yield* TxReentrantLock.readLock(lock) // read lock is held for the duration of the scope return yield* TxReentrantLock.readLocks(lock) }) ) // read lock is released return [held, yield* TxReentrantLock.readLocks(lock)]})
await Effect.runPromise(program) // => [1, 0]Releases one read lock held by the current fiber.
When to use
Use to leave a manually acquired read lock.
Details
Returns the remaining number of read locks held by this fiber.
Signature
declare function releaseRead(self: TxReentrantLock): Effect<number>Releases one write lock held by the current fiber.
When to use
Use to leave a manually acquired write lock.
Details
Returns the remaining number of write locks held by this fiber.
Signature
declare function releaseWrite(self: TxReentrantLock): Effect<number>Runs an effect while holding a write lock.
When to use
Use when you need to run an effect with exclusive write access through a
TxReentrantLock and prefer the concise lock helper.
Signature
declare const withLock: { <A, E, R>(effect: Effect<A, E, R>): (self: TxReentrantLock) => Effect<A, E, R>; <A, E, R>(self: TxReentrantLock, effect: Effect<A, E, R>): Effect<A, E, R>;}Example Running an effect with exclusive access
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.withLock( lock, Effect.succeed("exclusive operation") )})
await Effect.runPromise(program) // => "exclusive operation"Runs the provided effect while holding a read lock. The lock is automatically released after the effect completes, fails, or is interrupted.
Signature
declare const withReadLock: { <A, E, R>(effect: Effect<A, E, R>): (self: TxReentrantLock) => Effect<A, E, R>; <A, E, R>(self: TxReentrantLock, effect: Effect<A, E, R>): Effect<A, E, R>;}Example Running an effect with a read lock
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.withReadLock( lock, Effect.succeed("read data") )})
await Effect.runPromise(program) // => "read data"Runs the provided effect while holding a write lock. The lock is automatically released after the effect completes, fails, or is interrupted.
Signature
declare const withWriteLock: { <A, E, R>(effect: Effect<A, E, R>): (self: TxReentrantLock) => Effect<A, E, R>; <A, E, R>(self: TxReentrantLock, effect: Effect<A, E, R>): Effect<A, E, R>;}Example Running an effect with a write lock
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make() return yield* TxReentrantLock.withWriteLock( lock, Effect.succeed("wrote data") )})
await Effect.runPromise(program) // => "wrote data"Acquires a write lock for the duration of the scope. The lock is automatically released when the scope closes.
Signature
declare function writeLock(self: TxReentrantLock): Effect<number, never, Scope>Example Holding a scoped write lock
import { Effect, TxReentrantLock } from "effect"
const program = Effect.gen(function*() { const lock = yield* TxReentrantLock.make()
const held = yield* Effect.scoped( Effect.gen(function*() { yield* TxReentrantLock.writeLock(lock) // write lock is held for the duration of the scope return yield* TxReentrantLock.writeLocks(lock) }) ) // write lock is released return [held, yield* TxReentrantLock.writeLocks(lock)]})
await Effect.runPromise(program) // => [1, 0]