diff --git a/src/server/features/domain/services/DomainService.ts b/src/server/features/domain/services/DomainService.ts index f7be38e0..23338519 100644 --- a/src/server/features/domain/services/DomainService.ts +++ b/src/server/features/domain/services/DomainService.ts @@ -1,3 +1,4 @@ +import { waitUntil } from "cloudflare:workers"; import { buildCacheKey, getCached, setCached } from "@/server/lib/r2-cache"; import { z } from "zod"; import type { BillingCustomerContext } from "@/server/billing/subscription"; @@ -90,10 +91,14 @@ async function getOverview( }; if (result.hasData) { - void setCached(cacheKey, result, DOMAIN_OVERVIEW_TTL_SECONDS).catch( - (error) => { - console.error("domain.overview.cache-write failed:", error); - }, + // waitUntil, not void: workerd cancels unregistered pending I/O once the + // response is sent, so a fire-and-forget put never persists the cache. + waitUntil( + setCached(cacheKey, result, DOMAIN_OVERVIEW_TTL_SECONDS).catch( + (error) => { + console.error("domain.overview.cache-write failed:", error); + }, + ), ); } @@ -174,10 +179,15 @@ async function getSuggestedKeywords( })); if (keywords.length > 0) { - void setCached(cacheKey, keywords, DOMAIN_OVERVIEW_TTL_SECONDS).catch( - (error) => { - console.error("domain.keyword-suggestions.cache-write failed:", error); - }, + waitUntil( + setCached(cacheKey, keywords, DOMAIN_OVERVIEW_TTL_SECONDS).catch( + (error) => { + console.error( + "domain.keyword-suggestions.cache-write failed:", + error, + ); + }, + ), ); } diff --git a/src/server/features/domain/services/domainKeywordsPage.ts b/src/server/features/domain/services/domainKeywordsPage.ts index d57bfeb6..995911ce 100644 --- a/src/server/features/domain/services/domainKeywordsPage.ts +++ b/src/server/features/domain/services/domainKeywordsPage.ts @@ -1,3 +1,4 @@ +import { waitUntil } from "cloudflare:workers"; import { z } from "zod"; import type { BillingCustomerContext } from "@/server/billing/subscription"; import { createDataforseoClient } from "@/server/lib/dataforseo"; @@ -113,10 +114,14 @@ export async function getKeywordsPage( fetchedAt: new Date().toISOString(), }; - void setCached(cacheKey, result, DOMAIN_KEYWORDS_PAGE_TTL_SECONDS).catch( - (error) => { - console.error("domain.keywords-page.cache-write failed:", error); - }, + // waitUntil, not void: workerd cancels unregistered pending I/O once the + // response is sent, so a fire-and-forget put never persists the cache. + waitUntil( + setCached(cacheKey, result, DOMAIN_KEYWORDS_PAGE_TTL_SECONDS).catch( + (error) => { + console.error("domain.keywords-page.cache-write failed:", error); + }, + ), ); return result; diff --git a/src/server/features/domain/services/domainPagesPage.ts b/src/server/features/domain/services/domainPagesPage.ts index 4475ad87..1fbd9c0f 100644 --- a/src/server/features/domain/services/domainPagesPage.ts +++ b/src/server/features/domain/services/domainPagesPage.ts @@ -1,3 +1,4 @@ +import { waitUntil } from "cloudflare:workers"; import { z } from "zod"; import type { BillingCustomerContext } from "@/server/billing/subscription"; import { createDataforseoClient } from "@/server/lib/dataforseo"; @@ -193,10 +194,14 @@ export async function getPagesPage( fetchedAt: new Date().toISOString(), }; - void setCached(cacheKey, result, DOMAIN_PAGES_PAGE_TTL_SECONDS).catch( - (error) => { - console.error("domain.pages-page.cache-write failed:", error); - }, + // waitUntil, not void: workerd cancels unregistered pending I/O once the + // response is sent, so a fire-and-forget put never persists the cache. + waitUntil( + setCached(cacheKey, result, DOMAIN_PAGES_PAGE_TTL_SECONDS).catch( + (error) => { + console.error("domain.pages-page.cache-write failed:", error); + }, + ), ); return result; diff --git a/src/server/features/keywords/services/research/serp.ts b/src/server/features/keywords/services/research/serp.ts index 2339d729..7fde9405 100644 --- a/src/server/features/keywords/services/research/serp.ts +++ b/src/server/features/keywords/services/research/serp.ts @@ -1,3 +1,4 @@ +import { waitUntil } from "cloudflare:workers"; import { type SerpLiveItem } from "@/server/lib/dataforseo"; import { buildCacheKey, getCached, setCached } from "@/server/lib/r2-cache"; import type { SerpResultItem } from "@/types/keywords"; @@ -91,9 +92,13 @@ async function getSerpLiveAnalysis( result.reason = "no_organic_results"; } - void setCached(cacheKey, result, SERP_CACHE_TTL_SECONDS).catch((error) => { - console.error("keywords.serp.cache-write failed:", error); - }); + // waitUntil, not void: workerd cancels unregistered pending I/O once the + // response is sent, so a fire-and-forget put never persists the cache. + waitUntil( + setCached(cacheKey, result, SERP_CACHE_TTL_SECONDS).catch((error) => { + console.error("keywords.serp.cache-write failed:", error); + }), + ); return result; }