From a76ced3e0441b2d4acdb5b43dd41b4d1691f04a6 Mon Sep 17 00:00:00 2001 From: julianpoyourow Date: Tue, 19 Nov 2024 16:38:49 +0000 Subject: [PATCH] feat(auth): various Strapi fixes Because - We want to spread out any flood of cache resets (unlikely since servers take varying amounts of time to spin up, but possible) - We want to wait on a pending cachable request between reset periods, simply due to the sheer number of requests that could go through in the interval during a cache reset period. - We want to enable Strapi in "shadow mode" to log potential mismatches This commit - Adds a random spread to cache reset interval - Waits on pending cachable requests - Enables Strapi in key_server if config is present --- libs/shared/cms/src/lib/strapi.client.ts | 38 +++++++++++++++------- packages/fxa-auth-server/bin/key_server.js | 8 ++++- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/libs/shared/cms/src/lib/strapi.client.ts b/libs/shared/cms/src/lib/strapi.client.ts index a26f3f05d6..fb0f31c4a1 100644 --- a/libs/shared/cms/src/lib/strapi.client.ts +++ b/libs/shared/cms/src/lib/strapi.client.ts @@ -50,7 +50,7 @@ export class StrapiClient { event: 'response', listener: (response: EventResponse) => void ) => EventEmitter; - private graphqlMemCache: Record = {}; + private graphqlMemCache: Record | undefined> = {}; constructor( private strapiClientConfig: StrapiClientConfig, @@ -103,21 +103,35 @@ export class StrapiClient { }; if (this.graphqlMemCache[cacheKey]) { - this.emitter.emit('response', { - ...emitterResponse, - requestEndTime: emitterResponse.requestStartTime, - elapsed: 0, - cache: true, - }); - return this.graphqlMemCache[cacheKey] as Result; + let response: Result | undefined; + try { + response = (await this.graphqlMemCache[cacheKey]) as Result; + } catch (e) { + // Do nothing, fall through to do the actual query since the cached instance failed + } + + if (response) { + this.emitter.emit('response', { + ...emitterResponse, + requestEndTime: emitterResponse.requestStartTime, + elapsed: 0, + cache: true, + }); + + return response; + } } try { - const response = await this.client.request({ + const response = this.client.request({ document: query, variables, }); + this.graphqlMemCache[cacheKey] = response; + + await response; + const requestEndTime = Date.now(); this.emitter.emit('response', { ...emitterResponse, @@ -125,8 +139,6 @@ export class StrapiClient { requestEndTime, }); - this.graphqlMemCache[cacheKey] = response; - return response; } catch (e) { const requestEndTime = Date.now(); @@ -151,8 +163,10 @@ export class StrapiClient { const cacheTTL = (this.strapiClientConfig.memCacheTTL || DEFAULT_MEM_CACHE_TTL) * 1000; + const randomSpread = Math.floor(Math.random() * 100); + setInterval(() => { this.graphqlMemCache = {}; - }, cacheTTL); + }, cacheTTL + randomSpread); } } diff --git a/packages/fxa-auth-server/bin/key_server.js b/packages/fxa-auth-server/bin/key_server.js index 6ec807306c..d112fdb07b 100755 --- a/packages/fxa-auth-server/bin/key_server.js +++ b/packages/fxa-auth-server/bin/key_server.js @@ -138,7 +138,13 @@ async function run(config) { ); Container.set(PromotionCodeManager, promotionCodeManager); - if (config.cms.enabled) { + if ( + config.cms.enabled || + (config.cms.strapiClient && + config.cms.strapiClient.graphqlApiUri && + config.cms.strapiClient.apiKey && + config.cms.strapiClient.firestoreCacheCollectionName) + ) { const strapiClientConfig = config.cms.strapiClient; const { graphqlApiUri, apiKey, firestoreCacheCollectionName } = strapiClientConfig;