Hyperlinkv0.8.0-beta.28

TxSemaphore

TxSemaphore.withPermitconsteffect/TxSemaphore.ts:531
(self: TxSemaphore): <A, E, R>(
  effect: Effect.Effect<A, E, R>
) => Effect.Effect<A, E, R>
<A, E, R>(
  self: TxSemaphore,
  effect: Effect.Effect<A, E, R>
): Effect.Effect<A, E, R>

Executes an effect with a single permit from the semaphore. The permit is automatically acquired before execution and released afterwards, even if the effect fails or is interrupted.

When to use

Use to run an effect while automatically acquiring and releasing one transactional permit.

Details

The permit acquisition and release operations use atomic semantics to ensure proper resource management with Effect's scoped operations.

Example (Running an effect with a permit)

import { Console, Effect, TxSemaphore } from "effect"

const program = Effect.gen(function*() {
  const semaphore = yield* TxSemaphore.make(2)

  // Execute database operation with automatic permit management
  const result = yield* TxSemaphore.withPermit(
    semaphore,
    Effect.gen(function*() {
      yield* Console.log("Permit acquired, accessing database...")
      yield* Effect.sleep("100 millis") // Simulate database work
      yield* Console.log("Database operation complete")
      return "query result"
    })
  )

  yield* Console.log(`Result: ${result}`)
  // Permit is automatically released here
})
export const withPermit: {
  (self: TxSemaphore): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
  <A, E, R>(self: TxSemaphore, effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>
} = ((...args: Array<any>) => {
  if (args.length === 1) {
    const [self] = args
    return (effect: Effect.Effect<any, any, any>) =>
      Effect.acquireUseRelease(
        acquire(self),
        () => effect,
        () => release(self)
      )
  }
  const [self, effect] = args
  return Effect.acquireUseRelease(
    acquire(self),
    () => effect,
    () => release(self)
  )
}) as any