Skip to content

Commit

Permalink
Latch implements Effect<void> with .await semantics (#3638)
Browse files Browse the repository at this point in the history
Co-authored-by: maksim.khramtsov <maksim.khramtsov@btsdigital.kz>
  • Loading branch information
2 people authored and gcanti committed Sep 24, 2024
1 parent 680377d commit 87dc1fa
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/early-poems-explode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": minor
---

`Latch` implements `Effect<void>` with `.await` semantic
3 changes: 2 additions & 1 deletion packages/effect/dtslint/Unify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export type ResourceUnify = Unify.Unify<
| Resource.Resource<any, any>
>

// $ExpectType 0 | Option<string | number> | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Fiber<"a" | 1, "b" | 2> | RuntimeFiber<"a" | 1, "b" | 2> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | ScopedRef<1> | ScopedRef<"a"> | Resource<1, 2> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | FiberRef<12> | FiberRef<"a2"> | Resource<"a", never> | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E">
// $ExpectType 0 | Option<string | number> | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Fiber<"a" | 1, "b" | 2> | RuntimeFiber<"a" | 1, "b" | 2> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | ScopedRef<1> | ScopedRef<"a"> | Resource<1, 2> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | FiberRef<12> | FiberRef<"a2"> | Resource<"a", never> | Latch | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E">
export type AllUnify = Unify.Unify<
| Either.Either<1, 0>
| Either.Either<"A", "E">
Expand Down Expand Up @@ -149,5 +149,6 @@ export type AllUnify = Unify.Unify<
| ScopedRef.ScopedRef<"a">
| Resource.Resource<1, 2>
| Resource.Resource<"a">
| Effect.Latch
| 0
>
22 changes: 21 additions & 1 deletion packages/effect/src/Effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5408,7 +5408,7 @@ export const makeSemaphore: (permits: number) => Effect<Semaphore> = circular.ma
* @category latch
* @since 3.8.0
*/
export interface Latch {
export interface Latch extends Effect<void> {
/** open the latch, releasing all fibers waiting on it */
readonly open: Effect<void>
/** release all fibers waiting on the latch, without opening it */
Expand All @@ -5419,6 +5419,26 @@ export interface Latch {
readonly close: Effect<void>
/** only run the given effect when the latch is open */
readonly whenOpen: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>

readonly [Unify.typeSymbol]?: unknown
readonly [Unify.unifySymbol]?: LatchUnify<this>
readonly [Unify.ignoreSymbol]?: LatchUnifyIgnore
}

/**
* @category models
* @since 3.8.0
*/
export interface LatchUnify<A extends { [Unify.typeSymbol]?: any }> extends EffectUnify<A> {
Latch?: () => Latch
}

/**
* @category models
* @since 3.8.0
*/
export interface LatchUnifyIgnore extends EffectUnifyIgnore {
Effect?: true
}

/**
Expand Down
10 changes: 8 additions & 2 deletions packages/effect/src/internal/effect/circular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,16 @@ export const unsafeMakeSemaphore = (permits: number): Semaphore => new Semaphore
/** @internal */
export const makeSemaphore = (permits: number) => core.sync(() => unsafeMakeSemaphore(permits))

class Latch implements Effect.Latch {
class Latch extends Effectable.Class<void> implements Effect.Latch {
waiters: Array<(_: Effect.Effect<void>) => void> = []
scheduled = false
constructor(private isOpen: boolean) {}
constructor(private isOpen: boolean) {
super()
}

commit() {
return this.await
}

private unsafeSchedule(fiber: Fiber.RuntimeFiber<void>) {
if (this.scheduled || this.waiters.length === 0) {
Expand Down
10 changes: 10 additions & 0 deletions packages/effect/test/Effect/latch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,14 @@ describe("Latch", () => {
yield* latch.release
assert.deepStrictEqual(yield* fiber.await, Exit.void)
}))

it.effect("subtype of Effect", () =>
Effect.gen(function*() {
const latch = yield* Effect.makeLatch()
const fiber = yield* Effect.fork(latch)

yield* latch.open

assert.deepStrictEqual(yield* fiber.await, Exit.void)
}))
})

0 comments on commit 87dc1fa

Please sign in to comment.