perf/test: Build-Coalescing teilen, syncLibrary drosseln, API-Tests
- 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>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
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');
|
||||
});
|
||||
Reference in New Issue
Block a user