fix: harden unfurl timeout + persist CI fetch cache
- Add hard 22s Promise.race deadline in prefetchUrl() to guard against TCP-level connection hangs that bypass unfurl.js's read-only timeout. Fixes builds hanging indefinitely on unresponsive hosts. - Add actions/cache step to deploy.yml persisting .cache/ between runs. Prevents webmention (and all eleventy-fetch) data loss on transient 502s: a populated cache means failures return existing data, not []. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
8
.github/workflows/deploy.yml
vendored
8
.github/workflows/deploy.yml
vendored
@@ -32,6 +32,14 @@ jobs:
|
||||
"sudo bastille cmd node cat /usr/local/indiekit/content/.indiekit/homepage.json" \
|
||||
> content/.indiekit/homepage.json
|
||||
|
||||
- name: Cache Eleventy fetch cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .cache
|
||||
key: eleventy-fetch-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: |
|
||||
eleventy-fetch-${{ runner.os }}-
|
||||
|
||||
- name: Build CSS
|
||||
run: npm run build:css
|
||||
|
||||
|
||||
@@ -132,10 +132,15 @@ export async function prefetchUrl(url) {
|
||||
|
||||
const metadata = await throttled(async () => {
|
||||
try {
|
||||
return await unfurl(url, {
|
||||
timeout: 20000,
|
||||
headers: { "User-Agent": USER_AGENT },
|
||||
});
|
||||
// Hard outer deadline guards against TCP-level hangs that bypass unfurl's
|
||||
// own timeout (which only covers HTTP read, not connection establishment).
|
||||
const deadline = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error("hard deadline 22s")), 22000)
|
||||
);
|
||||
return await Promise.race([
|
||||
unfurl(url, { timeout: 18000, headers: { "User-Agent": USER_AGENT } }),
|
||||
deadline,
|
||||
]);
|
||||
} catch (err) {
|
||||
console.warn(`[unfurl] Failed to fetch ${url}: ${err.message}`);
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user