Changeset 6fab3f3 in Klonkt for src/routes/guardian.js


Ignore:
Timestamp:
08/08/2026 10:42:20 PM (4 weeks ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
cae7bfc
Parents:
060d4a5
git-author:
Robin <roboburr@…> (08/08/2026 10:42:18 PM)
git-committer:
roboburr <roboburr@…> (08/08/2026 10:42:20 PM)
Message:

Een lange poll voor alles wat de Guardian te verwerken krijgt (Barts opdracht, 9-8)

Het paneel tikte elke 45 seconden, ongeacht of er iets gebeurd was. Nu hangt er
een verzoek open tot er iets IS. Dat is niet alleen zuiniger -- het is vooral
sneller: een hulproep stond eerst tot drie kwart minuut te wachten op de klok.

WAKKER OP ALLES, en dat is de kern van de opdracht. De guardianship-module zendt
veertien soorten gebeurtenissen uit; die gingen tot nu toe alleen naar push, en
push kiest bewust een handvol. De tien soorten zonder pushtekst -- een stem op
een lapse, een uitkomst, een review -- zag je pas bij de volgende tik. Wie maak
je WAKKER en wat moet een openstaand scherm WETEN zijn twee verschillende
vragen, en ze hadden hetzelfde antwoord.

Naast die bus wekt ook de tijdlijn (onNews): de berichten van je wards staan in
ditzelfde scherm. En de twee paden die niet via notify() lopen -- een
hulpmarkering van een mede-guardian, en een poortverzoek van een kind -- wekken
nu zelf.

EERST KIJKEN, DAN WACHTEN. Veranderde er iets tussen het vorige antwoord en dit
verzoek, dan is de merksteen al anders en gaat het antwoord meteen de deur uit.
Zou je eerst gaan wachten, dan blijft nieuws dat net in dat gaatje viel 25
seconden liggen -- en bij een hulpvraag is dat de verkeerde vertraging.

Het tikje blijft als vangnet, maar op vijf minuten in plaats van 45 seconden:
valt er een wekker weg (een pad dat niet wekt, een herstart midden in een
verzoek), dan mag het scherm niet voorgoed stilstaan. Met de ETag kost zo'n tik
meestal een lege 304.

EEN NAAD DIE IK EERST NIET KON RAKEN. Het wekken zat verstopt in de deps-literal,
en de mutatie die het weghaalde bleef groen -- mijn toetsen dekten alleen de bus.
onGuardianshipEvent is nu een functie met een naam, precies zoals
guardianEventPush dat al was, en de mutatie is nu rood. Een lange poll die niet
wekt is niet te onderscheiden van een trage server, en dat is het soort fout dat
niemand meldt.

Tien toetsen. Suite 770/770.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/guardian.js

    r060d4a5 r6fab3f3  
    182182
    183183// ── JSON state for refreshes ─────────────────────────────────────────────
    184 router.get('/api/state', requireAuth, (req, res) => {
    185   const site = siteForUser(req);
    186   if (!site) return res.status(404).json({ error: 'no_site' });
    187   // Het paneel tikt elke 45 seconden, of er nu iets gebeurd is of niet. Met een
    188   // ETag kost stilte een lege 304 in plaats van het hele paneel (Barts punt, 9-8).
    189   return AP.sendMaybe304(req, res, dashboardState(site, resolveLang(req)), { contentType: 'application/json' });
     184/**
     185 * De staat van het paneel, desgewenst als LANGE POLL (Barts opdracht, 9-8).
     186 *
     187 * Zonder `wait` gedraagt de route zich exact zoals altijd. Met `wait` blijft het
     188 * antwoord hangen tot er iets gebeurt dat de guardian moet verwerken, of tot de
     189 * tijd om is -- dan een lege 304.
     190 *
     191 * EERST KIJKEN, DAN WACHTEN. Veranderde er iets tussen het vorige antwoord en
     192 * dit verzoek, dan is de merksteen nu al anders en gaat het antwoord METEEN de
     193 * deur uit. Zou je eerst gaan wachten, dan blijft nieuws dat net in dat gaatje
     194 * viel vijfentwintig seconden liggen -- en juist bij een hulpvraag is dat de
     195 * verkeerde vertraging.
     196 *
     197 * WAKKER OP ALLES. De guardianship-module zendt veertien soorten gebeurtenissen
     198 * uit en die wekken allemaal (wakeGuardian); daarnaast wekt de tijdlijn (onNews),
     199 * want de berichten van je wards staan in ditzelfde scherm.
     200 */
     201router.get('/api/state', requireAuth, async (req, res) => {
     202  const site = siteForUser(req);
     203  if (!site) return res.status(404).json({ error: 'no_site' });
     204  const stuur = () => AP.sendMaybe304(req, res, dashboardState(site, resolveLang(req)), { contentType: 'application/json' });
     205
     206  const wachtS = Math.min(Math.max(parseInt(req.query.wait, 10) || 0, 0), 50);
     207  const merk = req.headers['if-none-match'];
     208  if (!wachtS || !merk) return stuur();
     209
     210  // Is er nu al iets anders? Dan niet wachten.
     211  const nu = AP.etagFor(JSON.stringify(dashboardState(site, resolveLang(req))));
     212  if (nu !== merk) return stuur();
     213
     214  await new Promise((klaar) => {
     215    let af = false;
     216    const eind = () => { if (af) return; af = true; clearTimeout(t); offG(); offN(); klaar(); };
     217    const offG = AP.onGuardian(site.slug, eind);
     218    const offN = AP.onNews(site.slug, eind);
     219    const t = setTimeout(eind, wachtS * 1000);
     220    // Hing de client op, dan houdt niemand dit antwoord meer vast.
     221    res.on('close', eind);
     222  });
     223  if (res.writableEnded) return undefined;
     224  return stuur();
    190225});
    191226
Note: See TracChangeset for help on using the changeset viewer.