Skip to content

Commit

Permalink
Pool is subtype of Effect (#3674)
Browse files Browse the repository at this point in the history
Co-authored-by: maksim.khramtsov <maksim.khramtsov@btsdigital.kz>
Co-authored-by: Tim <hello@timsmart.co>
  • Loading branch information
3 people committed Sep 26, 2024
1 parent 952656b commit 5222099
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/lemon-worms-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": minor
---

`Pool` is now a subtype of `Effect`, equivalent to `Pool.get`
13 changes: 12 additions & 1 deletion packages/effect/dtslint/Unify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type * as FiberRef from "effect/FiberRef"
import type * as ManagedRuntime from "effect/ManagedRuntime"
import type * as Micro from "effect/Micro"
import type * as Option from "effect/Option"
import type * as Pool from "effect/Pool"
import type * as Queue from "effect/Queue"
import type * as RcRef from "effect/RcRef"
import type * as Ref from "effect/Ref"
Expand Down Expand Up @@ -116,6 +117,13 @@ export type DequeueUnify = Unify.Unify<
| Queue.Dequeue<1>
| Queue.Dequeue<"a">
>
// $ExpectType Pool<1, 2> | Pool<"a", "b" | "c">
export type PoolUnify = Unify.Unify<
| Pool.Pool<1, 2>
| Pool.Pool<"a", "b">
| Pool.Pool<"a", "c">
>

// $ExpectType ScopedRef<1> | ScopedRef<"a">
export type ScopedRefUnify = Unify.Unify<
| ScopedRef.ScopedRef<1>
Expand All @@ -130,7 +138,7 @@ export type ResourceUnify = Unify.Unify<
| Resource.Resource<any, any>
>

// $ExpectType 0 | Option<string | number> | Ref<1> | Ref<"a"> | SynchronizedRef<1> | SynchronizedRef<"a"> | SubscriptionRef<1> | SubscriptionRef<"a"> | RcRef<"a", "b"> | Deferred<"a", "b"> | FiberRef<1> | FiberRef<"a"> | ManagedRuntime<"a", "b"> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | ScopedRef<1> | ScopedRef<"a"> | Resource<"a", "b"> | RcRef<1, 0> | Deferred<1, 0> | Resource<1, 0> | Latch | ManagedRuntime<1, 0> | Fiber<"a" | 1, 0 | "b"> | RuntimeFiber<"a" | 1, 0 | "b"> | Either<"a" | 1, 0 | "b"> | Effect<"a" | 1, 0 | "b", "R" | "R1">
// $ExpectType 0 | Option<string | number> | Ref<1> | Ref<"a"> | SynchronizedRef<1> | SynchronizedRef<"a"> | SubscriptionRef<1> | SubscriptionRef<"a"> | RcRef<"a", "b"> | Deferred<"a", "b"> | FiberRef<1> | FiberRef<"a"> | ManagedRuntime<"a", "b"> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | Pool<1, 2> | Pool<"a", "b" | "c"> | ScopedRef<1> | ScopedRef<"a"> | Resource<"a", "b"> | RcRef<1, 0> | Deferred<1, 0> | Resource<1, 0> | Latch | ManagedRuntime<1, 0> | Fiber<"a" | 1, 0 | "b"> | RuntimeFiber<"a" | 1, 0 | "b"> | Either<"a" | 1, 0 | "b"> | Effect<"a" | 1, 0 | "b", "R" | "R1">
export type AllUnify = Unify.Unify<
| Either.Either<1, 0>
| Either.Either<"a", "b">
Expand Down Expand Up @@ -158,6 +166,9 @@ export type AllUnify = Unify.Unify<
| Queue.Queue<"a">
| Queue.Dequeue<1>
| Queue.Dequeue<"a">
| Pool.Pool<1, 2>
| Pool.Pool<"a", "b">
| Pool.Pool<"a", "c">
| ScopedRef.ScopedRef<1>
| ScopedRef.ScopedRef<"a">
| Resource.Resource<1, 0>
Expand Down
27 changes: 26 additions & 1 deletion packages/effect/src/Pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as internal from "./internal/pool.js"
import type { Pipeable } from "./Pipeable.js"
import type * as Scope from "./Scope.js"
import type * as Types from "./Types.js"
import type * as Unify from "./Unify.js"

/**
* @since 2.0.0
Expand All @@ -28,7 +29,7 @@ export type PoolTypeId = typeof PoolTypeId
* @since 2.0.0
* @category models
*/
export interface Pool<in out A, out E = never> extends Pool.Variance<A, E>, Pipeable {
export interface Pool<in out A, out E = never> extends Pool.Variance<A, E>, Effect.Effect<A, E, Scope.Scope>, Pipeable {
/**
* Retrieves an item from the pool in a scoped effect. Note that if
* acquisition fails, then the returned effect will fail for that same reason.
Expand All @@ -42,6 +43,30 @@ export interface Pool<in out A, out E = never> extends Pool.Variance<A, E>, Pipe
* than eagerly.
*/
invalidate(item: A): Effect.Effect<void>

readonly [Unify.typeSymbol]?: unknown
readonly [Unify.unifySymbol]?: PoolUnify<this>
readonly [Unify.ignoreSymbol]?: PoolUnifyIgnore
}

/**
* @category models
* @since 3.9.0
*/
export interface PoolUnify<A extends { [Unify.typeSymbol]?: any }> extends Effect.EffectUnify<A> {
Pool?: () => Extract<A[Unify.typeSymbol], Pool<any, any>> extends Pool<infer A0, infer _E0> | infer _ ?
A0 extends any ? Extract<A[Unify.typeSymbol], Pool<A0, any>> extends Pool<A0, infer E1> ? Pool<A0, E1>
: never
: never :
never
}

/**
* @category models
* @since 3.9.0
*/
export interface PoolUnifyIgnore extends Effect.EffectUnifyIgnore {
Effect?: true
}

/**
Expand Down
8 changes: 7 additions & 1 deletion packages/effect/src/internal/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Cause } from "effect/Cause"
import * as Context from "../Context.js"
import * as Duration from "../Duration.js"
import type { Effect, Semaphore } from "../Effect.js"
import * as Effectable from "../Effectable.js"
import type { Exit } from "../Exit.js"
import { dual, identity } from "../Function.js"
import * as Iterable from "../Iterable.js"
Expand Down Expand Up @@ -122,7 +123,7 @@ interface Strategy<A, E> {
readonly reclaim: (pool: PoolImpl<A, E>) => Effect<Option.Option<PoolItem<A, E>>>
}

class PoolImpl<A, E> implements Pool<A, E> {
class PoolImpl<A, E> extends Effectable.Class<A, E, Scope> implements Pool<A, E> {
readonly [PoolTypeId]: Pool.Variance<A, E>[PoolTypeId_]

isShuttingDown = false
Expand All @@ -140,6 +141,7 @@ class PoolImpl<A, E> implements Pool<A, E> {
readonly strategy: Strategy<A, E>,
readonly targetUtilization: number
) {
super()
this[PoolTypeId] = poolVariance
this.semaphore = circular.unsafeMakeSemaphore(concurrency * maxSize)
}
Expand Down Expand Up @@ -253,6 +255,10 @@ class PoolImpl<A, E> implements Pool<A, E> {
)
)

commit() {
return this.get
}

readonly get: Effect<A, E, Scope> = core.flatMap(
core.suspend(() => this.isShuttingDown ? core.interrupt : this.getPoolItem),
(_) => _.exit
Expand Down
10 changes: 10 additions & 0 deletions packages/effect/test/Pool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,4 +423,14 @@ describe("Pool", () => {
expect(yield* Ref.get(allocations)).toBe(11)
expect(yield* Ref.get(released)).toBe(11)
}))

it.scoped("is subtype of Effect", () =>
Effect.gen(function*() {
const pool = yield* Pool.make({
acquire: Effect.succeed(1),
size: 1
})
const item = yield* pool
assert.strictEqual(item, 1)
}))
})

0 comments on commit 5222099

Please sign in to comment.