1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00

fix: initialize cache when we get the first request (#8971)

This PR changes the caching functionality so that we initialize the
cache when we receive the first request instead of frontloading the
caches.
This commit is contained in:
Fredrik Strand Oseberg 2024-12-13 08:39:40 +01:00 committed by GitHub
parent 67864e7008
commit 8eb84e9645
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -115,14 +115,20 @@ export class ClientFeatureToggleCache {
this.clientFeatureToggleStore = clientFeatureToggleStore; this.clientFeatureToggleStore = clientFeatureToggleStore;
this.flagResolver = flagResolver; this.flagResolver = flagResolver;
this.onUpdateRevisionEvent = this.onUpdateRevisionEvent.bind(this); this.onUpdateRevisionEvent = this.onUpdateRevisionEvent.bind(this);
this.cache = {};
// this.initCache(); TODO: we dont want to initialize cache on startup, but ondemand in future? this.initRevisionId();
this.configurationRevisionService.on( this.configurationRevisionService.on(
UPDATE_REVISION, UPDATE_REVISION,
this.onUpdateRevisionEvent, this.onUpdateRevisionEvent,
); );
} }
private async initRevisionId() {
this.currentRevisionId =
await this.configurationRevisionService.getMaxRevisionId();
}
async getDelta( async getDelta(
sdkRevisionId: number | undefined, sdkRevisionId: number | undefined,
environment: string, environment: string,
@ -130,11 +136,18 @@ export class ClientFeatureToggleCache {
): Promise<ClientFeatureChange | undefined> { ): Promise<ClientFeatureChange | undefined> {
const requiredRevisionId = sdkRevisionId || 0; const requiredRevisionId = sdkRevisionId || 0;
const hasCache = this.cache[environment] !== undefined;
if (!hasCache) {
await this.initEnvironmentCache(environment);
}
// Should get the latest state if revision does not exist or if sdkRevision is not present // Should get the latest state if revision does not exist or if sdkRevision is not present
// We should be able to do this without going to the database by merging revisions from the cache with // We should be able to do this without going to the database by merging revisions from the cache with
// the base case // the base case
const firstTimeCalling = !sdkRevisionId;
if ( if (
!sdkRevisionId || firstTimeCalling ||
(sdkRevisionId && (sdkRevisionId &&
sdkRevisionId !== this.currentRevisionId && sdkRevisionId !== this.currentRevisionId &&
!this.cache[environment].hasRevision(sdkRevisionId)) !this.cache[environment].hasRevision(sdkRevisionId))
@ -203,7 +216,6 @@ export class ClientFeatureToggleCache {
const features = await this.getClientFeatures({ const features = await this.getClientFeatures({
environment: 'development', environment: 'development',
}); });
if (this.cache.development) { if (this.cache.development) {
this.cache.development.addRevision({ this.cache.development.addRevision({
updated: features as any, //impressionData is not on the type but should be updated: features as any, //impressionData is not on the type but should be
@ -238,67 +250,25 @@ export class ClientFeatureToggleCache {
revisionId, revisionId,
}; };
} }
// TODO: I think we should remove it as is, because we do not need initialized cache, I think we should populate cache on demand for each env
// also we already have populateBaseCache method
public async initCache() {
//TODO: This only returns stuff for the default environment!!! Need to pass a query to get the relevant environment
// featuresByEnvironment cache
// The base cache is a record of <environment, array> public async initEnvironmentCache(environment: string) {
// Each array holds a collection of objects that contains the revisionId and which // Todo: replace with method that gets all features for an environment
// flags changed in each revision. It also holds a type that informs us whether or not const baseFeatures = await this.getClientFeatures({
// the revision is the base case or if is an update or remove operation environment,
// To get the base for each cache we need to get all features for all environments and the max revision id
// hardcoded for now
// const environments = ["default", "development", "production"];
const defaultBaseFeatures = await this.getClientFeatures({
environment: 'default',
});
const developmentBaseFeatures = await this.getClientFeatures({
environment: 'development',
});
const productionBaseFeatures = await this.getClientFeatures({
environment: 'production',
}); });
const defaultCache = new RevisionCache([ this.currentRevisionId =
{
revisionId: this.currentRevisionId,
updated: [defaultBaseFeatures],
removed: [],
},
]);
const developmentCache = new RevisionCache([
{
revisionId: this.currentRevisionId,
updated: [developmentBaseFeatures],
removed: [],
},
]);
const productionCache = new RevisionCache([
{
revisionId: this.currentRevisionId,
updated: [productionBaseFeatures],
removed: [],
},
]);
// Always assume that the first item of the array is the base
const cache = {
default: defaultCache,
development: developmentCache,
production: productionCache,
};
const latestRevision =
await this.configurationRevisionService.getMaxRevisionId(); await this.configurationRevisionService.getMaxRevisionId();
this.currentRevisionId = latestRevision; const cache = new RevisionCache([
this.cache = cache; {
revisionId: this.currentRevisionId,
updated: baseFeatures,
removed: [],
},
]);
this.cache[environment] = cache;
} }
async getClientFeatures( async getClientFeatures(