| 1 | import { Effect, Exit, Pool, Scope } from "effect" |
| 2 | import { Bench } from "tinybench" |
| 3 | |
| 4 | const poolSize = 10 |
| 5 | let nextItem = 0 |
| 6 | |
| 7 | const acquire = Effect.sync(() => ++nextItem) |
| 8 | const getAll = (pool: Pool.Pool<number>) => |
| 9 | Effect.all( |
| 10 | Array.from({ length: poolSize }, () => Pool.get(pool)), |
| 11 | { concurrency: "unbounded", discard: true } |
| 12 | ) |
| 13 | |
| 14 | const makeFixed = Effect.scoped( |
| 15 | Effect.flatMap( |
| 16 | Pool.make({ acquire, size: poolSize }), |
| 17 | getAll |
| 18 | ) |
| 19 | ) |
| 20 | |
| 21 | const 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 | |
| 33 | const poolScope = await Effect.runPromise(Scope.make()) |
| 34 | const fixedPool = await Effect.runPromise( |
| 35 | Pool.make({ acquire, size: poolSize }).pipe(Scope.provide(poolScope)) |
| 36 | ) |
| 37 | const 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 | ) |
| 45 | const invalidationPool = await Effect.runPromise( |
| 46 | Pool.make({ acquire, size: 1 }).pipe(Scope.provide(poolScope)) |
| 47 | ) |
| 48 | |
| 49 | await Effect.runPromise(Effect.scoped(Effect.all([getAll(fixedPool), getAll(ttlPool)], { discard: true }))) |
| 50 | |
| 51 | let invalidationItem = await Effect.runPromise(Effect.scoped(Pool.get(invalidationPool))) |
| 52 | const invalidateAndReplace = Effect.scoped( |
| 53 | Effect.gen(function*() { |
| 54 | yield* Pool.invalidate(invalidationPool, invalidationItem) |
| 55 | invalidationItem = yield* Pool.get(invalidationPool) |
| 56 | }) |
| 57 | ) |
| 58 | |
| 59 | const bench = new Bench() |
| 60 | |
| 61 | const useItem = (item: number) => Effect.succeed(item) |
| 62 | |
| 63 | bench |
| 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 | |
| 73 | await bench.run() |
| 74 | await Effect.runPromise(Scope.close(poolScope, Exit.void)) |
| 75 | |
| 76 | console.table(bench.table()) |