Merged in feat/redis-fix (pull request #3207)
Feat/redis fix * feat(redis): delete multiple keys in one partition scan * fix(BOOK-603): make it possible to do multiple deletes in redis at once using one partition scan Approved-by: Linus Flood
This commit is contained in:
@@ -99,4 +99,12 @@ export type DataCache = {
|
||||
* @returns
|
||||
*/
|
||||
deleteKey: (key: string, opts?: { fuzzy?: boolean }) => Promise<void>
|
||||
|
||||
/**
|
||||
* Deletes a key from the cache
|
||||
* @param keys CacheKeys to delete
|
||||
* @param fuzzy If true, does a wildcard delete. *key*
|
||||
* @returns
|
||||
*/
|
||||
deleteKeys: (keys: string[], opts?: { fuzzy?: boolean }) => Promise<void>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { cacheOrGet } from "./cacheOrGet"
|
||||
import { deleteKey } from "./deleteKey"
|
||||
import { deleteKeys } from "./deleteKeys"
|
||||
import { get } from "./get"
|
||||
import { set } from "./set"
|
||||
|
||||
@@ -12,5 +13,6 @@ export async function createDistributedCache(): Promise<DataCache> {
|
||||
set,
|
||||
cacheOrGet,
|
||||
deleteKey,
|
||||
deleteKeys,
|
||||
} satisfies DataCache
|
||||
}
|
||||
|
||||
45
packages/common/dataCache/DistributedCache/deleteKeys.ts
Normal file
45
packages/common/dataCache/DistributedCache/deleteKeys.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import * as Sentry from "@sentry/nextjs"
|
||||
|
||||
import { env } from "../../env/server"
|
||||
import { safeTry } from "../../utils/safeTry"
|
||||
import { cacheLogger } from "../logger"
|
||||
import { getDeleteMultipleKeysEndpoint } from "./endpoints"
|
||||
|
||||
const API_KEY = env.REDIS_API_KEY ?? ""
|
||||
export async function deleteKeys(keys: string[], opts?: { fuzzy?: boolean }) {
|
||||
const perf = performance.now()
|
||||
const endpoint = getDeleteMultipleKeysEndpoint()
|
||||
|
||||
const [response, error] = await safeTry(
|
||||
fetch(endpoint, {
|
||||
method: "DELETE",
|
||||
cache: "no-cache",
|
||||
headers: {
|
||||
"x-api-key": API_KEY,
|
||||
},
|
||||
body: JSON.stringify({ keys, fuzzy: opts?.fuzzy ?? false }),
|
||||
signal: AbortSignal.timeout(10_000),
|
||||
})
|
||||
)
|
||||
|
||||
if (!response || !response.ok || error) {
|
||||
if (response?.status !== 404) {
|
||||
Sentry.captureException(
|
||||
error ?? new Error("Unable to DELETE cachekeys"),
|
||||
{
|
||||
extra: {
|
||||
cacheKeys: keys,
|
||||
statusCode: response?.status,
|
||||
statusText: response?.statusText,
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
cacheLogger.debug(
|
||||
`Deleted '${keys.join(", ")}' took ${(performance.now() - perf).toFixed(2)}ms`
|
||||
)
|
||||
}
|
||||
@@ -10,3 +10,13 @@ export function getCacheEndpoint(key: string) {
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
export function getDeleteMultipleKeysEndpoint() {
|
||||
if (!env.REDIS_API_HOST) {
|
||||
throw new Error("REDIS_API_HOST is not set")
|
||||
}
|
||||
|
||||
const url = new URL(`/api/cache/multiple`, env.REDIS_API_HOST)
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { cacheLogger } from "../../logger"
|
||||
import { cacheMap } from "./cacheMap"
|
||||
|
||||
export async function deleteKeys(keys: string[], opts?: { fuzzy?: boolean }) {
|
||||
cacheLogger.debug("Deleting keys", keys)
|
||||
keys.forEach((key) => {
|
||||
if (opts?.fuzzy) {
|
||||
cacheMap.forEach((_, k) => {
|
||||
if (k.includes(key)) {
|
||||
cacheMap.delete(k)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
cacheMap.delete(key)
|
||||
})
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { cacheOrGet } from "./cacheOrGet"
|
||||
import { deleteKey } from "./deleteKey"
|
||||
import { deleteKeys } from "./deleteKeys"
|
||||
import { get } from "./get"
|
||||
import { set } from "./set"
|
||||
|
||||
import type { DataCache } from "../../Cache"
|
||||
|
||||
export async function createInMemoryCache(): Promise<DataCache> {
|
||||
return { type: "in-memory", cacheOrGet, deleteKey, get, set }
|
||||
return { type: "in-memory", cacheOrGet, deleteKey, get, set, deleteKeys }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user