UNPKG

@splitsoftware/splitio-commons

Version:
81 lines (80 loc) 4.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.segmentChangesUpdaterFactory = void 0; var constants_1 = require("../../../readiness/constants"); var constants_2 = require("../../../logger/constants"); /** * Factory of SegmentChanges updater, a task that: * - fetches segment changes using `segmentChangesFetcher` * - updates `segmentsCache` * - uses `segmentsEventEmitter` to emit events related to segments data updates * * @param log - logger instance * @param segmentChangesFetcher - fetcher of `/segmentChanges` * @param segments - segments storage, with sync or async methods * @param readiness - optional readiness manager. Not required for synchronizer or producer mode. */ function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, readiness) { var readyOnAlreadyExistentState = true; function updateSegment(segmentName, noCache, till, fetchOnlyNew) { log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing segment " + segmentName); var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName)); return sincePromise.then(function (since) { // if fetchOnlyNew flag, avoid processing already fetched segments return fetchOnlyNew && since !== undefined ? false : segmentChangesFetcher(since || -1, segmentName, noCache, till).then(function (changes) { return Promise.all(changes.map(function (x) { log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing " + segmentName + " with till = " + x.till + ". Added: " + x.added.length + ". Removed: " + x.removed.length); return segments.update(segmentName, x.added, x.removed, x.till); })).then(function (updates) { return updates.some(function (update) { return update; }); }); }); }); } /** * Segments updater returns a promise that resolves with a `false` boolean value if it fails at least to fetch a segment or synchronize it with the storage. * Thus, a false result doesn't imply that SDK_SEGMENTS_ARRIVED was not emitted. * Returned promise will not be rejected. * * @param fetchOnlyNew - if true, only fetch the segments that not exists, i.e., which `changeNumber` is equal to -1. * This param is used by SplitUpdateWorker on server-side SDK, to fetch new registered segments on SPLIT_UPDATE or RB_SEGMENT_UPDATE notifications. * @param segmentName - segment name to fetch. By passing `undefined` it fetches the list of segments registered at the storage * @param noCache - true to revalidate data to fetch on a SEGMENT_UPDATE notifications. * @param till - till target for the provided segmentName, for CDN bypass. */ return function segmentChangesUpdater(fetchOnlyNew, segmentName, noCache, till) { log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Started segments update"); // If not a segment name provided, read list of available segments names to be updated. var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments()); return segmentsPromise.then(function (segmentNames) { // Async fetchers var updaters = segmentNames.map(function (segmentName) { return updateSegment(segmentName, noCache, till, fetchOnlyNew); }); return Promise.all(updaters).then(function (shouldUpdateFlags) { // if at least one segment fetch succeeded, mark segments ready if (shouldUpdateFlags.some(function (update) { return update; }) || readyOnAlreadyExistentState) { readyOnAlreadyExistentState = false; if (readiness) readiness.segments.emit(constants_1.SDK_SEGMENTS_ARRIVED); } return true; }); }) // Handles rejected promises at `segmentChangesFetcher`, `segments.getRegisteredSegments` and other segment storage operations. .catch(function (error) { if (error && error.statusCode === 403) { // If the operation is forbidden, it may be due to permissions. Destroy the SDK instance. // @TODO although factory status is destroyed, synchronization is not stopped if (readiness) readiness.setDestroyed(); log.error(constants_2.LOG_PREFIX_INSTANTIATION + ": you passed a client-side type authorizationKey, please grab an SDK Key from the Split user interface that is of type server-side."); } else { log.warn(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Error while doing fetch of segments. " + error); } return false; }); }; } exports.segmentChangesUpdaterFactory = segmentChangesUpdaterFactory;