UNPKG

@splitsoftware/splitio-commons

Version:
81 lines (80 loc) 4.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mySegmentsUpdaterFactory = void 0; var timeout_1 = require("../../../utils/promise/timeout"); var constants_1 = require("../../../readiness/constants"); var constants_2 = require("../../../logger/constants"); var constants_3 = require("../../streaming/constants"); /** * factory of MySegments updater, a task that: * - fetches mySegments using `mySegmentsFetcher` * - updates `mySegmentsCache` * - uses `segmentsEventEmitter` to emit events related to segments data updates */ function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmentsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, matchingKey) { var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments, largeSegments = storage.largeSegments; var readyOnAlreadyExistentState = true; var startingUp = true; /** timeout and telemetry decorator for `splitChangesFetcher` promise */ function _promiseDecorator(promise) { if (startingUp) promise = (0, timeout_1.timeout)(requestTimeoutBeforeReady, promise); return promise; } // @TODO if allowing pluggable storages, handle async execution function updateSegments(segmentsData) { var shouldNotifyUpdate; if (segmentsData.type !== undefined) { shouldNotifyUpdate = segmentsData.type === constants_3.MEMBERSHIPS_LS_UPDATE ? largeSegments.resetSegments(segmentsData) : segments.resetSegments(segmentsData); } else { shouldNotifyUpdate = segments.resetSegments(segmentsData.ms || {}); shouldNotifyUpdate = largeSegments.resetSegments(segmentsData.ls || {}) || shouldNotifyUpdate; } // Notify update if required if ((splits.usesSegments() || rbSegments.usesSegments()) && (shouldNotifyUpdate || readyOnAlreadyExistentState)) { readyOnAlreadyExistentState = false; segmentsEventEmitter.emit(constants_1.SDK_SEGMENTS_ARRIVED); } } function _mySegmentsUpdater(retry, segmentsData, noCache, till) { var updaterPromise = segmentsData ? // If segmentsData is provided, there is no need to fetch mySegments new Promise(function (res) { updateSegments(segmentsData); res(true); }) : // If not provided, fetch mySegments mySegmentsFetcher(matchingKey, noCache, till, _promiseDecorator).then(function (segments) { // Only when we have downloaded segments completely, we should not keep retrying anymore startingUp = false; updateSegments(segments); return true; }); return updaterPromise.catch(function (error) { if (startingUp && retriesOnFailureBeforeReady > retry) { retry += 1; log.warn(constants_2.SYNC_MYSEGMENTS_FETCH_RETRY, [retry, error]); return _mySegmentsUpdater(retry); // no need to forward `segmentList` and `noCache` params } else { startingUp = false; } return false; }); } /** * MySegments updater returns a promise that resolves with a `false` boolean value if it fails to fetch mySegments or synchronize them with the storage. * Returned promise will not be rejected. * * @param segmentsData - it can be: * (1) the list of mySegments names to sync in the storage, * (2) an object with a segment name and action (true: add, or false: delete) to update the storage, * (3) or `undefined`, for which the updater will fetch mySegments in order to sync the storage. * @param noCache - true to revalidate data to fetch * @param till - query param to bypass CDN requests */ return function mySegmentsUpdater(segmentsData, noCache, till) { return _mySegmentsUpdater(0, segmentsData, noCache, till); }; } exports.mySegmentsUpdaterFactory = mySegmentsUpdaterFactory;