(self: TxReentrantLock): Effect.Effect<number>Acquires 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.
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)
console.log(count) // 1
yield* TxReentrantLock.releaseWrite(lock)
})export const const acquireWrite: (
self: TxReentrantLock
) => Effect.Effect<number>
Acquires 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.
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)
console.log(count) // 1
yield* TxReentrantLock.releaseWrite(lock)
})
acquireWrite = (self: TxReentrantLock(parameter) self: {
stateRef: TxRef.TxRef<LockState>;
toString: () => string;
toJSON: () => unknown;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self: TxReentrantLock): import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<number> =>
import EffectEffect.withFiber((fiber: Fiber<unknown, unknown>(parameter) fiber: {
id: number;
currentOpCount: number;
getRef: <A>(ref: Context.Reference<A>) => A;
context: Context.Context<never>;
setContext: (context: Context.Context<never>) => void;
currentScheduler: Scheduler;
currentDispatcher: SchedulerDispatcher;
currentSpan: AnySpan | undefined;
currentLogLevel: LogLevel;
minimumLogLevel: LogLevel;
currentStackFrame: StackFrame | undefined;
maxOpsBeforeYield: number;
currentPreventYield: boolean;
addObserver: (cb: (exit: Exit<A, E>) => void) => () => void;
interruptUnsafe: (fiberId?: number | undefined, annotations?: Context.Context<never> | undefined) => void;
pollUnsafe: () => Exit<A, E> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
fiber) =>
import EffectEffect.gen(function*() {
const const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state = yield* import TxRefTxRef.const get: <A>(
self: TxRef<A>
) => Effect.Effect<A>
Reads the current value of the TxRef.
When to use
Use to read the current value of a TxRef.
Example (Reading transactional references)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(42)
// Read the value within a transaction
const value = yield* Effect.tx(
TxRef.get(counter)
)
console.log(value) // 42
})
get(self: TxReentrantLock(parameter) self: {
stateRef: TxRef.TxRef<LockState>;
toString: () => string;
toJSON: () => unknown;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.TxReentrantLock.stateRef: TxRef.TxRef<LockState>(property) TxReentrantLock.stateRef: {
version: number;
pending: Map<unknown, () => void>;
value: A;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
stateRef)
const const fiberId: anyfiberId = fiber: Fiber<unknown, unknown>(parameter) fiber: {
id: number;
currentOpCount: number;
getRef: <A>(ref: Context.Reference<A>) => A;
context: Context.Context<never>;
setContext: (context: Context.Context<never>) => void;
currentScheduler: Scheduler;
currentDispatcher: SchedulerDispatcher;
currentSpan: AnySpan | undefined;
currentLogLevel: LogLevel;
minimumLogLevel: LogLevel;
currentStackFrame: StackFrame | undefined;
maxOpsBeforeYield: number;
currentPreventYield: boolean;
addObserver: (cb: (exit: Exit<A, E>) => void) => () => void;
interruptUnsafe: (fiberId?: number | undefined, annotations?: Context.Context<never> | undefined) => void;
pollUnsafe: () => Exit<A, E> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
fiber.id
// If another fiber holds the write lock, retry
if (import OptionOption.isSome(const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state.writer) && const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state.writer.value[0] !== const fiberId: anyfiberId) {
return yield* import EffectEffect.txRetry
}
// If other fibers hold read locks, retry
for (const [const readerId: anyreaderId] of const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state.readers) {
if (const readerId: anyreaderId !== const fiberId: anyfiberId && import OptionOption.getOrElse(import HashMapHashMap.get(const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state.readers, const readerId: anyreaderId), () => 0) > 0) {
return yield* import EffectEffect.txRetry
}
}
// Grant write lock
if (import OptionOption.isSome(const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state.writer)) {
// Reentrant: increment write count
const const newCount: anynewCount = const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state.writer.value[1] + 1
yield* import TxRefTxRef.const set: {
<A>(value: A): (
self: TxRef<A>
) => Effect.Effect<void>
<A>(
self: TxRef<A>,
value: A
): Effect.Effect<void>
}
set(self: TxReentrantLock(parameter) self: {
stateRef: TxRef.TxRef<LockState>;
toString: () => string;
toJSON: () => unknown;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.TxReentrantLock.stateRef: TxRef.TxRef<LockState>(property) TxReentrantLock.stateRef: {
version: number;
pending: Map<unknown, () => void>;
value: A;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
stateRef, {
...const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state,
writer: Option.Option<readonly [number, number]>writer: import OptionOption.some([const fiberId: anyfiberId, const newCount: anynewCount] as type const = readonly [any, any]const)
})
return const newCount: anynewCount
}
// First write lock acquisition
yield* import TxRefTxRef.const set: {
<A>(value: A): (
self: TxRef<A>
) => Effect.Effect<void>
<A>(
self: TxRef<A>,
value: A
): Effect.Effect<void>
}
set(self: TxReentrantLock(parameter) self: {
stateRef: TxRef.TxRef<LockState>;
toString: () => string;
toJSON: () => unknown;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.TxReentrantLock.stateRef: TxRef.TxRef<LockState>(property) TxReentrantLock.stateRef: {
version: number;
pending: Map<unknown, () => void>;
value: A;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
stateRef, {
...const state: anyconst state: {
readers: HashMap.HashMap<number, number>;
writer: Option.Option<readonly [fiberId: number, count: number]>;
}
state,
writer: Option.Option<readonly [number, 1]>writer: import OptionOption.some([const fiberId: anyfiberId, 1] as type const = readonly [any, 1]const)
})
return 1
}).pipe(import EffectEffect.tx)
)