Created
February 9, 2024 00:09
-
-
Save tim-smart/fd87d99ab23e242b5c1ebf8f7a58ba1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Duration, Scope } from "effect" | |
import { Effect, SynchronizedRef } from "effect" | |
export const make = (limit: number, window: Duration.DurationInput): Effect.Effect< | |
<A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>, | |
never, | |
Scope.Scope | |
> => | |
Effect.gen(function*(_) { | |
const scope = yield* _(Effect.scope) | |
const semaphore = yield* _(Effect.makeSemaphore(limit)) | |
const ref = yield* _(SynchronizedRef.make(false)) | |
const reset = SynchronizedRef.updateEffect(ref, (running) => | |
running ? Effect.succeed(true) : Effect.sleep(window).pipe( | |
Effect.zipRight(SynchronizedRef.set(ref, false)), | |
Effect.zipRight(semaphore.releaseAll), | |
Effect.forkIn(scope), | |
Effect.interruptible, | |
Effect.as(true) | |
)) | |
const take = Effect.zipRight(semaphore.take(1), reset) | |
return (effect) => | |
Effect.zipRight(take, effect) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment