Effect CommunityEC
Effect Communityβ€’2y agoβ€’
144 replies
Patrick Roza

Implementing Semaphore Control with Time-bound Release in TypeScript

does this look sane?
/**
 * Executes the specified effect, acquiring the specified number of permits
 * immediately before the effect begins execution and releasing them
 * after specified delay, whether by success, failure, or interruption.
 */
export function withPermitsOrDuration(permits: number, duration: Duration.Duration) {
  return (self: Semaphore): <R, E, A>(effect: Effect<A, E, R>) => Effect<A, E, R> => {
    return (effect) =>
      Effect.uninterruptibleMask(
        (restore) =>
          restore(self.take(permits))
            .andThen(
              Effect.ensuring(
                restore(effect.tap(Effect.sleep(duration))),
                self.release(permits)
              )
            )
      )
  }
}

  const rateLimit = yield* $(
    Effect
      .makeSemaphore(4)
      .pipe(Effect.andThen(withPermitsOrDuration(1, Duration.seconds(1))))
  )

i'm experiencing deadlocks with this and nested batching.
Was this page helpful?