mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-11-09 13:44:29 +08:00
added LRU cache to avoid asking firebase to decode the tokens
added prometheus metrics for the token cache
This commit is contained in:
parent
61626aa44d
commit
a54eb3a3bb
2 changed files with 66 additions and 1 deletions
|
|
@ -1,9 +1,44 @@
|
|||
import admin from "firebase-admin";
|
||||
import { UserRecord } from "firebase-admin/lib/auth/user-record";
|
||||
import { DecodedIdToken } from "firebase-admin/lib/auth/token-verifier";
|
||||
import LRUCache from "lru-cache";
|
||||
import {
|
||||
recordTokenCacheAccess,
|
||||
setTokenCacheLength,
|
||||
setTokenCacheSize,
|
||||
} from "./prometheus";
|
||||
|
||||
const tokenCache = new LRUCache<string, DecodedIdToken>({
|
||||
max: 20000,
|
||||
maxSize: 20000000, // 20MB
|
||||
sizeCalculation: (token, key): number =>
|
||||
JSON.stringify(token).length + key.length, //sizeInBytes
|
||||
});
|
||||
|
||||
const TOKEN_CACHE_BUFFER = 1000 * 60 * 5; // 5 minutes
|
||||
|
||||
export async function verifyIdToken(idToken: string): Promise<DecodedIdToken> {
|
||||
return await admin.auth().verifyIdToken(idToken, true);
|
||||
setTokenCacheLength(tokenCache.size);
|
||||
setTokenCacheSize(tokenCache.calculatedSize ?? 0);
|
||||
|
||||
const cached = tokenCache.get(idToken);
|
||||
|
||||
if (cached) {
|
||||
const expirationDate = (cached.exp - TOKEN_CACHE_BUFFER) * 1000;
|
||||
|
||||
if (expirationDate > Date.now()) {
|
||||
recordTokenCacheAccess("hit_expired");
|
||||
tokenCache.delete(idToken);
|
||||
} else {
|
||||
recordTokenCacheAccess("hit");
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
recordTokenCacheAccess("miss");
|
||||
|
||||
const decoded = await admin.auth().verifyIdToken(idToken, true);
|
||||
tokenCache.set(idToken, decoded);
|
||||
return decoded;
|
||||
}
|
||||
|
||||
export async function updateUserEmail(
|
||||
|
|
|
|||
|
|
@ -227,3 +227,33 @@ export function recordRequestCountry(
|
|||
|
||||
requestCountry.inc({ path: pathNoGet, country });
|
||||
}
|
||||
|
||||
const tokenCacheAccess = new Counter({
|
||||
name: "api_token_cache_access",
|
||||
help: "Token cache access",
|
||||
labelNames: ["status"],
|
||||
});
|
||||
|
||||
export function recordTokenCacheAccess(
|
||||
status: "hit" | "miss" | "hit_expired"
|
||||
): void {
|
||||
tokenCacheAccess.inc({ status });
|
||||
}
|
||||
|
||||
const tokenCacheSize = new Gauge({
|
||||
name: "api_token_cache_size",
|
||||
help: "Token cache size",
|
||||
});
|
||||
|
||||
export function setTokenCacheSize(size: number): void {
|
||||
tokenCacheSize.set(size);
|
||||
}
|
||||
|
||||
const tokenCacheLength = new Gauge({
|
||||
name: "api_token_cache_length",
|
||||
help: "Token cache length",
|
||||
});
|
||||
|
||||
export function setTokenCacheLength(length: number): void {
|
||||
tokenCacheLength.set(length);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue