const SESSION_CACHE_TTL_MS = 5000 type SessionCacheSource = "memory" | "shared" | "redis" interface SessionCacheEntry { data: T expiresAt: number } const sessionCache = new Map>() const inflightSessionLoads = new Map>() const getNow = () => Date.now() const getValidCachedSession = (redisKey: string) => { const cacheEntry = sessionCache.get(redisKey) if (!cacheEntry) { return null } if (cacheEntry.expiresAt <= getNow()) { sessionCache.delete(redisKey) return null } return cacheEntry.data as T } export const getCachedSession = (redisKey: string) => getValidCachedSession(redisKey) export const setCachedSession = (redisKey: string, data: T) => { sessionCache.set(redisKey, { data, expiresAt: getNow() + SESSION_CACHE_TTL_MS, }) } export const deleteCachedSession = (redisKey: string) => { sessionCache.delete(redisKey) inflightSessionLoads.delete(redisKey) } export const getSessionCacheTtlMs = () => SESSION_CACHE_TTL_MS export const getOrLoadSession = async ( redisKey: string, loader: () => Promise ): Promise<{ data: T | null source: SessionCacheSource }> => { const cachedData = getValidCachedSession(redisKey) if (cachedData) { return { data: cachedData, source: "memory", } } const inflightLoad = inflightSessionLoads.get(redisKey) if (inflightLoad) { return { data: (await inflightLoad) as T | null, source: "shared", } } const loadPromise = (async () => { const loadedData = await loader() if (loadedData) { setCachedSession(redisKey, loadedData) } else { deleteCachedSession(redisKey) } return loadedData })() inflightSessionLoads.set(redisKey, loadPromise) try { return { data: await loadPromise, source: "redis", } } finally { if (inflightSessionLoads.get(redisKey) === loadPromise) { inflightSessionLoads.delete(redisKey) } } }