Changeset 1b1cc89 in Klonkt


Ignore:
Timestamp:
07/01/2026 12:45:51 AM (2 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
e1c4f3e
Parents:
0f2d441
Message:

fix(federation): deliver Follow via the retry queue (byh)

followActor() sent the Follow with a plain deliver() (fire-and-forget), so a
first-attempt failure (peer down/timeout/transient 5xx) left the follow stuck
on 'pending' forever — the Accept can only come back once the Follow lands.
Route it through deliverWithRetry() like deliverCreate/unfollowActor already do:
immediate attempt, then backoff retries via the ap_delivery queue (the worker
re-signs from the slug key).

  • src/services/ActivityPubService.js — followActor Follow delivery -> deliverWithRetry
  • CHANGELOG.md / .nl / .de — Unreleased Fixed: follow-retry + this session's cover/right-click/boost fixes

Co-Authored-By: Claude <noreply@…>

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • .beads/issues.jsonl

    r0f2d441 r1b1cc89  
    22{"_type":"issue","id":"prutfolio-src-3fl","title":"Audio: continuous playback breekt na 3-4 tracks (browser-policy / state corruption)","description":"Na fix v1 (next() unconditional play) werkt 1-\u003e2 en 2-\u003e3, maar stopt bij 3-\u003e4. Verdacht: iOS Safari autoplay-policy revoke OF audio element state-corruption na meerdere src changes. Fix: pause()+load()+play() pattern in loadTrack, error-event auto-skip naar volgende, NotAllowedError visuele hint (pulse op play-btn).","status":"open","priority":1,"issue_type":"bug","owner":"robin@roboburr.com","created_at":"2026-05-07T22:38:42Z","created_by":"Robin","updated_at":"2026-05-07T22:38:42Z","dependency_count":0,"dependent_count":0,"comment_count":0}
    33{"_type":"issue","id":"prutfolio-src-0tg","title":"Audio: continuous playback fix — next() altijd play() ipv conditional","description":"Bug: next() checkte 'if (isPlaying) play()' maar isPlaying was al false door de pause-event die de browser firet vóór ended. Resultaat: track stopt na 1 keer. Fix: drop de conditional, roep altijd play() aan. Zelfde voor prev(). Bestand: src/assets/js/audio-player.js regels 221-230.","status":"closed","priority":1,"issue_type":"bug","assignee":"Robin","owner":"robin@roboburr.com","created_at":"2026-05-06T22:18:40Z","created_by":"Robin","updated_at":"2026-05-06T22:28:20Z","started_at":"2026-05-06T22:26:37Z","closed_at":"2026-05-06T22:28:20Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
    4 {"_type":"issue","id":"prutfolio-src-byh","title":"Retry Follow delivery so follows don't get stuck on 'pending'","description":"followActor() inserts the ap_following row as 'pending' and then delivers the signed Follow once, with no retry (unlike deliverCreate, which uses the ap_delivery retry queue). A single transient delivery failure therefore leaves the follow permanently 'pending' — the remote never received it, so no Accept ever comes back.\n\nBuild later:\n- Route the Follow delivery through the existing ap_delivery retry queue (backoff), OR\n- Add a periodic re-send / re-poll for follows still 'pending' after N minutes.\n\nNote: a legitimately locked (manual-approval) account also shows 'pending' until the person approves — that is NOT this bug and must stay pending. Only retry the *delivery*, don't auto-flip status.\n\nWorkaround today: unfollow + follow again sends a fresh Follow.","status":"open","priority":2,"issue_type":"feature","owner":"roboburr@gmail.com","created_at":"2026-06-26T13:36:15Z","created_by":"roboburr","updated_at":"2026-06-26T13:36:15Z","dependency_count":0,"dependent_count":0,"comment_count":0}
     4{"_type":"issue","id":"prutfolio-src-byh","title":"Retry Follow delivery so follows don't get stuck on 'pending'","description":"followActor() inserts the ap_following row as 'pending' and then delivers the signed Follow once, with no retry (unlike deliverCreate, which uses the ap_delivery retry queue). A single transient delivery failure therefore leaves the follow permanently 'pending' — the remote never received it, so no Accept ever comes back.\n\nBuild later:\n- Route the Follow delivery through the existing ap_delivery retry queue (backoff), OR\n- Add a periodic re-send / re-poll for follows still 'pending' after N minutes.\n\nNote: a legitimately locked (manual-approval) account also shows 'pending' until the person approves — that is NOT this bug and must stay pending. Only retry the *delivery*, don't auto-flip status.\n\nWorkaround today: unfollow + follow again sends a fresh Follow.","status":"in_progress","priority":2,"issue_type":"feature","assignee":"roboburr","owner":"roboburr@gmail.com","created_at":"2026-06-26T13:36:15Z","created_by":"roboburr","updated_at":"2026-07-01T00:43:31Z","started_at":"2026-07-01T00:43:31Z","dependency_count":0,"dependent_count":0,"comment_count":0}
    55{"_type":"issue","id":"prutfolio-src-5gl","title":"Self-heal van de fediverse-cache (ap_timeline) bij ingrijpende updates","description":"Robin (2026-06-26): een self-heal als vaste functie, die getriggerd wordt bij ingrijpende updates -- zodat de fediverse-cache zichzelf repareert na een release waar posts in een flux-window coverless/stale bezorgd kunnen zijn (zoals de Cirkels-op-AP-migratie: gelijktijdige vloot-update + new-follower-backfill -\u003e sommige Creates kwamen zonder cover binnen, en de timeline is een snapshot-op-bezorging die nooit auto-bijwerkt).\n\nAanpak (generaliseer het eenmalige scripts/backfill-cirkel-covers.mjs tot een ingebouwde functie):\n- selfHealTimeline() in ActivityPubService: her-fetch ap_timeline-notes (AP) en werk content + media bij (covers/edits); 404/Tombstone -\u003e rij verwijderen.\n- Versie-gate: constante SELFHEAL_VERSION + app_setting selfheal_done_v\u003cN\u003e. Draait EENMAAL bij boot wanneer N wijzigt. Je bumpt N bij een ingrijpende release.\n- Net als autoMigrateCircles: async, non-blocking, best-effort, GEBOUND (bv. laatste ~50 of rate-limited) zodat het de boot niet belast en geen fetch-storm geeft.\n- Aangeroepen in server.js naast startScheduler/startDeliveryWorker/autoMigrateCircles.\n\nComplementair aan prutfolio-src-ymj (live inkomende Update afhandelen = continue self-heal); dit is het catch-up-vangnet voor wat live gemist is. Hergebruik de coverFrom/fetchNote-helpers uit het backfill-script.","status":"closed","priority":2,"issue_type":"feature","owner":"roboburr@gmail.com","created_at":"2026-06-26T10:00:19Z","created_by":"roboburr","updated_at":"2026-06-26T10:04:54Z","closed_at":"2026-06-26T10:04:54Z","close_reason":"Gebouwd: selfHealTimeline() in ActivityPubService, gegate op selfheal_version vs SELFHEAL_VERSION (draait 1x per bump), aangeroepen in server.js bij boot. Geverifieerd op democirkel (7/20 ververst, 2e reload skipt).","dependency_count":0,"dependent_count":0,"comment_count":0}
    66{"_type":"issue","id":"prutfolio-src-8z2","title":"Cirkel-feed: boosts van cirkel-vrienden tonen ZONDER ze opnieuw auto-te-boosten (anti-feedback-loop)","description":"Toekomstige feature: ook boosts (Announce) van accounts in je cirkel tonen in de feed/Cirkel.\n\nKRITIEKE GUARD (Robin 2026-06-26): auto-boost mag NOOIT een binnengekomen boost (Announce) opnieuw boosten -- alleen ORIGINELE posts (Create, geauteurd door het gevolgde account zelf). Anders feedback-loop: A boost X -\u003e B auto-boost A-z\\\"n-boost -\u003e C auto-boost B-z\\\"n-boost -\u003e ...\n\nHuidige status: VEILIG. De auto-boost-hook in handleInbox zit alleen op de Create-tak (top-level post van een gevolgd account), niet op Announce. Announces worden nu niet in ap_timeline opgeslagen, dus boosts worden nog niet getoond.\n\nTe doen zodra we boosts tonen:\n- Inkomende Announce van een gevolgd account opslaan/tonen in de feed (los van Create).\n- Auto-boost EXPLICIET beperken tot Create-van-de-auteur; nooit een Announce her-announcen.\n- Evt. extra dedup: niet auto-boosten wat je zelf al geboost hebt, en geen Announce van een Announce.","status":"closed","priority":2,"issue_type":"feature","owner":"roboburr@gmail.com","created_at":"2026-06-26T09:39:44Z","created_by":"roboburr","updated_at":"2026-06-26T12:01:22Z","closed_at":"2026-06-26T12:01:22Z","close_reason":"Opgelost door het nieuwe model: auto-boost is volledig verwijderd (uitlichten = lokaal), dus geen auto-re-Announce → loop-vrij. Boosts tonen in cirkel = lokaal (se8), geen her-boost.","dependency_count":0,"dependent_count":0,"comment_count":0}
  • CHANGELOG.de.md

    r0f2d441 r1b1cc89  
    55
    66## [Unreleased]
     7
     8### Behoben
     9- **Jemandem zu folgen bleibt nicht mehr hängen.** Eine Follow-Anfrage, deren erste Zustellung
     10  fehlschlägt (der andere Server kurz nicht erreichbar), wird jetzt automatisch mit Backoff erneut
     11  versucht, statt für immer auf „ausstehend" zu bleiben.
     12- **Animierte Video-Cover werden in Feeds korrekt angezeigt.** Sie erscheinen nicht mehr leer in der
     13  Rasteransicht.
     14- **Cover-Videos sind wieder dekorativ.** Ein Rechtsklick auf ein Cover zeigt das normale Link-Menü
     15  statt der Video-Steuerung des Browsers, und Rechtsklick „Speichern" ist bei Covern, Bildern und
     16  Videos unterdrückt (leichte Reibung).
     17- **Geboostete Beiträge zeigen ihren echten Text** im Zirkel, statt eines „RE: <Link>"-Präfixes.
    718
    819## [1.1.0] — 2026-06-30
  • CHANGELOG.md

    r0f2d441 r1b1cc89  
    55
    66## [Unreleased]
     7
     8### Fixed
     9- **Following someone no longer gets stuck.** A follow whose first delivery fails (the other server
     10  briefly unreachable) is now retried automatically with backoff, instead of staying on "pending" forever.
     11- **Animated video covers show correctly in feeds.** They no longer appear blank in the grid view.
     12- **Cover videos are decorative again.** Right-clicking a cover gives the normal link menu instead of the
     13  browser's video controls, and right-click "Save" is suppressed on covers, images and videos (light friction).
     14- **Boosted posts show their real text** in the Circle, instead of a "RE: <link>" prefix.
    715
    816## [1.1.0] — 2026-06-30
  • CHANGELOG.nl.md

    r0f2d441 r1b1cc89  
    55
    66## [Unreleased]
     7
     8### Opgelost
     9- **Iemand volgen blijft niet meer hangen.** Een volg-verzoek waarvan de eerste bezorging faalt (de
     10  andere server even onbereikbaar) wordt nu automatisch opnieuw geprobeerd, in plaats van eeuwig op
     11  "in behandeling" te blijven staan.
     12- **Geanimeerde video-covers tonen correct in feeds.** Ze verschijnen niet meer als een leeg vak in
     13  het raster.
     14- **Cover-video's zijn weer decoratief.** Rechtsklikken op een cover geeft het normale link-menu in
     15  plaats van de video-bediening van de browser, en rechtsklik "Opslaan" is onderdrukt op covers,
     16  afbeeldingen en video's (lichte frictie).
     17- **Geboooste posts tonen hun echte tekst** in de Cirkel, in plaats van een "RE: <link>"-prefix.
    718
    819## [1.1.0] — 2026-06-30
  • src/services/ActivityPubService.js

    r0f2d441 r1b1cc89  
    16621662  fwStmts().ins.run(site.slug, actor.id, ai.handle, ai.name, ai.icon, ai.url, actor.inbox, followId, 'pending', autoBoost ? 1 : 0);
    16631663  const follow = { '@context': AP_CONTEXT, id: followId, type: 'Follow', actor: me, object: actor.id };
    1664   try { await deliver(actor.inbox, follow, `${me}#main-key`, keys.private_pem); }
    1665   catch (e) { console.warn('[AP] follow deliver failed:', e.message); }
     1664  // Deliver via the retry queue: a Follow that fails the first attempt (peer down,
     1665  // timeout, transient 5xx) is retried with backoff instead of staying stuck on
     1666  // 'pending' forever — the Accept can only come back once the Follow lands.
     1667  await deliverWithRetry(site.slug, actor.inbox, follow, `${me}#main-key`, keys.private_pem);
    16661668  console.log('[AP] follow', site.slug, '→', actor.id);
    16671669  // Follow + feature in one step → backfill their recent posts into the Cirkel right away.
Note: See TracChangeset for help on using the changeset viewer.