feat: add agent API and operational analytics
This commit is contained in:
1 parent
720ea0652a
commit
e8b730b592
65 files changed
+2650
-1214
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { RedditRequestCoordinator } from '../src/reddit/request-coordinator.js';
|
||||
|
||||
describe('RedditRequestCoordinator', () => {
|
||||
it('paces requests and applies a shared cooldown to the next queued request', async () => {
|
||||
let now = 0;
|
||||
const sleeps: number[] = [];
|
||||
const coordinator = new RedditRequestCoordinator(6_500, {
|
||||
now: () => now,
|
||||
sleep: async (ms) => { sleeps.push(ms); now += ms; },
|
||||
});
|
||||
|
||||
await coordinator.schedule(async () => undefined);
|
||||
coordinator.extendCooldown(30_000);
|
||||
await coordinator.schedule(async () => undefined);
|
||||
|
||||
expect(sleeps).toEqual([31_000]);
|
||||
});
|
||||
|
||||
it('serializes concurrent requests through one process-wide queue', async () => {
|
||||
const order: string[] = [];
|
||||
let releaseFirst!: () => void;
|
||||
const firstFinished = new Promise<void>((resolve) => { releaseFirst = resolve; });
|
||||
const coordinator = new RedditRequestCoordinator(0);
|
||||
|
||||
const first = coordinator.schedule(async () => {
|
||||
order.push('first:start');
|
||||
await firstFinished;
|
||||
order.push('first:end');
|
||||
});
|
||||
const second = coordinator.schedule(async () => { order.push('second'); });
|
||||
|
||||
await Promise.resolve();
|
||||
expect(order).toEqual(['first:start']);
|
||||
releaseFirst();
|
||||
await Promise.all([first, second]);
|
||||
expect(order).toEqual(['first:start', 'first:end', 'second']);
|
||||
});
|
||||
|
||||
it('does not release a queued request before a failing request records its cooldown', async () => {
|
||||
let now = 0;
|
||||
const sleeps: number[] = [];
|
||||
const coordinator = new RedditRequestCoordinator(0, {
|
||||
now: () => now,
|
||||
sleep: async (ms) => { sleeps.push(ms); now += ms; },
|
||||
});
|
||||
|
||||
const first = coordinator.schedule(async () => {
|
||||
coordinator.extendCooldown(15_000);
|
||||
throw new Error('429');
|
||||
});
|
||||
const second = coordinator.schedule(async () => undefined);
|
||||
|
||||
await expect(first).rejects.toThrow('429');
|
||||
await second;
|
||||
expect(sleeps).toEqual([16_000]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user