Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place

Add firehose negative cache

+22 -2
+2
apps/hosting-service/.env.example
··· 8 8 9 9 # Redis (cache invalidation + revalidation queue) 10 10 REDIS_URL=redis://localhost:6379 11 + WISP_REVALIDATE_DEDUPE_TTL_SECONDS=60 12 + WISP_REVALIDATE_STORAGE_MISS_DEDUPE_TTL_SECONDS=600 11 13 12 14 # S3 Storage (leave empty for local disk fallback) 13 15 S3_BUCKET=
+20 -2
apps/hosting-service/src/lib/revalidate-queue.ts
··· 3 3 4 4 const redisUrl = process.env.REDIS_URL; 5 5 const streamName = process.env.WISP_REVALIDATE_STREAM || 'wisp:revalidate'; 6 - const dedupeTtlSeconds = Number.parseInt(process.env.WISP_REVALIDATE_DEDUPE_TTL_SECONDS || '60', 10); 6 + const dedupeTtlSeconds = parsePositiveInt(process.env.WISP_REVALIDATE_DEDUPE_TTL_SECONDS, 60); 7 + const storageMissDedupeTtlSeconds = parsePositiveInt( 8 + process.env.WISP_REVALIDATE_STORAGE_MISS_DEDUPE_TTL_SECONDS, 9 + Math.max(dedupeTtlSeconds, 600) 10 + ); 7 11 8 12 let client: Redis | null = null; 9 13 let loggedMissingRedis = false; 14 + 15 + function parsePositiveInt(value: string | undefined, fallback: number): number { 16 + if (!value) return fallback; 17 + const parsed = Number.parseInt(value, 10); 18 + return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; 19 + } 20 + 21 + function getDedupeTtlSeconds(reasonCategory: 'storage-miss' | 'rewrite-miss' | 'other'): number { 22 + if (reasonCategory === 'storage-miss') { 23 + return storageMissDedupeTtlSeconds; 24 + } 25 + return dedupeTtlSeconds; 26 + } 10 27 11 28 function getRedisClient(): Redis | null { 12 29 if (!redisUrl) { ··· 56 73 : reason.startsWith('rewrite-miss') ? 'rewrite-miss' 57 74 : 'other'; 58 75 const dedupeKey = `revalidate:site:${reasonCategory}:${did}:${rkey}`; 59 - const set = await redis.set(dedupeKey, '1', 'EX', dedupeTtlSeconds, 'NX'); 76 + const dedupeTtl = getDedupeTtlSeconds(reasonCategory); 77 + const set = await redis.set(dedupeKey, '1', 'EX', dedupeTtl, 'NX'); 60 78 if (!set) { 61 79 recordRevalidateResult('deduped'); 62 80 return { enqueued: false, result: 'deduped' };