feat: defer background tasks until host readiness signal

This commit is contained in:
Ricardo
2026-03-28 22:18:24 +01:00
parent 6436763dab
commit d52869a50b
2 changed files with 62 additions and 55 deletions
+25 -19
View File
@@ -1,4 +1,5 @@
import express from "express";
import { waitForReady } from "@rmdes/indiekit-startup-gate";
import { setupFederation, buildPersonActor } from "./lib/federation-setup.js";
import { createMastodonRouter } from "./lib/mastodon/router.js";
@@ -1096,19 +1097,6 @@ export default class ActivityPubEndpoint {
// Register syndicator (appears in post editing UI)
Indiekit.addSyndicator(this.syndicator);
// Start batch re-follow processor after federation settles
const refollowOptions = {
federation: this._federation,
collections: this._collections,
handle: this.options.actor.handle,
publicationUrl: this._publicationUrl,
};
setTimeout(() => {
startBatchRefollow(refollowOptions).catch((error) => {
console.error("[ActivityPub] Batch refollow start failed:", error.message);
});
}, 10_000);
// Run one-time migrations (idempotent — safe to run on every startup)
console.info("[ActivityPub] Init: starting post-refollow setup");
runSeparateMentionsMigration(this._collections).then(({ skipped, updated }) => {
@@ -1119,6 +1107,23 @@ export default class ActivityPubEndpoint {
console.error("[ActivityPub] Migration separate-mentions failed:", error.message);
});
// Defer background workers until host is ready
const refollowOptions = {
federation: this._federation,
collections: this._collections,
handle: this.options.actor.handle,
publicationUrl: this._publicationUrl,
};
const keyRefreshHandle = this.options.actor.handle;
const keyRefreshFederation = this._federation;
const keyRefreshPubUrl = this._publicationUrl;
this._stopGate = waitForReady(
() => {
// Start batch re-follow processor
startBatchRefollow(refollowOptions).catch((error) => {
console.error("[ActivityPub] Batch refollow start failed:", error.message);
});
// Schedule timeline retention cleanup (runs on startup + every 24h)
if (this.options.timelineRetention > 0) {
scheduleCleanup(this._collections, this.options.timelineRetention);
@@ -1130,9 +1135,6 @@ export default class ActivityPubEndpoint {
});
// Schedule proactive key refresh for stale follower keys (runs on startup + every 24h)
const keyRefreshHandle = this.options.actor.handle;
const keyRefreshFederation = this._federation;
const keyRefreshPubUrl = this._publicationUrl;
scheduleKeyRefresh(
this._collections,
() => keyRefreshFederation?.createContext(new URL(keyRefreshPubUrl), {
@@ -1144,8 +1146,6 @@ export default class ActivityPubEndpoint {
// Backfill ap_timeline from posts collection (idempotent, runs on every startup)
import("./lib/mastodon/backfill-timeline.js").then(({ backfillTimeline }) => {
// Delay to let MongoDB connections settle
setTimeout(() => {
backfillTimeline(this._collections).then(({ total, inserted, skipped }) => {
if (inserted > 0) {
console.log(`[Mastodon API] Timeline backfill: ${inserted} posts added (${skipped} already existed, ${total} total)`);
@@ -1153,7 +1153,6 @@ export default class ActivityPubEndpoint {
}).catch((error) => {
console.warn("[Mastodon API] Timeline backfill failed:", error.message);
});
}, 5000);
});
// Start async inbox queue processor (processes one item every 3s)
@@ -1166,6 +1165,9 @@ export default class ActivityPubEndpoint {
}),
this.options.actor.handle,
);
},
{ label: "ActivityPub" },
);
}
/**
@@ -1198,4 +1200,8 @@ export default class ActivityPubEndpoint {
await ap_profile.insertOne(profile);
}
destroy() {
this._stopGate?.();
}
}
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@rmdes/indiekit-endpoint-activitypub",
"version": "3.10.3",
"version": "3.10.4",
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
"keywords": [
"indiekit",
@@ -38,6 +38,7 @@
},
"dependencies": {
"@fedify/debugger": "^2.1.0",
"@rmdes/indiekit-startup-gate": "^1.0.0",
"@fedify/fedify": "^2.1.0",
"@fedify/redis": "^2.1.0",
"@js-temporal/polyfill": "^0.5.0",