Counted Semaphore for Resource Limits

Limit how many callers may hold a resource at once with a counted semaphore that queues waiters and releases permits fairly.

JavascriptResilience

Code

snippet
export function createSemaphore(permits) {
  let available = permits;
  const waiters = [];
  return {
    async acquire() {
      if (available > 0) {
        available--;
        return () => release();
      }
      await new Promise((resolve) => waiters.push(resolve));
      return () => release();
    },
  };
  function release() {
    const next = waiters.shift();
    if (next) next();
    else available++;
  }
}