UNPKG

unleash-server

Version:

Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.

102 lines 4.07 kB
import EventEmitter from 'events'; import { mapFeaturesForClient, mapSegmentsForClient, } from '../playground/offline-unleash-client.js'; import { ALL_ENVS } from '../../util/constants.js'; import { UnleashEvents } from 'unleash-client'; import { UPDATE_REVISION } from '../feature-toggle/configuration-revision-service.js'; import { FUNCTION_TIME, PROXY_FEATURES_FOR_TOKEN_TIME, } from '../../metric-events.js'; import metricsHelper from '../../util/metrics-helper.js'; // TODO: remove after finished migration to global frontend api cache export class ProxyRepository extends EventEmitter { constructor(config, stores, services, token) { super(); this.config = config; this.logger = config.getLogger('proxy-repository.ts'); this.stores = stores; this.services = services; this.configurationRevisionService = services.configurationRevisionService; this.token = token; this.onUpdateRevisionEvent = this.onUpdateRevisionEvent.bind(this); this.interval = config.frontendApi.refreshIntervalInMs; this.methodTimer = (functionName) => metricsHelper.wrapTimer(config.eventBus, FUNCTION_TIME, { className: 'ProxyRepository', functionName, }); } getTogglesWithSegmentData() { // TODO: add real implementation return []; } getSegment(id) { return this.segments.find((segment) => segment.id === id); } getToggle(name) { //@ts-expect-error (we must update the node SDK to allow undefined) return this.features.find((feature) => feature.name === name); } getToggles() { return this.features; } async start() { this.running = true; await this.dataPolling(); // Reload cached token data whenever something relevant has changed. // For now, simply reload all the data on any EventStore event. this.configurationRevisionService.on(UPDATE_REVISION, this.onUpdateRevisionEvent); this.emit(UnleashEvents.Ready); this.emit(UnleashEvents.Changed); } stop() { this.configurationRevisionService.off(UPDATE_REVISION, this.onUpdateRevisionEvent); this.running = false; } async dataPolling() { this.timer = setTimeout(async () => { if (!this.running) { clearTimeout(this.timer); this.timer = null; this.logger.debug('Shutting down data polling for proxy repository'); return; } await this.dataPolling(); }, this.randomizeDelay(this.interval, this.interval * 2)).unref(); await this.loadDataForToken(); } async loadDataForToken() { try { const stopTimer = this.methodTimer('loadDataForToken'); this.features = await this.featuresForToken(); this.segments = await this.segmentsForToken(); stopTimer(); } catch (e) { this.logger.error('Cannot load data for token', e); } } randomizeDelay(floor, ceiling) { return Math.floor(Math.random() * (ceiling - floor) + floor); } async onUpdateRevisionEvent() { await this.loadDataForToken(); } async featuresForToken() { const start = Date.now(); const mappedFeatures = await mapFeaturesForClient(await this.services.featureToggleService.getClientFeatures({ project: this.token.projects, environment: this.environmentNameForToken(), })); const duration = (Date.now() - start) / 1000; this.config.eventBus.emit(PROXY_FEATURES_FOR_TOKEN_TIME, { duration }); return mappedFeatures; } async segmentsForToken() { return mapSegmentsForClient(await this.stores.segmentReadModel.getAll()); } environmentNameForToken() { if (this.token.environment === ALL_ENVS) { return 'default'; } return this.token.environment; } } //# sourceMappingURL=proxy-repository.js.map