1import { Effect, Exit, Pool, Scope } from "effect"
2import { Bench } from "tinybench"
3
4const poolSize = 10
5let nextItem = 0
6
7const acquire = Effect.sync(() => ++nextItem)
8const getAll = (pool: Pool.Pool<number>) =>
9 Effect.all(
10 Array.from({ length: poolSize }, () => Pool.get(pool)),
11 { concurrency: "unbounded", discard: true }
12 )
13
14const makeFixed = Effect.scoped(
15 Effect.flatMap(
16 Pool.make({ acquire, size: poolSize }),
17 getAll
18 )
19)
20
21const makeWithTTL = Effect.scoped(
22 Effect.flatMap(
23 Pool.makeWithTTL({
24 acquire,
25 min: 0,
26 max: poolSize,
27 timeToLive: "1 minute"
28 }),
29 getAll
30 )
31)
32
33const poolScope = await Effect.runPromise(Scope.make())
34const fixedPool = await Effect.runPromise(
35 Pool.make({ acquire, size: poolSize }).pipe(Scope.provide(poolScope))
36)
37const ttlPool = await Effect.runPromise(
38 Pool.makeWithTTL({
39 acquire,
40 min: 0,
41 max: poolSize,
42 timeToLive: "1 minute"
43 }).pipe(Scope.provide(poolScope))
44)
45const invalidationPool = await Effect.runPromise(
46 Pool.make({ acquire, size: 1 }).pipe(Scope.provide(poolScope))
47)
48
49await Effect.runPromise(Effect.scoped(Effect.all([getAll(fixedPool), getAll(ttlPool)], { discard: true })))
50
51let invalidationItem = await Effect.runPromise(Effect.scoped(Pool.get(invalidationPool)))
52const invalidateAndReplace = Effect.scoped(
53 Effect.gen(function*() {
54 yield* Pool.invalidate(invalidationPool, invalidationItem)
55 invalidationItem = yield* Pool.get(invalidationPool)
56 })
57)
58
59const bench = new Bench()
60
61const useItem = (item: number) => Effect.succeed(item)
62
63bench
64 .add("make fixed pool (10 items)", () => Effect.runPromise(makeFixed))
65 .add("make TTL pool (10 items)", () => Effect.runPromise(makeWithTTL))
66 .add("get and release (fixed pool)", () => Effect.runPromise(Effect.scoped(Pool.get(fixedPool))))
67 .add("get and release (TTL pool)", () => Effect.runPromise(Effect.scoped(Pool.get(ttlPool))))
68 .add("use (fixed pool)", () => Effect.runPromise(Pool.use(fixedPool, useItem)))
69 .add("use (TTL pool)", () => Effect.runPromise(Pool.use(ttlPool, useItem)))
70 .add("get and release (10 concurrent)", () => Effect.runPromise(Effect.scoped(getAll(fixedPool))))
71 .add("invalidate and replace", () => Effect.runPromise(invalidateAndReplace))
72
73await bench.run()
74await Effect.runPromise(Scope.close(poolScope, Exit.void))
75
76console.table(bench.table())