UNPKG

@splitsoftware/splitio-commons

Version:
89 lines (88 loc) 3.83 kB
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" + (cdnBypass ? ' bypassing the CDN' : '') + " in " + attempts + " attempts."); isHandlingEvent = false; return; } if (attempts < 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; __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(); }); } }; }