@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
89 lines (88 loc) • 3.85 kB
JavaScript
import { Backoff } from '../../../utils/Backoff';
import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_RETRIES, FETCH_BACKOFF_MAX_WAIT } from './constants';
/**
* SegmentsUpdateWorker factory
*/
export function SegmentsUpdateWorker(log, segmentsSyncTask, segmentsCache) {
// Handles retries with CDN bypass per segment name
function SegmentUpdateWorker(segment) {
var maxChangeNumber = 0;
var handleNewEvent = false;
var isHandlingEvent;
var cdnBypass;
var backoff = new Backoff(__handleSegmentUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
function __handleSegmentUpdateCall() {
isHandlingEvent = true;
if (maxChangeNumber > (segmentsCache.getChangeNumber(segment) || -1)) {
handleNewEvent = false;
// fetch segments revalidating data if cached
segmentsSyncTask.execute(false, segment, true, cdnBypass ? maxChangeNumber : undefined).then(function () {
if (!isHandlingEvent)
return; // halt if `stop` has been called
if (handleNewEvent) {
__handleSegmentUpdateCall();
}
else {
var attempts = backoff.attempts + 1;
if (maxChangeNumber <= (segmentsCache.getChangeNumber(segment) || -1)) {
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
isHandlingEvent = false;
return;
}
if (attempts < FETCH_BACKOFF_MAX_RETRIES) {
backoff.scheduleCall();
return;
}
if (cdnBypass) {
log.debug("No changes fetched after ".concat(attempts, " attempts with CDN bypassed."));
isHandlingEvent = false;
}
else {
backoff.reset();
cdnBypass = true;
__handleSegmentUpdateCall();
}
}
});
}
else {
isHandlingEvent = false;
}
}
return {
put: function (changeNumber) {
var currentChangeNumber = segmentsCache.getChangeNumber(segment) || -1;
if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber)
return;
maxChangeNumber = changeNumber;
handleNewEvent = true;
cdnBypass = false;
if (backoff.timeoutID || !isHandlingEvent)
__handleSegmentUpdateCall();
backoff.reset();
},
stop: function () {
isHandlingEvent = false;
backoff.reset();
}
};
}
var segments = {};
return {
/**
* Invoked by NotificationProcessor on SEGMENT_UPDATE event
*
* @param changeNumber - change number of the SEGMENT_UPDATE notification
* @param segmentName - segment name of the SEGMENT_UPDATE notification
*/
put: function (_a) {
var changeNumber = _a.changeNumber, segmentName = _a.segmentName;
if (!segments[segmentName])
segments[segmentName] = SegmentUpdateWorker(segmentName);
segments[segmentName].put(changeNumber);
},
stop: function () {
Object.keys(segments).forEach(function (segmentName) { return segments[segmentName].stop(); });
}
};
}