Changeset bfd9c73 in Klonkt
- Timestamp:
- 08/08/2026 10:09:50 PM (4 weeks ago)
- Branches:
- main
- Children:
- 8179fdb
- Parents:
- 1d76e0e
- git-author:
- Robin <roboburr@…> (08/08/2026 10:09:48 PM)
- git-committer:
- roboburr <roboburr@…> (08/08/2026 10:09:50 PM)
- Files:
-
- 1 added
- 3 edited
-
src/routes/activitypub.js (modified) (1 diff)
-
src/routes/guardian.js (modified) (1 diff)
-
src/services/ActivityPubService.js (modified) (2 diffs)
-
test/conditional-queues.test.js (added)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/activitypub.js
r1d76e0e rbfd9c73 321 321 const base = baseUrl(req); 322 322 const me = `${base}/ap/users/${auth.site.slug}`; 323 AP.sendAP(res, { '@context': AP.AP_CONTEXT, ...build(`${me}/queues/${name}`, auth.site.slug, me) }); 323 // 304 als er niets veranderde (Barts punt, 9-8). Zonder dit haalde een app 324 // bij elke actie de hele lijst opnieuw op -- een hulpvraag afvinken vroeg de 325 // honderd wards inclusief poorten terug. 326 AP.sendMaybe304(req, res, { '@context': AP.AP_CONTEXT, ...build(`${me}/queues/${name}`, auth.site.slug, me) }); 324 327 }); 325 328 } -
src/routes/guardian.js
r1d76e0e rbfd9c73 185 185 const site = siteForUser(req); 186 186 if (!site) return res.status(404).json({ error: 'no_site' }); 187 res.json(dashboardState(site, resolveLang(req))); 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' }); 188 190 }); 189 191 -
src/services/ActivityPubService.js
r1d76e0e rbfd9c73 211 211 212 212 const AP_CONTENT_TYPE = 'application/activity+json; charset=utf-8'; 213 /** 214 * Hetzelfde antwoord als de vorige keer? Dan 304 (Barts punt, 9-8). 215 * 216 * De inbox doet dit al met `since` + `wait`, en de guardian-wachtrijen niet: die 217 * stuurden bij elke verversing de hele lijst terug, ook als er niets veranderd 218 * was. Bij honderd wards is dat 217 KB JSON die de telefoon opnieuw moet 219 * parsen -- over de lijn valt het mee (2,8 KB gzip), maar het OPBOUWEN van 220 * veertienhonderd objecten is wat je merkt. 221 * 222 * EEN INHOUDS-ETAG, geen cursor. Een cursor vraagt een tweede beschrijving van 223 * wanneer iets "veranderd" is, en die kan uit de pas gaan lopen met wat er 224 * werkelijk in het antwoord staat; een hash van het antwoord zelf kan dat per 225 * definitie niet. De server bouwt het antwoord nog steeds (26 ms) -- wat we 226 * besparen is de overdracht en het parsen. 227 * 228 * NOOIT 304 OP EEN LEEG ANTWOORD. Dezelfde les als de '0'-uitzondering bij de 229 * inbox: gaat er bij het opbouwen iets mis en komt er een lege lijst uit, dan is 230 * die hash ook stabiel, en zou een client voor eeuwig 304 krijgen op niets. 231 */ 232 export function etagFor(body) { 233 return `"${crypto.createHash('sha256').update(body).digest('base64url').slice(0, 27)}"`; 234 } 235 236 export function sendMaybe304(req, res, obj, { cacheControl, contentType } = {}) { 237 const body = JSON.stringify(obj); 238 const leeg = !obj || (Array.isArray(obj.orderedItems) && obj.orderedItems.length === 0); 239 res.set('Vary', 'Authorization'); 240 if (!leeg) { 241 const tag = etagFor(body); 242 res.set('ETag', tag); 243 if (req.headers['if-none-match'] === tag) return res.status(304).end(); 244 } 245 res.type(contentType || AP_CONTENT_TYPE); 246 // `no-cache` betekent NIET "niet bewaren": de client bewaart het antwoord en 247 // vraagt elke keer of het nog klopt. Precies wat we willen -- zonder dit 248 // stuurt een browser geen If-None-Match en is de ETag decoratie. 249 res.set('Cache-Control', cacheControl || 'private, no-cache'); 250 return res.send(body); 251 } 252 213 253 export function sendAP(res, obj, cacheControl) { 214 254 res.type(AP_CONTENT_TYPE); … … 6390 6430 getNotifications, listBlocks, isBlockedAny, blockTarget, unblock, 6391 6431 deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker, 6392 proposeGate, getReplyUris, getThread, filterThreadToCircle, gateAttachments, stripEmojiTags, markNotificationsSeen, countUnseenNotifications, hasPlayableAudio,6432 sendMaybe304, etagFor, proposeGate, getReplyUris, getThread, filterThreadToCircle, gateAttachments, stripEmojiTags, markNotificationsSeen, countUnseenNotifications, hasPlayableAudio, 6393 6433 linkifyBody, bakePostContent, bakePostContentWithMentions, listFollowers, removeFollower, listConnections, 6394 6434 noteVisibility, belongsInTimeline, playerUrlFor, isRejectedObject, rejectInteraction, interactionReportTarget,
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)