From a05e7ab2143f97deb3b03f5a7e6c64973058d4c0 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Tue, 28 Sep 2021 10:17:47 +0200 Subject: [PATCH] feat(core): Make entity cache ttl values configurable Relates to #988 --- packages/core/src/config/config.service.ts | 5 +++ packages/core/src/config/default-config.ts | 4 +++ packages/core/src/config/vendure-config.ts | 33 +++++++++++++++++++ .../src/service/services/channel.service.ts | 2 +- .../core/src/service/services/zone.service.ts | 5 +-- 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/packages/core/src/config/config.service.ts b/packages/core/src/config/config.service.ts index 4876b24494..5d1d455e85 100644 --- a/packages/core/src/config/config.service.ts +++ b/packages/core/src/config/config.service.ts @@ -11,6 +11,7 @@ import { AssetOptions, AuthOptions, CatalogOptions, + EntityOptions, ImportExportOptions, JobQueueOptions, OrderOptions, @@ -54,6 +55,10 @@ export class ConfigService implements VendureConfig { return this.activeConfig.defaultLanguageCode; } + get entityOptions(): Required { + return this.activeConfig.entityOptions; + } + get entityIdStrategy(): EntityIdStrategy { return this.activeConfig.entityIdStrategy; } diff --git a/packages/core/src/config/default-config.ts b/packages/core/src/config/default-config.ts index 4594beca6e..f50c774263 100644 --- a/packages/core/src/config/default-config.ts +++ b/packages/core/src/config/default-config.ts @@ -102,6 +102,10 @@ export const defaultConfig: RuntimeVendureConfig = { timezone: 'Z', type: 'mysql', }, + entityOptions: { + channelCacheTtl: 30000, + zoneCacheTtl: 30000, + }, promotionOptions: { promotionConditions: defaultPromotionConditions, promotionActions: defaultPromotionActions, diff --git a/packages/core/src/config/vendure-config.ts b/packages/core/src/config/vendure-config.ts index 1d9abe689e..1898b64ccc 100644 --- a/packages/core/src/config/vendure-config.ts +++ b/packages/core/src/config/vendure-config.ts @@ -745,6 +745,37 @@ export interface JobQueueOptions { activeQueues?: string[]; } +/** + * @description + * Options relating to the internal handling of entities. + * + * @since 1.3.0 + */ +export interface EntityOptions { + /** + * @description + * Channels get cached in-memory as they are accessed very frequently. This + * setting determines how long the cache lives (in ms) until it is considered stale and + * refreshed. For multi-instance deployments (e.g. serverless, load-balanced), a + * smaller value here will prevent data inconsistencies between instances. + * + * @since 1.3.0 + * @default 30000 + */ + channelCacheTtl?: number; + /** + * @description + * Zones get cached in-memory as they are accessed very frequently. This + * setting determines how long the cache lives (in ms) until it is considered stale and + * refreshed. For multi-instance deployments (e.g. serverless, load-balanced), a + * smaller value here will prevent data inconsistencies between instances. + * + * @since 1.3.0 + * @default 30000 + */ + zoneCacheTtl?: number; +} + /** * @description * All possible configuration options are defined by the @@ -813,6 +844,7 @@ export interface VendureConfig { * @default AutoIncrementIdStrategy */ entityIdStrategy?: EntityIdStrategy; + entityOptions?: EntityOptions; /** * @description * Configuration settings for data import and export. @@ -879,6 +911,7 @@ export interface RuntimeVendureConfig extends Required { authOptions: Required; catalogOptions: Required; customFields: Required; + entityOptions: Required; importExportOptions: Required; jobQueueOptions: Required; orderOptions: Required; diff --git a/packages/core/src/service/services/channel.service.ts b/packages/core/src/service/services/channel.service.ts index 868d1b143d..331cc0fbe6 100644 --- a/packages/core/src/service/services/channel.service.ts +++ b/packages/core/src/service/services/channel.service.ts @@ -50,7 +50,7 @@ export class ChannelService { await this.ensureDefaultChannelExists(); this.allChannels = await createSelfRefreshingCache({ name: 'ChannelService.allChannels', - ttl: 10000, + ttl: this.configService.entityOptions.channelCacheTtl, refreshFn: () => this.findAll(RequestContext.empty()), }); } diff --git a/packages/core/src/service/services/zone.service.ts b/packages/core/src/service/services/zone.service.ts index 66ccc25aea..67010a2480 100644 --- a/packages/core/src/service/services/zone.service.ts +++ b/packages/core/src/service/services/zone.service.ts @@ -13,6 +13,7 @@ import { unique } from '@vendure/common/lib/unique'; import { RequestContext } from '../../api/common/request-context'; import { createSelfRefreshingCache, SelfRefreshingCache } from '../../common/self-refreshing-cache'; import { assertFound } from '../../common/utils'; +import { ConfigService } from '../../config/config.service'; import { Channel, TaxRate } from '../../entity'; import { Country } from '../../entity/country/country.entity'; import { Zone } from '../../entity/zone/zone.entity'; @@ -26,12 +27,12 @@ export class ZoneService { * We cache all Zones to avoid hitting the DB many times per request. */ private zones: SelfRefreshingCache; - constructor(private connection: TransactionalConnection) {} + constructor(private connection: TransactionalConnection, private configService: ConfigService) {} async initZones() { this.zones = await createSelfRefreshingCache({ name: 'ZoneService.zones', - ttl: 10000, + ttl: this.configService.entityOptions.zoneCacheTtl, refreshFn: () => this.connection.getRepository(Zone).find({ relations: ['members'],