mirror of
https://github.com/MrUnknownDE/cloudflare-prometheus-exporter.git
synced 2026-04-19 22:33:44 +02:00
refactor: use WeakMap for client singleton, ignore gql files in biome
- replace string hash cache with WeakMap keyed on rate limiter - auto-GC client when env released - exclude cloudflare/gql files from biome checks
This commit is contained in:
@@ -11,7 +11,9 @@
|
|||||||
"**",
|
"**",
|
||||||
"!worker-configuration.d.ts",
|
"!worker-configuration.d.ts",
|
||||||
"!src/gql/graphql-env.d.ts",
|
"!src/gql/graphql-env.d.ts",
|
||||||
"!src/gql/schema.gql"
|
"!src/gql/schema.gql",
|
||||||
|
"!src/cloudflare/gql/graphql-env.d.ts",
|
||||||
|
"!src/cloudflare/gql/schema.gql"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"formatter": {
|
"formatter": {
|
||||||
|
|||||||
@@ -2379,23 +2379,12 @@ export class CloudflareMetricsClient {
|
|||||||
// Singleton factory
|
// Singleton factory
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
let cachedClient: CloudflareMetricsClient | null = null;
|
const clientCache = new WeakMap<RateLimiter, CloudflareMetricsClient>();
|
||||||
let cachedEnvHash: string | null = null;
|
|
||||||
|
|
||||||
type RateLimiter = {
|
type RateLimiter = {
|
||||||
limit: (opts: { key: string }) => Promise<{ success: boolean }>;
|
limit: (opts: { key: string }) => Promise<{ success: boolean }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates hash from environment for client caching.
|
|
||||||
*
|
|
||||||
* @param env Environment variables.
|
|
||||||
* @returns Hash string (API token).
|
|
||||||
*/
|
|
||||||
function envHash(env: Env): string {
|
|
||||||
return env.CLOUDFLARE_API_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
const MAX_RETRIES = 3;
|
const MAX_RETRIES = 3;
|
||||||
const BASE_DELAY_MS = 250;
|
const BASE_DELAY_MS = 250;
|
||||||
|
|
||||||
@@ -2433,16 +2422,16 @@ function createRateLimitedFetch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or creates singleton CloudflareMetricsClient with rate limiting and env-based caching.
|
* Gets or creates singleton CloudflareMetricsClient with rate limiting.
|
||||||
|
* Uses WeakMap keyed on rate limiter for automatic GC when env is released.
|
||||||
*
|
*
|
||||||
* @param env Environment variables.
|
* @param env Environment variables.
|
||||||
* @returns CloudflareMetricsClient singleton instance.
|
* @returns CloudflareMetricsClient singleton instance.
|
||||||
*/
|
*/
|
||||||
export function getCloudflareMetricsClient(env: Env): CloudflareMetricsClient {
|
export function getCloudflareMetricsClient(env: Env): CloudflareMetricsClient {
|
||||||
const currentHash = envHash(env);
|
const existing = clientCache.get(env.CF_API_RATE_LIMITER);
|
||||||
|
if (existing) {
|
||||||
if (cachedClient && cachedEnvHash === currentHash) {
|
return existing;
|
||||||
return cachedClient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const loggerConfig = configFromEnv(env);
|
const loggerConfig = configFromEnv(env);
|
||||||
@@ -2459,7 +2448,7 @@ export function getCloudflareMetricsClient(env: Env): CloudflareMetricsClient {
|
|||||||
logger,
|
logger,
|
||||||
);
|
);
|
||||||
|
|
||||||
cachedClient = new CloudflareMetricsClient({
|
const client = new CloudflareMetricsClient({
|
||||||
apiToken: env.CLOUDFLARE_API_TOKEN,
|
apiToken: env.CLOUDFLARE_API_TOKEN,
|
||||||
scrapeDelaySeconds: env.SCRAPE_DELAY_SECONDS,
|
scrapeDelaySeconds: env.SCRAPE_DELAY_SECONDS,
|
||||||
timeWindowSeconds: env.TIME_WINDOW_SECONDS,
|
timeWindowSeconds: env.TIME_WINDOW_SECONDS,
|
||||||
@@ -2468,6 +2457,6 @@ export function getCloudflareMetricsClient(env: Env): CloudflareMetricsClient {
|
|||||||
fetch: rateLimitedFetch,
|
fetch: rateLimitedFetch,
|
||||||
});
|
});
|
||||||
|
|
||||||
cachedEnvHash = currentHash;
|
clientCache.set(env.CF_API_RATE_LIMITER, client);
|
||||||
return cachedClient;
|
return client;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user