Changeset 4c12783 in Klonkt


Ignore:
Timestamp:
06/25/2026 08:52:26 PM (3 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
8ad1784
Parents:
a9900ec
Message:

perf(ap): backfill new followers once per remote instance, not per follower

Backfill fired 20 Create deliveries on every Follow. Mastodon dedupes notes
per-instance, so the 2nd+ follower from the same instance got the same 20 posts
re-sent for nothing (and old posts don't re-enter a new follower's timeline
anyway). Now we skip backfill when another follower already represents that
instance (same shared_inbox), and deliver to the shared inbox when present.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ActivityPubService.js

    ra9900ec r4c12783  
    585585    const remote = await fetchActor(who);
    586586    if (!remote || !remote.inbox) return 202; // can't reach them → drop quietly
    587     fStmts().ins.run(slug, who, remote.inbox, (remote.endpoints && remote.endpoints.sharedInbox) || null);
     587    const sharedInbox = (remote.endpoints && remote.endpoints.sharedInbox) || null;
     588    fStmts().ins.run(slug, who, remote.inbox, sharedInbox);
    588589    const me = actorId(base, slug);
    589590    const keys = getOrCreateKeys(slug);
    590591    const accept = { '@context': 'https://www.w3.org/ns/activitystreams', id: `${me}#accept-${Date.now()}-${rid()}`, type: 'Accept', actor: me, object: act };
    591592    deliver(remote.inbox, accept, `${me}#main-key`, keys.private_pem).catch((e) => console.warn('[AP] Accept delivery failed:', e.message));
    592     // Auto-backfill: send the new follower our recent posts as Create so their
    593     // timeline isn't empty (Mastodon doesn't fetch history on follow). Fire-and-forget.
    594     backfillNewFollower(base, slug, remote.inbox).catch(() => { /* best-effort */ });
     593    // Auto-backfill: send our recent posts as Create so the instance has our history
     594    // (Mastodon doesn't fetch history on follow). ONCE PER REMOTE INSTANCE only —
     595    // Mastodon dedupes notes per-instance, so re-filling an instance that already has
     596    // a follower of ours is wasted work (and won't re-populate the new follower's
     597    // timeline anyway). Deliver to the shared inbox (instance-level) when present.
     598    // Sync insert+check (no await between) → no interleave race with concurrent Follows.
     599    const instanceFilled = sharedInbox &&
     600      db.prepare('SELECT 1 FROM ap_followers WHERE slug = ? AND shared_inbox = ? AND actor_uri != ? LIMIT 1')
     601        .get(slug, sharedInbox, who);
     602    if (!instanceFilled) {
     603      backfillNewFollower(base, slug, sharedInbox || remote.inbox).catch(() => { /* best-effort */ });
     604    }
    595605    console.log('[AP] Follow', who, '→', slug, verified ? '(sig ok)' : '(sig unverified)');
    596606    return 202;
Note: See TracChangeset for help on using the changeset viewer.