happy-rusty
    Preparing search index...

    Interface Semaphore

    A counting semaphore for limiting async concurrency.

    Allows up to capacity concurrent operations. Each acquire() consumes one permit; each release() returns one. When the limit is reached, acquire() waits for a permit to be released. Waiters are served in FIFO order.

    Unlike Mutex<T>, Semaphore does not protect a value — it is a pure concurrency counter. For exclusive access to a value, use Mutex<T>.

    1.10.0

    // Limit concurrent fetch to 10
    const sem = Semaphore(10);

    async function niceFetch(url: string): Promise<Response> {
    return sem.withPermit(() => fetch(url));
    }

    await Promise.all(urls.map(niceFetch));
    // Database connection pool with 5 connections
    const pool = Semaphore(5);

    async function query(sql: string): Promise<Row[]> {
    return pool.withPermit(async () => {
    const conn = await getConnection();
    try {
    return await conn.query(sql);
    } finally {
    releaseConnection(conn);
    }
    });
    }
    interface Semaphore {
        "[toStringTag]": "Semaphore";
        capacity: number;
        acquire(): Promise<SemaphorePermit>;
        availablePermits(): number;
        toString(): string;
        tryAcquire(): Option<SemaphorePermit>;
        withPermit<U>(fn: () => U | PromiseLike<U>): Promise<Awaited<U>>;
    }
    Index

    Properties

    "[toStringTag]": "Semaphore"

    The well-known symbol Symbol.toStringTag used by Object.prototype.toString(). Returns 'Semaphore' so that Object.prototype.toString.call(sem) produces '[object Semaphore]'.

    capacity: number

    The maximum number of permits (concurrency limit), set at construction.

    const sem = Semaphore(5);
    console.log(sem.capacity); // 5

    Methods

    • Acquires a permit, waiting if necessary until one is available.

      Important: Always release the permit in a finally block to avoid leaking permits on exceptions. Prefer withPermit for automatic release.

      Returns Promise<SemaphorePermit>

      A promise that resolves to a SemaphorePermit.

      const sem = Semaphore(2);
      const permit = await sem.acquire();
      try {
      await doWork();
      } finally {
      permit.release();
      }
    • Returns the number of permits currently available (not acquired).

      Note: this is a snapshot and may change immediately after the call as other async operations acquire/release permits.

      Returns number

      const sem = Semaphore(3);
      console.log(sem.availablePermits()); // 3
      const permit = await sem.acquire();
      console.log(sem.availablePermits()); // 2
      permit.release();
      console.log(sem.availablePermits()); // 3
    • Custom toString implementation showing available/capacity.

      Returns string

      const sem = Semaphore(3);
      console.log(sem.toString()); // 'Semaphore(3/3)'
      const permit = await sem.acquire();
      console.log(sem.toString()); // 'Semaphore(2/3)'
      permit.release();
      console.log(sem.toString()); // 'Semaphore(3/3)'
    • Attempts to acquire a permit without waiting.

      Returns Option<SemaphorePermit>

      Some(permit) if a permit was available, None if the limit has been reached.

      const sem = Semaphore(1);
      const maybePermit = sem.tryAcquire();
      if (maybePermit.isSome()) {
      const permit = maybePermit.unwrap();
      try {
      await doWork();
      } finally {
      permit.release();
      }
      } else {
      console.log('At capacity, skipping');
      }
    • Acquires a permit, executing the callback with at most capacity concurrent callers. The permit is automatically released when the callback settles (success or rejection).

      This is the recommended way to use the semaphore as it avoids leaking permits on exceptions.

      Type Parameters

      • U

        The return type of the callback.

      Parameters

      • fn: () => U | PromiseLike<U>

        The callback to execute while holding a permit.

      Returns Promise<Awaited<U>>

      A promise that resolves to the callback's return value.

      const sem = Semaphore(3);
      const result = await sem.withPermit(async () => {
      return await fetch('/api/data');
      });