From 0ae3d835cdc4f6864a3204a3f47190da1bed807a Mon Sep 17 00:00:00 2001 From: Sven Date: Sun, 3 May 2026 12:39:29 +0200 Subject: [PATCH] Add patch: touchKeyFreshness() fire-and-forget in inbox-listeners.js 11x 'await touchKeyFreshness()' blocks AP inbox processing on a non-critical tracking write. Under burst traffic this caused 8s delays (seen in profiling). Removing await + .catch(() => {}) mirrors the function's own error handling and lets inbox listeners complete without waiting for the DB write. --- .../patch-ap-key-freshness-nonblocking.mjs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 scripts/patch-ap-key-freshness-nonblocking.mjs diff --git a/scripts/patch-ap-key-freshness-nonblocking.mjs b/scripts/patch-ap-key-freshness-nonblocking.mjs new file mode 100644 index 00000000..cd78807d --- /dev/null +++ b/scripts/patch-ap-key-freshness-nonblocking.mjs @@ -0,0 +1,55 @@ +/** + * Patch: make touchKeyFreshness() fire-and-forget in inbox-listeners.js. + * + * touchKeyFreshness() is non-critical tracking (records lastSeenAt on + * ap_key_freshness). Under burst AP traffic, 11 parallel awaited upserts + * compete for MongoDB write locks — profiling shows 8-second delays on + * this single call while holding up inbox processing. + * + * Removing the await means inbox listeners don't block on the tracking + * write. The .catch(() => {}) mirrors the existing error handling inside + * the function itself. + */ + +import { access, readFile, writeFile } from "node:fs/promises"; + +const candidates = [ + "node_modules/@rmdes/indiekit-endpoint-activitypub/lib/inbox-listeners.js", + "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-activitypub/lib/inbox-listeners.js", +]; + +const MARKER = "// [patch] key-freshness-nonblocking"; + +async function exists(p) { + try { await access(p); return true; } catch { return false; } +} + +let patched = false; +for (const filePath of candidates) { + if (!(await exists(filePath))) continue; + let src = await readFile(filePath, "utf8"); + if (src.includes(MARKER)) { + console.log(`[postinstall] patch-ap-key-freshness-nonblocking: already applied in ${filePath}`); + patched = true; + break; + } + const before = src; + // Replace all: await touchKeyFreshness(...) → touchKeyFreshness(...).catch(() => {}) + src = src.replace( + /await touchKeyFreshness\(([^)]+)\);/g, + `touchKeyFreshness($1).catch(() => {}); ${MARKER}`, + ); + const count = (src.match(/key-freshness-nonblocking/g) || []).length; + if (count === 0) { + console.log(`[postinstall] patch-ap-key-freshness-nonblocking: target not found in ${filePath}`); + continue; + } + await writeFile(filePath, src, "utf8"); + console.log(`[postinstall] patch-ap-key-freshness-nonblocking: applied to ${count} calls in ${filePath}`); + patched = true; + break; +} + +if (!patched) { + console.log("[postinstall] patch-ap-key-freshness-nonblocking: no target file found"); +}