import { IDefinitionsCacheAsync } from './types'; import { IDefinition } from '../dtos/types'; import { objectAssign } from '../utils/lang/objectAssign'; /** * This class provides a skeletal implementation of the IDefinitionsCacheAsync interface * to minimize the effort required to implement this interface. */ export abstract class AbstractDefinitionsCacheAsync implements IDefinitionsCacheAsync { protected abstract add(definition: IDefinition): Promise protected abstract remove(name: string): Promise protected abstract setChangeNumber(changeNumber: number): Promise update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): Promise { return Promise.all([ this.setChangeNumber(changeNumber), Promise.all(toAdd.map(addedFF => this.add(addedFF))), Promise.all(toRemove.map(removedFF => this.remove(removedFF))) ]).then(([, added, removed]) => { return added.some(result => result) || removed.some(result => result); }); } abstract get(name: string): Promise abstract getMany(names: string[]): Promise> abstract getChangeNumber(): Promise abstract getAll(): Promise abstract getNames(): Promise abstract getNamesBySets(sets: string[]): Promise[]> abstract trafficTypeExists(trafficType: string): Promise abstract clear(): Promise // @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments') // noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage. usesSegments(): Promise { return Promise.resolve(true); } /** * Kill `name` definition and set `defaultTreatment` and `changeNumber`. * Used for SPLIT_KILL push notifications. * * @returns a promise that is resolved once the definition kill operation is performed. The fulfillment value is a boolean: `true` if the operation succeeded updating the definition or `false` if no definition is updated, * for instance, if the `changeNumber` is old, or if the definition is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update. * The promise will never be rejected. */ killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise { return this.get(name).then(definition => { if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) { const newDefinition = objectAssign({}, definition); newDefinition.killed = true; newDefinition.defaultTreatment = defaultTreatment; newDefinition.changeNumber = changeNumber; return this.add(newDefinition); } return false; }).catch(() => false); } }