Merged in feature/redis (pull request #1478)
Distributed cache * cache deleteKey now uses an options object instead of a lonely argument variable fuzzy * merge * remove debug logs and cleanup * cleanup * add fault handling * add fault handling * add pid when logging redis client creation * add identifier when logging redis client creation * cleanup * feat: add redis-api as it's own app * feature: use http wrapper for redis * feat: add the possibility to fallback to unstable_cache * Add error handling if redis cache is unresponsive * add logging for unstable_cache * merge * don't cache errors * fix: metadatabase on branchdeploys * Handle when /en/destinations throws add ErrorBoundary * Add sentry-logging when ErrorBoundary catches exception * Fix error handling for distributed cache * cleanup code * Added Application Insights back * Update generateApiKeys script and remove duplicate * Merge branch 'feature/redis' of bitbucket.org:scandic-swap/web into feature/redis * merge Approved-by: Linus Flood
This commit is contained in:
committed by
Linus Flood
parent
a8304e543e
commit
fa63b20ed0
@@ -1,9 +1,8 @@
|
||||
import { metrics } from "@opentelemetry/api"
|
||||
import { revalidateTag, unstable_cache } from "next/cache"
|
||||
import { metrics, trace } from "@opentelemetry/api"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import { generateServiceTokenTag } from "@/utils/generateTag"
|
||||
import { getCacheClient } from "@/services/dataCache"
|
||||
|
||||
import type { ServiceTokenResponse } from "@/types/tokens"
|
||||
|
||||
@@ -12,13 +11,49 @@ const meter = metrics.getMeter("trpc.context.serviceToken")
|
||||
const fetchServiceTokenCounter = meter.createCounter(
|
||||
"trpc.context.serviceToken.fetch-new-token"
|
||||
)
|
||||
const fetchTempServiceTokenCounter = meter.createCounter(
|
||||
"trpc.context.serviceToken.fetch-temporary"
|
||||
)
|
||||
|
||||
const fetchServiceTokenFailCounter = meter.createCounter(
|
||||
"trpc.context.serviceToken.fetch-fail"
|
||||
)
|
||||
|
||||
export async function getServiceToken() {
|
||||
const tracer = trace.getTracer("getServiceToken")
|
||||
|
||||
return await tracer.startActiveSpan("getServiceToken", async () => {
|
||||
let scopes: string[] = []
|
||||
if (env.ENABLE_BOOKING_FLOW) {
|
||||
scopes = ["profile", "hotel", "booking", "package", "availability"]
|
||||
} else {
|
||||
scopes = ["profile"]
|
||||
}
|
||||
const cacheKey = getServiceTokenCacheKey(scopes)
|
||||
|
||||
const cacheClient = await getCacheClient()
|
||||
const token =
|
||||
await cacheClient.get<Awaited<ReturnType<typeof getJwt>>>(cacheKey)
|
||||
console.log("[DEBUG] getServiceToken", typeof token, token)
|
||||
if (!token || token.expiresAt < Date.now()) {
|
||||
return await tracer.startActiveSpan("fetch new token", async () => {
|
||||
const newToken = await getJwt(scopes)
|
||||
const relativeTime = (newToken.expiresAt - Date.now()) / 1000
|
||||
await cacheClient.set(cacheKey, newToken, relativeTime)
|
||||
|
||||
return newToken.jwt
|
||||
})
|
||||
}
|
||||
|
||||
return token.jwt
|
||||
})
|
||||
}
|
||||
|
||||
async function getJwt(scopes: string[]) {
|
||||
fetchServiceTokenCounter.add(1)
|
||||
const jwt = await fetchServiceToken(scopes)
|
||||
|
||||
const expiresAt = Date.now() + jwt.expires_in * 1000
|
||||
return { expiresAt, jwt }
|
||||
}
|
||||
|
||||
async function fetchServiceToken(scopes: string[]) {
|
||||
fetchServiceTokenCounter.add(1)
|
||||
|
||||
@@ -69,41 +104,6 @@ async function fetchServiceToken(scopes: string[]) {
|
||||
return response.json() as Promise<ServiceTokenResponse>
|
||||
}
|
||||
|
||||
export async function getServiceToken() {
|
||||
let scopes: string[] = []
|
||||
if (env.ENABLE_BOOKING_FLOW) {
|
||||
scopes = ["profile", "hotel", "booking", "package", "availability"]
|
||||
} else {
|
||||
scopes = ["profile"]
|
||||
}
|
||||
|
||||
const tag = generateServiceTokenTag(scopes)
|
||||
const getCachedJwt = unstable_cache(
|
||||
async (scopes) => {
|
||||
const jwt = await fetchServiceToken(scopes)
|
||||
|
||||
const expiresAt = Date.now() + jwt.expires_in * 1000
|
||||
return { expiresAt, jwt }
|
||||
},
|
||||
[tag],
|
||||
{ tags: [tag] }
|
||||
)
|
||||
|
||||
const cachedJwt = await getCachedJwt(scopes)
|
||||
if (cachedJwt.expiresAt < Date.now()) {
|
||||
console.log(
|
||||
"trpc.context.serviceToken: Service token expired, revalidating tag"
|
||||
)
|
||||
|
||||
revalidateTag(tag)
|
||||
|
||||
console.log(
|
||||
"trpc.context.serviceToken: Fetching new temporary service token."
|
||||
)
|
||||
fetchTempServiceTokenCounter.add(1)
|
||||
const newToken = await fetchServiceToken(scopes)
|
||||
return newToken
|
||||
}
|
||||
|
||||
return cachedJwt.jwt
|
||||
function getServiceTokenCacheKey(scopes: string[]): string {
|
||||
return `serviceToken:${scopes.join(",")}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user