Pace engine reads under the proxy's rate limit

The proxy allows 10 requests a second per address and answers the rest
503. Limiting how many reads run at once still sent 40-50 a second, since
each answers in about 100 ms. Reads now share one pace of 8 a second,
actions skip the queue, and a 503 pauses every read for 2 seconds.
Results and Schedule share each schedule's production status, and an
archived schedule is read once until an action.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Iqbal
2026-10-30 10:06:40 +07:00
parent 138be5ac96
commit 977a8fafc4
6 changed files with 121 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { limiter } from './client'
import { limiter, pacer } from './client'
describe('limiter', () => {
it('runs at most n calls at once, all of them, failures included', async () => {
@@ -17,3 +17,23 @@ describe('limiter', () => {
expect(out.map(r => (r.status === 'fulfilled' ? r.value : 'x'))).toEqual([1, 'x', 3, 4, 5])
})
})
describe('pacer', () => {
it('lets a burst through, then spaces the rest out in order', async () => {
const pace = pacer(100, 2)
const t0 = Date.now()
const order: number[] = []
await Promise.all([1, 2, 3, 4, 5, 6].map(n => pace.wait().then(() => order.push(n))))
// Two at once, then four more at 10 ms each.
expect(Date.now() - t0).toBeGreaterThanOrEqual(35)
expect(order).toEqual([1, 2, 3, 4, 5, 6])
})
it('pauses everything after the proxy turns one away', async () => {
const pace = pacer(100, 5)
pace.pause(50)
const t0 = Date.now()
await pace.wait()
expect(Date.now() - t0).toBeGreaterThanOrEqual(45)
})
})