Files
auto-team-custom/server/concurrency-queue.test.mjs

59 lines
2.0 KiB
JavaScript

import assert from 'node:assert/strict';
import { AsyncLocalStorage } from 'node:async_hooks';
import test from 'node:test';
import { createConcurrencyQueue } from './concurrency-queue.mjs';
const tick = () => new Promise((resolve) => setImmediate(resolve));
const deferred = () => {
let resolve;
const promise = new Promise((done) => { resolve = done; });
return { promise, resolve };
};
for (const limit of [1, 3]) {
test(`a shared browser queue permits ${limit} operations and starts the next only after completion`, async () => {
const queue = createConcurrencyQueue(() => limit);
const holds = Array.from({ length: 5 }, deferred);
const started = [];
let active = 0;
let peak = 0;
const results = holds.map((hold, index) => queue.run(async () => {
started.push(index);
peak = Math.max(peak, ++active);
await hold.promise;
active -= 1;
return index;
}));
await tick();
assert.deepEqual(started, Array.from({ length: limit }, (_, index) => index));
holds[0].resolve();
await results[0];
await tick();
assert.deepEqual(started, Array.from({ length: limit + 1 }, (_, index) => index));
holds.forEach((hold) => hold.resolve());
assert.deepEqual(await Promise.all(results), [0, 1, 2, 3, 4]);
assert.equal(peak, limit);
});
}
test('failure releases the shared queue and each account keeps its own async network context', async () => {
const network = new AsyncLocalStorage();
const queue = createConcurrencyQueue(() => 1);
const hold = deferred();
const observed = [];
const first = network.run('proxy-a', () => queue.run(async () => {
await hold.promise;
observed.push(network.getStore());
throw new Error('fixture login failed');
}));
const failure = assert.rejects(first, /fixture login failed/);
const second = network.run('proxy-b', () => queue.run(async () => {
observed.push(network.getStore());
return 'saved';
}));
hold.resolve();
await failure;
assert.equal(await second, 'saved');
assert.deepEqual(observed, ['proxy-a', 'proxy-b']);
});