59 lines
2.0 KiB
JavaScript
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']);
|
|
});
|