diff --git a/apps/api/src/app/subscription/subscription.controller.ts b/apps/api/src/app/subscription/subscription.controller.ts index 4018e4753e..a70fe87916 100644 --- a/apps/api/src/app/subscription/subscription.controller.ts +++ b/apps/api/src/app/subscription/subscription.controller.ts @@ -54,7 +54,9 @@ export class SubscriptionController { } let coupons = - (await this.propertyService.getByKey(PROPERTY_COUPONS)) ?? []; + (await this.propertyService.getByKey(PROPERTY_COUPONS, { + skipCache: true + })) ?? []; const coupon = coupons.find((currentCoupon) => { return currentCoupon.code === couponCode; diff --git a/apps/api/src/services/benchmark/benchmark.service.ts b/apps/api/src/services/benchmark/benchmark.service.ts index 17e729f9f4..993e0f0aae 100644 --- a/apps/api/src/services/benchmark/benchmark.service.ts +++ b/apps/api/src/services/benchmark/benchmark.service.ts @@ -159,7 +159,8 @@ export class BenchmarkService { let benchmarks = (await this.propertyService.getByKey( - PROPERTY_BENCHMARKS + PROPERTY_BENCHMARKS, + { skipCache: true } )) ?? []; benchmarks.push({ symbolProfileId: assetProfile.id }); @@ -196,7 +197,8 @@ export class BenchmarkService { let benchmarks = (await this.propertyService.getByKey( - PROPERTY_BENCHMARKS + PROPERTY_BENCHMARKS, + { skipCache: true } )) ?? []; benchmarks = benchmarks.filter(({ symbolProfileId }) => { diff --git a/apps/api/src/services/property/property.service.ts b/apps/api/src/services/property/property.service.ts index acfa5822c9..6d8130bbc2 100644 --- a/apps/api/src/services/property/property.service.ts +++ b/apps/api/src/services/property/property.service.ts @@ -31,14 +31,14 @@ export class PropertyService { return property; } - public async get() { + public async get({ skipCache = false } = {}) { const response: { [key: string]: PropertyValue; } = { [PROPERTY_CURRENCIES]: [] }; - const properties = await this.getProperties(); + const properties = await this.getProperties({ skipCache }); for (const property of properties) { let value = property.value; @@ -53,8 +53,11 @@ export class PropertyService { return response; } - public async getByKey(aKey: PropertyKey) { - const properties = await this.get(); + public async getByKey( + aKey: PropertyKey, + { skipCache = false } = {} + ) { + const properties = await this.get({ skipCache }); return properties[aKey] as TValue; } @@ -78,9 +81,14 @@ export class PropertyService { /** * Returns the properties from the in-memory cache, falling back to the - * database + * database. Callers which write back a modified property must set + * skipCache to avoid basing the write on a stale read. */ - private async getProperties() { + private async getProperties({ skipCache = false } = {}) { + if (skipCache) { + return this.prismaService.property.findMany(); + } + if ( this.cachedProperties && isBefore(new Date(), this.cachedPropertiesExpiresAt) @@ -88,14 +96,15 @@ export class PropertyService { return this.cachedProperties; } - this.cachedProperties = this.prismaService.property - .findMany() - .catch((error) => { + const properties = this.prismaService.property.findMany().catch((error) => { + if (this.cachedProperties === properties) { this.invalidateCache(); + } - throw error; - }); + throw error; + }); + this.cachedProperties = properties; this.cachedPropertiesExpiresAt = addMilliseconds( new Date(), PropertyService.CACHE_TTL