f97999c3c0
- coalesce.js: generisches Serialisieren+Koaleszieren je Key; buildSite() in hugo.js nutzt es → Publish/Preview/Profil starten nie überlappende Hugo- Prozesse, schnelle Folge-Aufrufe lösen nur einen Trailing-Build aus - dialog-store: syncLibrary() gedrosselt (60s-TTL) statt bei jedem Forum-Read Filesystem-Walk + Upsert; Publish forciert Sync (force:true) - test/: node:test-Suite (19 Tests) für safeRel/normAuthors/urlFor/hasAccess, roleOf + lokale JWT-Verifikation, Rate-Limiter, Coalescing; npm test Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
2.0 KiB
JavaScript
47 lines
2.0 KiB
JavaScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
const { coalesce } = await import('../src/coalesce.js');
|
|
|
|
const tick = (ms = 5) => new Promise((r) => setTimeout(r, ms));
|
|
|
|
test('coalesce: nie mehr als ein Lauf gleichzeitig pro Key', async () => {
|
|
let active = 0, maxActive = 0, runs = 0;
|
|
const fn = async () => { active++; maxActive = Math.max(maxActive, active); await tick(10); runs++; active--; return runs; };
|
|
|
|
// 5 gleichzeitige Aufrufe.
|
|
await Promise.all(Array.from({ length: 5 }, () => coalesce('k1', fn)));
|
|
assert.equal(maxActive, 1, 'parallele Läufe');
|
|
// Erster Lauf bedient den ersten Aufruf; die 4 während des Laufs eingetroffenen
|
|
// teilen sich GENAU EINEN nachgelagerten Lauf → insgesamt 2.
|
|
assert.equal(runs, 2);
|
|
});
|
|
|
|
test('coalesce: Wartende teilen sich das Ergebnis des nachgelagerten Laufs', async () => {
|
|
let n = 0;
|
|
const fn = async () => { await tick(10); return ++n; };
|
|
const first = coalesce('k2', fn); // startet sofort → Ergebnis 1
|
|
await tick(2); // sicherstellen, dass er läuft
|
|
const a = coalesce('k2', fn); // wartet → nachgelagerter Lauf
|
|
const b = coalesce('k2', fn); // wartet → selber Lauf wie a
|
|
assert.equal(await first, 1);
|
|
const [ra, rb] = await Promise.all([a, b]);
|
|
assert.equal(ra, 2);
|
|
assert.equal(rb, 2); // a und b teilen sich Lauf 2
|
|
});
|
|
|
|
test('coalesce: Fehler wird an die Wartenden propagiert, Key bleibt nutzbar', async () => {
|
|
let fail = true;
|
|
const fn = async () => { await tick(5); if (fail) throw new Error('boom'); return 'ok'; };
|
|
await assert.rejects(() => coalesce('k3', fn), /boom/);
|
|
fail = false;
|
|
assert.equal(await coalesce('k3', fn), 'ok'); // danach wieder verwendbar
|
|
});
|
|
|
|
test('coalesce: verschiedene Keys laufen unabhängig', async () => {
|
|
const fn = async () => { await tick(5); return 'done'; };
|
|
const [x, y] = await Promise.all([coalesce('kA', fn), coalesce('kB', fn)]);
|
|
assert.equal(x, 'done');
|
|
assert.equal(y, 'done');
|
|
});
|