Implementing Semaphore Control with Time-bound Release in TypeScript
does this look sane?
i'm experiencing deadlocks with this and nested batching.
/**
* 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)
)
)
)
}
}/**
* 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))))
) const rateLimit = yield* $(
Effect
.makeSemaphore(4)
.pipe(Effect.andThen(withPermitsOrDuration(1, Duration.seconds(1))))
)i'm experiencing deadlocks with this and nested batching.
