Skip to content

Commit

Permalink
refactor: remove internal cache and stale state flow
Browse files Browse the repository at this point in the history
Signed-off-by: Luiz Ribeiro <[email protected]>
  • Loading branch information
luizgribeiro committed Nov 20, 2023
1 parent 4a3da77 commit c44b8f8
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class InMemoryProvider implements Provider {
name: 'in-memory',
} as const;
private _flagConfiguration: FlagConfiguration;
private _flagEvalCache: Record<string, ResolutionDetails<number | string | boolean | JsonValue>> = {};
private _context: EvaluationContext | undefined;

constructor(flagConfiguration: FlagConfiguration = {}) {
this._flagConfiguration = { ...flagConfiguration };
Expand All @@ -40,14 +40,10 @@ export class InMemoryProvider implements Provider {
try {

for (const key in this._flagConfiguration) {
if (this._flagConfiguration[key].disabled) {
continue;
}

this._flagEvalCache[key] = this.resolveFlagWithReason(key, context);

this.resolveFlagWithReason(key, context);
}

this._context = context;
this.events.emit(ProviderEvents.Ready);
} catch (error) {
this.status = ProviderStatus.ERROR;
Expand All @@ -60,7 +56,7 @@ export class InMemoryProvider implements Provider {
* Overwrites the configured flags.
* @param { FlagConfiguration } flagConfiguration new flag configuration
*/
putConfiguration(flagConfiguration: FlagConfiguration) {
async putConfiguration(flagConfiguration: FlagConfiguration) {
const flagsChanged = Object.entries(flagConfiguration)
.filter(([key, value]) => this._flagConfiguration[key] !== value)
.map(([key]) => key);
Expand All @@ -70,17 +66,8 @@ export class InMemoryProvider implements Provider {

this._flagConfiguration = { ...flagConfiguration };
this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged });
}

/**
* Overwrites the configured flags & updates internal cache (resolved flags).
* @param { FlagConfiguration } flagConfiguration new flag configuration
* @param { EvaluationContext } [context] flag evaluation context
*/
async putConfigurationAndUpdateResolution(flagConfiguration: FlagConfiguration, context?: EvaluationContext | undefined): Promise<void> {
this.putConfiguration(flagConfiguration);

await this.initialize(context);
await this.initialize(this._context);
}

resolveBooleanEvaluation(
Expand All @@ -89,7 +76,7 @@ export class InMemoryProvider implements Provider {
context?: EvaluationContext,
logger?: Logger,
): ResolutionDetails<boolean> {
return this.resolveFromCache<boolean>(flagKey, defaultValue, logger);
return this.resolveAndCheckFlag<boolean>(flagKey, defaultValue, context || this._context, logger);
}

resolveNumberEvaluation(
Expand All @@ -98,7 +85,7 @@ export class InMemoryProvider implements Provider {
context?: EvaluationContext,
logger?: Logger,
): ResolutionDetails<number> {
return this.resolveFromCache<number>(flagKey, defaultValue, logger);
return this.resolveAndCheckFlag<number>(flagKey, defaultValue, context || this._context, logger);
}

resolveStringEvaluation(
Expand All @@ -107,7 +94,7 @@ export class InMemoryProvider implements Provider {
context?: EvaluationContext,
logger?: Logger,
): ResolutionDetails<string> {
return this.resolveFromCache<string>(flagKey, defaultValue, logger);
return this.resolveAndCheckFlag<string>(flagKey, defaultValue, context || this._context, logger);
}

resolveObjectEvaluation<T extends JsonValue>(
Expand All @@ -116,12 +103,12 @@ export class InMemoryProvider implements Provider {
context?: EvaluationContext,
logger?: Logger,
): ResolutionDetails<T> {
return this.resolveFromCache<T>(flagKey, defaultValue, logger);
return this.resolveAndCheckFlag<T>(flagKey, defaultValue, context || this._context, logger);
}

private resolveFromCache<T extends JsonValue | FlagValueType>(flagKey: string,
defaultValue: T, logger?: Logger): ResolutionDetails<T> {
if (!(flagKey in this._flagEvalCache)) {
private resolveAndCheckFlag<T extends JsonValue | FlagValueType>(flagKey: string,
defaultValue: T, context?: EvaluationContext, logger?: Logger): ResolutionDetails<T> {
if (!(flagKey in this._flagConfiguration)) {
const message = `no flag found with key ${flagKey}`;
logger?.debug(message);
throw new FlagNotFoundError(message);
Expand All @@ -131,7 +118,7 @@ export class InMemoryProvider implements Provider {
return { value: defaultValue, reason: StandardResolutionReasons.DISABLED };
}

const resolvedFlag = this._flagEvalCache[flagKey] as ResolutionDetails<T>;
const resolvedFlag = this.resolveFlagWithReason(flagKey, context) as ResolutionDetails<T>;

if (resolvedFlag.value === undefined) {
const message = `no value associated with variant provided for ${flagKey} found`;
Expand All @@ -143,7 +130,7 @@ export class InMemoryProvider implements Provider {
throw new TypeMismatchError();
}

return this.status === ProviderStatus.STALE ? { ...resolvedFlag, reason: StandardResolutionReasons.CACHED } : resolvedFlag;
return resolvedFlag;
}

private resolveFlagWithReason<T extends JsonValue | FlagValueType>(
Expand Down
Loading

0 comments on commit c44b8f8

Please sign in to comment.