(algorithm: "fixed-window" | "token-bucket")
| 155 | }) |
| 156 | |
| 157 | const RateLimiterTestSuite = (algorithm: "fixed-window" | "token-bucket") => { |
| 158 | it.scoped(`${algorithm} - execute up to max calls immediately`, () => |
| 159 | Effect.gen(function*() { |
| 160 | const limit = yield* (RateLimiter.make({ |
| 161 | limit: 10, |
| 162 | interval: "1 seconds", |
| 163 | algorithm |
| 164 | })) |
| 165 | const now = yield* (Clock.currentTimeMillis) |
| 166 | const times = yield* (Effect.forEach( |
| 167 | Array.range(1, 10), |
| 168 | () => limit(Clock.currentTimeMillis) |
| 169 | )) |
| 170 | const result = Array.every(times, (time) => time === now) |
| 171 | assertTrue(result) |
| 172 | })) |
| 173 | |
| 174 | it.scoped(`${algorithm} - is not affected by stream chunk size`, () => |
| 175 | Effect.gen(function*() { |
| 176 | const limiter = yield* (RateLimiter.make({ |
| 177 | limit: 10, |
| 178 | interval: "1 seconds", |
| 179 | algorithm |
| 180 | })) |
| 181 | const now = yield* (Clock.currentTimeMillis) |
| 182 | const times1 = yield* (Effect.forEach( |
| 183 | Array.range(1, 5), |
| 184 | () => limiter(Clock.currentTimeMillis), |
| 185 | { concurrency: "unbounded" } |
| 186 | )) |
| 187 | const fibers = yield* (Effect.forEach( |
| 188 | Array.range(1, 15), |
| 189 | () => Effect.fork(limiter(Clock.currentTimeMillis)), |
| 190 | { concurrency: "unbounded" } |
| 191 | )) |
| 192 | yield* (TestClock.adjust("1 seconds")) |
| 193 | const times2 = yield* (Effect.forEach(fibers, Fiber.join, { concurrency: "unbounded" })) |
| 194 | const times = Array.appendAll(times1, times2) |
| 195 | const result = Array.filter(times, (time) => time === now) |
| 196 | strictEqual(result.length, 10) |
| 197 | })) |
| 198 | |
| 199 | it.scoped(`${algorithm} - succeed with the result of the call`, () => |
| 200 | Effect.gen(function*() { |
| 201 | const limit = yield* (RateLimiter.make({ |
| 202 | limit: 10, |
| 203 | interval: "1 seconds", |
| 204 | algorithm |
| 205 | })) |
| 206 | const result = yield* (limit(Effect.succeed(3))) |
| 207 | strictEqual(result, 3) |
| 208 | })) |
| 209 | |
| 210 | it.scoped(`${algorithm} - fail with the result of a failed call`, () => |
| 211 | Effect.gen(function*() { |
| 212 | const limit = yield* (RateLimiter.make({ |
| 213 | limit: 10, |
| 214 | interval: "1 seconds", |
no test coverage detected