Skip to content

Commit

Permalink
update changesets
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart committed May 28, 2024
1 parent 4ffc7be commit 700bc04
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 5 deletions.
11 changes: 11 additions & 0 deletions .changeset/flat-spiders-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"effect": minor
---

add `timeToLiveStrategy` to `Pool` options

The `timeToLiveStrategy` determines how items are invalidated. If set to
"creation", then items are invalidated based on their creation time. If set
to "usage", then items are invalidated based on pool usage.

By default, the `timeToLiveStrategy` is set to "usage".
5 changes: 4 additions & 1 deletion .changeset/quiet-maps-judge.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
"effect": minor
---

support concurrent access for Pool items
add `permits` option to `Pool.make` & `Pool.makeWithTTL`

This option allows you to specify the level of concurrent access per pool item.
I.e. setting `permits: 2` will allow each pool item to be in use by 2 concurrent tasks.
14 changes: 13 additions & 1 deletion packages/effect/src/Pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ export const isPool: (u: unknown) => u is Pool<unknown, unknown> = internal.isPo
* because the `Scope` is closed, the individual items allocated by the pool
* will be released in some unspecified order.
*
* By setting the `permits` parameter, you can control the level of concurrent
* access per pool item. By default, the number of permits is set to `1`.
*
* @since 2.0.0
* @category constructors
*/
Expand All @@ -93,6 +96,15 @@ export const make: <A, E, R>(
* used, the individual items allocated by the pool will be released in some
* unspecified order.
*
* By setting the `permits` parameter, you can control the level of concurrent
* access per pool item. By default, the number of permits is set to `1`.
*
* The `timeToLiveStrategy` determines how items are invalidated. If set to
* "creation", then items are invalidated based on their creation time. If set
* to "usage", then items are invalidated based on pool usage.
*
* By default, the `timeToLiveStrategy` is set to "usage".
*
* ```ts
* import { createConnection } from "mysql2";
* import { Duration, Effect, Pool } from "effect"
Expand Down Expand Up @@ -123,7 +135,7 @@ export const makeWithTTL: <A, E, R>(
readonly max: number
readonly permits?: number | undefined
readonly timeToLive: Duration.DurationInput
readonly timeToLiveStrategy?: "creation" | "access" | undefined
readonly timeToLiveStrategy?: "creation" | "usage" | undefined
}
) => Effect.Effect<Pool<A, E>, never, Scope.Scope | R> = internal.makeWithTTL

Expand Down
6 changes: 3 additions & 3 deletions packages/effect/src/internal/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ export const makeWithTTL = <A, E, R>(options: {
readonly max: number
readonly permits?: number | undefined
readonly timeToLive: Duration.DurationInput
readonly timeToLiveStrategy?: "creation" | "access" | undefined
readonly timeToLiveStrategy?: "creation" | "usage" | undefined
}): Effect<Pool<A, E>, never, R | Scope> =>
core.flatMap(
options.timeToLiveStrategy === "creation" ?
strategyCreationTTL<A, E>(options.timeToLive) :
strategyAccessTTL<A, E>(options.timeToLive),
strategyUsageTTL<A, E>(options.timeToLive),
(strategy) => makeWith({ ...options, strategy })
)

Expand Down Expand Up @@ -306,7 +306,7 @@ const strategyCreationTTL = <A, E>(ttl: Duration.DurationInput) =>
})
)

const strategyAccessTTL = <A, E>(ttl: Duration.DurationInput) =>
const strategyUsageTTL = <A, E>(ttl: Duration.DurationInput) =>
core.map(internalQueue.unbounded<PoolItem<A, E>>(), (queue) => {
return identity<Strategy<A, E>>({
run: (pool) => {
Expand Down
32 changes: 32 additions & 0 deletions packages/effect/test/Pool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,38 @@ describe("Pool", () => {
expect(max).toBe(15)
}))

it.scoped("scale to zero", () =>
Effect.gen(function*($) {
const deferred = yield* $(Deferred.make<void>())
const count = yield* $(Ref.make(0))
const acquire = Effect.acquireRelease(
Ref.updateAndGet(count, (n) => n + 1),
() => Ref.update(count, (n) => n - 1)
)
const pool = yield* $(Pool.makeWithTTL({
acquire,
min: 0,
max: 10,
permits: 3,
timeToLive: Duration.seconds(60)
}))
yield* $(
Effect.scoped(Effect.zipRight(
Pool.get(pool),
Deferred.await(deferred)
)),
Effect.fork,
Effect.repeatN(29)
)
yield* $(Effect.repeat(Ref.get(count), { until: (n) => n === 10 }))
yield* $(Deferred.succeed(deferred, void 0))
const max = yield* $(Ref.get(count))
yield* $(TestClock.adjust(Duration.seconds(60)))
const min = yield* $(Ref.get(count))
expect(min).toBe(0)
expect(max).toBe(10)
}))

it.scoped("shutdown robustness", () =>
Effect.gen(function*($) {
const count = yield* $(Ref.make(0))
Expand Down

0 comments on commit 700bc04

Please sign in to comment.