UNPKG

@splitsoftware/splitio-commons

Version:
137 lines (136 loc) 6.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SplitsUpdateWorker = void 0; var constants_1 = require("../../../logger/constants"); var constants_2 = require("../../../readiness/constants"); var Backoff_1 = require("../../../utils/Backoff"); var constants_3 = require("../../../utils/constants"); var constants_4 = require("../constants"); var parseUtils_1 = require("../parseUtils"); var constants_5 = require("./constants"); /** * SplitsUpdateWorker factory */ function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmitter, telemetryTracker, segmentsSyncTask) { var ff = SplitsUpdateWorker(storage.splits); var rbs = SplitsUpdateWorker(storage.rbSegments); function SplitsUpdateWorker(cache) { var maxChangeNumber = -1; var handleNewEvent = false; var isHandlingEvent; var cdnBypass; var instantUpdate; var backoff = new Backoff_1.Backoff(__handleSplitUpdateCall, constants_5.FETCH_BACKOFF_BASE, constants_5.FETCH_BACKOFF_MAX_WAIT); function __handleSplitUpdateCall() { isHandlingEvent = true; if (maxChangeNumber > cache.getChangeNumber()) { handleNewEvent = false; // fetch splits revalidating data if cached splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () { if (!isHandlingEvent) return; // halt if `stop` has been called if (handleNewEvent) { __handleSplitUpdateCall(); } else { if (instantUpdate) telemetryTracker.trackUpdatesFromSSE(constants_3.SPLITS); // fetch new registered segments for server-side API. Not retrying on error if (segmentsSyncTask) segmentsSyncTask.execute(true); var attempts = backoff.attempts + 1; if (ff.isSync() && rbs.isSync()) { log.debug("Refresh completed" + (cdnBypass ? ' bypassing the CDN' : '') + " in " + attempts + " attempts."); isHandlingEvent = false; return; } if (attempts < constants_5.FETCH_BACKOFF_MAX_RETRIES) { backoff.scheduleCall(); return; } if (cdnBypass) { log.debug("No changes fetched after " + attempts + " attempts with CDN bypassed."); isHandlingEvent = false; } else { backoff.reset(); cdnBypass = true; __handleSplitUpdateCall(); } } }); } else { isHandlingEvent = false; } } return { /** * Invoked by NotificationProcessor on SPLIT_UPDATE or RB_SEGMENT_UPDATE event * * @param changeNumber - change number of the notification */ put: function (_a, payload) { var changeNumber = _a.changeNumber, pcn = _a.pcn, type = _a.type; var currentChangeNumber = cache.getChangeNumber(); if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber) return; maxChangeNumber = changeNumber; handleNewEvent = true; cdnBypass = false; instantUpdate = undefined; if (payload && currentChangeNumber === pcn) { instantUpdate = { payload: payload, changeNumber: changeNumber, type: type }; } if (backoff.timeoutID || !isHandlingEvent) __handleSplitUpdateCall(); backoff.reset(); }, stop: function () { isHandlingEvent = false; backoff.reset(); }, isSync: function () { return maxChangeNumber <= cache.getChangeNumber(); } }; } return { put: function (parsedData) { if (parsedData.d && parsedData.c !== undefined) { try { var payload = (0, parseUtils_1.parseFFUpdatePayload)(parsedData.c, parsedData.d); if (payload) { (parsedData.type === constants_4.RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData, payload); return; } } catch (e) { log.warn(constants_1.STREAMING_PARSING_SPLIT_UPDATE, [parsedData.type, e]); } } (parsedData.type === constants_4.RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData); }, /** * Invoked by NotificationProcessor on SPLIT_KILL event * * @param changeNumber - change number of the notification * @param splitName - name of split to kill * @param defaultTreatment - default treatment value */ killSplit: function (_a) { var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment; if (storage.splits.killLocally(splitName, defaultTreatment, changeNumber)) { // trigger an SDK_UPDATE if Split was killed locally splitsEventEmitter.emit(constants_2.SDK_SPLITS_ARRIVED, true); } // queues the SplitChanges fetch (only if changeNumber is newer) ff.put({ changeNumber: changeNumber }); }, stop: function () { ff.stop(); rbs.stop(); } }; } exports.SplitsUpdateWorker = SplitsUpdateWorker;