+11
-1
hosting-service/src/index.ts
+11
-1
hosting-service/src/index.ts
···
4
4
import { logger } from './lib/observability';
5
5
import { mkdirSync, existsSync } from 'fs';
6
6
import { backfillCache } from './lib/backfill';
7
-
import { startDomainCacheCleanup, stopDomainCacheCleanup } from './lib/db';
7
+
import { startDomainCacheCleanup, stopDomainCacheCleanup, setCacheOnlyMode } from './lib/db';
8
8
9
9
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3001;
10
10
const CACHE_DIR = process.env.CACHE_DIR || './cache/sites';
···
13
13
const args = process.argv.slice(2);
14
14
const hasBackfillFlag = args.includes('--backfill');
15
15
const backfillOnStartup = hasBackfillFlag || process.env.BACKFILL_ON_STARTUP === 'true';
16
+
17
+
// Cache-only mode: service will only cache files locally, no DB writes
18
+
const hasCacheOnlyFlag = args.includes('--cache-only');
19
+
export const CACHE_ONLY_MODE = hasCacheOnlyFlag || process.env.CACHE_ONLY_MODE === 'true';
20
+
21
+
// Configure cache-only mode in database module
22
+
if (CACHE_ONLY_MODE) {
23
+
setCacheOnlyMode(true);
24
+
}
16
25
17
26
// Ensure cache directory exists
18
27
if (!existsSync(CACHE_DIR)) {
···
65
74
Health: http://localhost:${PORT}/health
66
75
Cache: ${CACHE_DIR}
67
76
Firehose: Connected to Firehose
77
+
Cache-Only: ${CACHE_ONLY_MODE ? 'ENABLED (no DB writes)' : 'DISABLED'}
68
78
`);
69
79
70
80
// Graceful shutdown
+16
hosting-service/src/lib/db.ts
+16
hosting-service/src/lib/db.ts
···
1
1
import postgres from 'postgres';
2
2
import { createHash } from 'crypto';
3
3
4
+
// Global cache-only mode flag (set by index.ts)
5
+
let cacheOnlyMode = false;
6
+
7
+
export function setCacheOnlyMode(enabled: boolean) {
8
+
cacheOnlyMode = enabled;
9
+
if (enabled) {
10
+
console.log('[DB] Cache-only mode enabled - database writes will be skipped');
11
+
}
12
+
}
13
+
4
14
const sql = postgres(
5
15
process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/wisp',
6
16
{
···
130
140
}
131
141
132
142
export async function upsertSite(did: string, rkey: string, displayName?: string) {
143
+
// Skip database writes in cache-only mode
144
+
if (cacheOnlyMode) {
145
+
console.log('[DB] Skipping upsertSite (cache-only mode)', { did, rkey });
146
+
return;
147
+
}
148
+
133
149
try {
134
150
// Only set display_name if provided (not undefined/null/empty)
135
151
const cleanDisplayName = displayName && displayName.trim() ? displayName.trim() : null;
+2
hosting-service/src/lib/firehose.ts
+2
hosting-service/src/lib/firehose.ts
···
197
197
)
198
198
199
199
// Acquire distributed lock only for database write to prevent duplicate writes
200
+
// Note: upsertSite will check cache-only mode internally and skip if needed
200
201
const lockKey = `db:upsert:${did}:${site}`
201
202
const lockAcquired = await tryAcquireLock(lockKey)
202
203
···
214
215
215
216
try {
216
217
// Upsert site to database (only one instance does this)
218
+
// In cache-only mode, this will be a no-op
217
219
await upsertSite(did, site, fsRecord.site)
218
220
this.log(
219
221
'Successfully processed create/update (cached + DB updated)',