@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
137 lines (136 loc) • 6.1 kB
JavaScript
;
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;