Skip to content

Instantly share code, notes, and snippets.

@schickling
Created October 28, 2022 09:27
Show Gist options
  • Save schickling/448aa9587da28e903bf91b8f9570784b to your computer and use it in GitHub Desktop.
Save schickling/448aa9587da28e903bf91b8f9570784b to your computer and use it in GitHub Desktop.
import type { Effect as T } from '@effect-ts/core'
import { pipe } from '@effect-ts/core'
import * as STM from '@effect-ts/core/Effect/Transactional/STM'
import * as TRef from '@effect-ts/core/Effect/Transactional/TRef'
export * from '@effect-ts/core/Effect/Transactional/STM'
export class Gate {
constructor(readonly ref: TRef.TRef<boolean>) {}
open = pipe(TRef.getAndSet_(this.ref, true), STM.commit)
close = pipe(TRef.getAndSet_(this.ref, false), STM.commit)
waitForOpen: T.Effect<unknown, never, void> = pipe(
TRef.get(this.ref),
STM.chain((isOpen) => STM.check(isOpen)),
STM.commit,
)
waitForOpenAndThenClose: T.Effect<unknown, never, void> = pipe(
TRef.get(this.ref),
STM.chain((isOpen) => STM.check(isOpen)),
STM.chain(() => TRef.set_(this.ref, false)),
STM.commit,
)
waitForClose: T.Effect<unknown, never, void> = pipe(
TRef.get(this.ref),
STM.chain((isOpen) => STM.check(!isOpen)),
STM.commit,
)
}
export const makeGate = (initiallyOpen: boolean): T.Effect<unknown, never, Gate> =>
pipe(
TRef.make(initiallyOpen),
STM.map((ref) => new Gate(ref)),
STM.commit,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment