diff --git a/packages/core/src/common/self-refreshing-cache.ts b/packages/core/src/common/self-refreshing-cache.ts index 8fa74cf231..550036818f 100644 --- a/packages/core/src/common/self-refreshing-cache.ts +++ b/packages/core/src/common/self-refreshing-cache.ts @@ -6,7 +6,7 @@ import { Logger } from '../config/logger/vendure-logger'; * @description * A cache which automatically refreshes itself if the value is found to be stale. */ -export interface SelfRefreshingCache { +export interface SelfRefreshingCache { /** * @description * The current value of the cache. If the value is stale, the data will be refreshed and then @@ -28,13 +28,16 @@ export interface SelfRefreshingCache { * Force a refresh of the value, e.g. when it is known that the value has changed such as after * an update operation to the source data in the database. */ - refresh(): Promise; + refresh(...args: RefreshArgs): Promise; } -export interface SelfRefreshingCacheConfig { +export interface SelfRefreshingCacheConfig { name: string; ttl: number; - refreshFn: () => Promise; + refresh: { + fn: (...args: RefreshArgs) => Promise; + defaultArgs: RefreshArgs; + }; } /** @@ -47,18 +50,19 @@ export interface SelfRefreshingCacheConfig { * value has expired, it will still be returned and the `refreshFn` will be triggered to update the value in the * background. */ -export async function createSelfRefreshingCache( - config: SelfRefreshingCacheConfig, -): Promise> { - const { ttl, name, refreshFn } = config; - const initialValue = await refreshFn(); +export async function createSelfRefreshingCache( + config: SelfRefreshingCacheConfig, +): Promise> { + const { ttl, name, refresh } = config; + const initialValue = await refresh.fn(...refresh.defaultArgs); let value = initialValue; let expires = new Date().getTime() + ttl; const memoCache = new Map(); const hashArgs = (...args: any[]) => JSON.stringify([args, expires]); - const refreshValue = (): Promise => { + const refreshValue = (...args: RefreshArgs): Promise => { Logger.debug(`Refreshing the SelfRefreshingCache "${name}"`); - return refreshFn() + return refresh + .fn(...args) .then(newValue => { value = newValue; expires = new Date().getTime() + ttl; @@ -77,7 +81,7 @@ export async function createSelfRefreshingCache( const getValue = async (): Promise => { const now = new Date().getTime(); if (expires < now) { - return refreshValue(); + return refreshValue(...refresh.defaultArgs); } return value; }; diff --git a/packages/core/src/service/services/channel.service.ts b/packages/core/src/service/services/channel.service.ts index 082c43d0d4..f812819ba5 100644 --- a/packages/core/src/service/services/channel.service.ts +++ b/packages/core/src/service/services/channel.service.ts @@ -33,7 +33,7 @@ import { GlobalSettingsService } from './global-settings.service'; @Injectable() export class ChannelService { - private allChannels: SelfRefreshingCache; + private allChannels: SelfRefreshingCache; constructor( private connection: TransactionalConnection, @@ -51,7 +51,7 @@ export class ChannelService { this.allChannels = await createSelfRefreshingCache({ name: 'ChannelService.allChannels', ttl: this.configService.entityOptions.channelCacheTtl, - refreshFn: () => this.findAll(RequestContext.empty()), + refresh: { fn: ctx => this.findAll(ctx), defaultArgs: [RequestContext.empty()] }, }); } @@ -174,7 +174,7 @@ export class ChannelService { } const newChannel = await this.connection.getRepository(ctx, Channel).save(channel); await this.customFieldRelationService.updateRelations(ctx, Channel, input, newChannel); - await this.allChannels.refresh(); + await this.allChannels.refresh(ctx); return channel; } @@ -207,7 +207,7 @@ export class ChannelService { } await this.connection.getRepository(ctx, Channel).save(updatedChannel, { reload: false }); await this.customFieldRelationService.updateRelations(ctx, Channel, input, updatedChannel); - await this.allChannels.refresh(); + await this.allChannels.refresh(ctx); return assertFound(this.findOne(ctx, channel.id)); } diff --git a/packages/core/src/service/services/zone.service.ts b/packages/core/src/service/services/zone.service.ts index d156ce7692..20c1f9bbff 100644 --- a/packages/core/src/service/services/zone.service.ts +++ b/packages/core/src/service/services/zone.service.ts @@ -26,17 +26,20 @@ export class ZoneService { /** * We cache all Zones to avoid hitting the DB many times per request. */ - private zones: SelfRefreshingCache; + private zones: SelfRefreshingCache; constructor(private connection: TransactionalConnection, private configService: ConfigService) {} async initZones() { this.zones = await createSelfRefreshingCache({ name: 'ZoneService.zones', ttl: this.configService.entityOptions.zoneCacheTtl, - refreshFn: () => - this.connection.getRepository(Zone).find({ - relations: ['members'], - }), + refresh: { + fn: ctx => + this.connection.getRepository(ctx, Zone).find({ + relations: ['members'], + }), + defaultArgs: [RequestContext.empty()], + }, }); } @@ -69,7 +72,7 @@ export class ZoneService { zone.members = await this.getCountriesFromIds(ctx, input.memberIds); } const newZone = await this.connection.getRepository(ctx, Zone).save(zone); - await this.zones.refresh(); + await this.zones.refresh(ctx); return assertFound(this.findOne(ctx, newZone.id)); } @@ -77,7 +80,7 @@ export class ZoneService { const zone = await this.connection.getEntityOrThrow(ctx, Zone, input.id); const updatedZone = patchEntity(zone, input); await this.connection.getRepository(ctx, Zone).save(updatedZone, { reload: false }); - await this.zones.refresh(); + await this.zones.refresh(ctx); return assertFound(this.findOne(ctx, zone.id)); } @@ -115,7 +118,7 @@ export class ZoneService { }; } else { await this.connection.getRepository(ctx, Zone).remove(zone); - await this.zones.refresh(); + await this.zones.refresh(ctx); return { result: DeletionResult.DELETED, message: '', @@ -131,7 +134,7 @@ export class ZoneService { const members = unique(zone.members.concat(countries), 'id'); zone.members = members; await this.connection.getRepository(ctx, Zone).save(zone, { reload: false }); - await this.zones.refresh(); + await this.zones.refresh(ctx); return assertFound(this.findOne(ctx, zone.id)); } @@ -144,7 +147,7 @@ export class ZoneService { }); zone.members = zone.members.filter(country => !input.memberIds.includes(country.id)); await this.connection.getRepository(ctx, Zone).save(zone, { reload: false }); - await this.zones.refresh(); + await this.zones.refresh(ctx); return assertFound(this.findOne(ctx, zone.id)); }