Skip to content

Commit a1b3aa4

Browse files
committed
restore multi-region-safe cache
Closes #1039 References #1038
1 parent fb1f753 commit a1b3aa4

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

app/utils/cache.server.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import fs from 'node:fs'
22
import path from 'node:path'
3-
import { DatabaseSync } from 'node:sqlite'
43
import {
54
cachified as baseCachified,
65
verboseReporter,
@@ -14,7 +13,10 @@ import {
1413
} from '@epic-web/cachified'
1514
import { remember } from '@epic-web/remember'
1615
import { LRUCache } from 'lru-cache'
16+
import { DatabaseSync } from 'node:sqlite'
1717
import { z } from 'zod'
18+
import { updatePrimaryCacheValue } from '#app/routes/admin+/cache_.sqlite.server.ts'
19+
import { getInstanceInfo, getInstanceInfoSync } from './litefs.server.ts'
1820
import { cachifiedTimingReporter, type Timings } from './timing.server.ts'
1921

2022
const CACHE_DATABASE_PATH = process.env.CACHE_DATABASE_PATH
@@ -26,6 +28,8 @@ function createDatabase(tryAgain = true): DatabaseSync {
2628
fs.mkdirSync(parentDir, { recursive: true })
2729

2830
const db = new DatabaseSync(CACHE_DATABASE_PATH)
31+
const { currentIsPrimary } = getInstanceInfoSync()
32+
if (!currentIsPrimary) return db
2933

3034
try {
3135
// create cache table with metadata JSON column and value JSON column if it does not exist already
@@ -136,11 +140,44 @@ export const cache: CachifiedCache = {
136140
return { metadata, value }
137141
},
138142
async set(key, entry) {
139-
const value = JSON.stringify(entry.value, bufferReplacer)
140-
setStatement.run(key, value, JSON.stringify(entry.metadata))
143+
const { currentIsPrimary, primaryInstance } = await getInstanceInfo()
144+
145+
if (currentIsPrimary) {
146+
const value = JSON.stringify(entry.value, bufferReplacer)
147+
setStatement.run(key, value, JSON.stringify(entry.metadata))
148+
} else {
149+
// fire-and-forget cache update
150+
void updatePrimaryCacheValue({
151+
key,
152+
cacheValue: entry,
153+
}).then((response) => {
154+
if (!response.ok) {
155+
console.error(
156+
`Error updating cache value for key "${key}" on primary instance (${primaryInstance}): ${response.status} ${response.statusText}`,
157+
{ entry },
158+
)
159+
}
160+
})
161+
}
141162
},
142163
async delete(key) {
143-
deleteStatement.run(key)
164+
const { currentIsPrimary, primaryInstance } = await getInstanceInfo()
165+
166+
if (currentIsPrimary) {
167+
deleteStatement.run(key)
168+
} else {
169+
// fire-and-forget cache update
170+
void updatePrimaryCacheValue({
171+
key,
172+
cacheValue: undefined,
173+
}).then((response) => {
174+
if (!response.ok) {
175+
console.error(
176+
`Error deleting cache value for key "${key}" on primary instance (${primaryInstance}): ${response.status} ${response.statusText}`,
177+
)
178+
}
179+
})
180+
}
144181
},
145182
}
146183

0 commit comments

Comments
 (0)