Changeset 7e474f7 in Klonkt for test/fep1580-migration.test.js


Ignore:
Timestamp:
08/14/2026 03:12:04 AM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
bfadc15
Parents:
47f1183
Message:

De publieke vertaaltabel laadde alles om er twintig te tonen

Robin, ter herinnering: honderd miljoen Klonkt-gebruikers. Terecht, en het
wees meteen een echte fout aan in wat ik vandaag bouwde.

migrationItems deed SELECT zonder LIMIT. buildMigration bouwde daar objecten
van en liet pagedCollection er twintig uit snijden. Bij een gebruiker met
honderdduizend berichten betekent dat: honderdduizend rijen uit de database,
honderdduizend objecten in geheugen, 99,98 procent daarvan direct de prullenbak
in. Per verzoek.

En het is geen intern verzoek. Dit endpoint is publiek EN FEP-1580 schrijft
derden voor het herhaaldelijk op te halen tot migrationComplete waar is. Een
ontbrekende LIMIT is daar geen inefficientie maar een hefboom.

Nu in SQL gepagineerd, met dezelfde alGesneden-aanpak die de outbox al had.

DE KALE COLLECTIE DRAAGT GEEN RIJEN MEER, alleen de telling en first/last. Dat
is niet alleen goedkoper maar ook veiliger: een kale collectie MET items was
precies de valstrik waar onze eigen ingest vanmorgen in liep. Hij zag items,
sloeg first over, vond geen next en dacht klaar te zijn bij 18 van de 35.

Changed files:
src/services/MigrationService.js

  • migrationItems kent limit en offset
  • buildMigration telt apart en haalt alleen de gevraagde pagina op

test/fep1580-migration.test.js

  • de kale collectie heeft een telling en geen rijen
  • 45 items geven pagina's van 20/20/5, zonder overlap en zonder verlies

remarks: de rate-limiter dekt /ap al, dus die kant zat goed. Wat NIET opgelost
is en bij deze schaal het echte plafond blijft: buildArchive bouwt de hele zip
in geheugen, inclusief elk audiobestand. Die grens van 512 MB is nog steeds een
beredeneerde gok en geen meting. Streamen staat als shaer-190t genoteerd; bij
honderd miljoen gebruikers is dat geen nice-to-have meer. Suite 1014 groen,
tegenproef gedaan.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/fep1580-migration.test.js

    r47f1183 r7e474f7  
    149149  Mig.recordMigrated('ik', { origin: `${BRON}/notes/1`, target: `${IK}/notes/a`, sourceActor: BRON });
    150150  Mig.recordMigrated('ik', { origin: `${BRON}/notes/2`, target: `${IK}/notes/b`, sourceActor: BRON });
    151   const coll = Mig.buildMigration('https://nieuw.example', s);
     151  // De KALE collectie draagt alleen de telling en de wegwijzers. Bewust: dit is
     152  // een publiek endpoint dat derden herhaaldelijk pollen, en alle rijen laden om
     153  // er twintig te tonen is bij honderdduizend berichten een hefboom. Bovendien
     154  // was een kale collectie MET items precies de valstrik waar onze eigen ingest
     155  // in liep: hij zag items, sloeg `first` over en miste de helft.
     156  const kaal = Mig.buildMigration('https://nieuw.example', s);
     157  assert.equal(kaal.totalItems, 2, 'de telling staat er wel');
     158  assert.equal((kaal.orderedItems || []).length, 0, 'maar de rijen niet');
     159  assert.ok(kaal.first, 'wie ze wil volgt first');
     160
     161  const coll = Mig.buildMigration('https://nieuw.example', s, { page: 1 });
    152162  assert.equal(coll.totalItems, 2);
    153163  const items = coll.orderedItems || coll.items;
     164  assert.equal(items.length, 2);
    154165  assert.equal(items[0].origin, `${BRON}/notes/2`, 'omgekeerd chronologisch op aanmaakmoment HIER');
    155166  assert.equal(items[0].type, 'Move');
    156167  assert.equal(items[0].target, `${IK}/notes/b`);
     168});
     169
     170test('de publieke vertaaltabel laadt niet alles om twintig te tonen', () => {
     171  // Robins herinnering: honderd miljoen Klonkt-gebruikers. Dit endpoint is
     172  // publiek en derden pollen het tot migrationComplete waar is, dus een query
     173  // zonder LIMIT is hier geen inefficientie maar een hefboom.
     174  const s = site();
     175  for (let i = 0; i < 45; i++) {
     176    Mig.recordMigrated('ik', { origin: `${BRON}/notes/n${i}`, target: `${IK}/notes/n${i}` });
     177  }
     178  const p1 = Mig.buildMigration('https://nieuw.example', s, { page: 1 });
     179  assert.equal(p1.totalItems, 45, 'de telling klopt over het geheel');
     180  assert.equal(p1.orderedItems.length, 20, 'maar er komt een PAGINA uit, geen bak van 45');
     181  assert.ok(p1.next, 'en er is een volgende');
     182  const p3 = Mig.buildMigration('https://nieuw.example', s, { page: 3 });
     183  assert.equal(p3.orderedItems.length, 5, 'de laatste pagina is de rest');
     184  assert.equal(p3.next, undefined, 'en die biedt geen volgende meer aan');
     185  // De pagina's overlappen niet en samen zijn ze het geheel.
     186  const p2 = Mig.buildMigration('https://nieuw.example', s, { page: 2 });
     187  const alle = [...p1.orderedItems, ...p2.orderedItems, ...p3.orderedItems].map((x) => x.origin);
     188  assert.equal(new Set(alle).size, 45, 'geen dubbele en niets kwijt');
    157189});
    158190
Note: See TracChangeset for help on using the changeset viewer.