@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
81 lines (80 loc) • 4.98 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.segmentChangesUpdaterFactory = void 0;
var constants_1 = require("../../../readiness/constants");
var constants_2 = require("../../../logger/constants");
/**
* Factory of SegmentChanges updater, a task that:
* - fetches segment changes using `segmentChangesFetcher`
* - updates `segmentsCache`
* - uses `segmentsEventEmitter` to emit events related to segments data updates
*
* @param log - logger instance
* @param segmentChangesFetcher - fetcher of `/segmentChanges`
* @param segments - segments storage, with sync or async methods
* @param readiness - optional readiness manager. Not required for synchronizer or producer mode.
*/
function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, readiness) {
var readyOnAlreadyExistentState = true;
function updateSegment(segmentName, noCache, till, fetchOnlyNew) {
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing segment " + segmentName);
var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
return sincePromise.then(function (since) {
// if fetchOnlyNew flag, avoid processing already fetched segments
return fetchOnlyNew && since !== undefined ?
false :
segmentChangesFetcher(since || -1, segmentName, noCache, till).then(function (changes) {
return Promise.all(changes.map(function (x) {
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing " + segmentName + " with till = " + x.till + ". Added: " + x.added.length + ". Removed: " + x.removed.length);
return segments.update(segmentName, x.added, x.removed, x.till);
})).then(function (updates) {
return updates.some(function (update) { return update; });
});
});
});
}
/**
* Segments updater returns a promise that resolves with a `false` boolean value if it fails at least to fetch a segment or synchronize it with the storage.
* Thus, a false result doesn't imply that SDK_SEGMENTS_ARRIVED was not emitted.
* Returned promise will not be rejected.
*
* @param fetchOnlyNew - if true, only fetch the segments that not exists, i.e., which `changeNumber` is equal to -1.
* This param is used by SplitUpdateWorker on server-side SDK, to fetch new registered segments on SPLIT_UPDATE or RB_SEGMENT_UPDATE notifications.
* @param segmentName - segment name to fetch. By passing `undefined` it fetches the list of segments registered at the storage
* @param noCache - true to revalidate data to fetch on a SEGMENT_UPDATE notifications.
* @param till - till target for the provided segmentName, for CDN bypass.
*/
return function segmentChangesUpdater(fetchOnlyNew, segmentName, noCache, till) {
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Started segments update");
// If not a segment name provided, read list of available segments names to be updated.
var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
return segmentsPromise.then(function (segmentNames) {
// Async fetchers
var updaters = segmentNames.map(function (segmentName) { return updateSegment(segmentName, noCache, till, fetchOnlyNew); });
return Promise.all(updaters).then(function (shouldUpdateFlags) {
// if at least one segment fetch succeeded, mark segments ready
if (shouldUpdateFlags.some(function (update) { return update; }) || readyOnAlreadyExistentState) {
readyOnAlreadyExistentState = false;
if (readiness)
readiness.segments.emit(constants_1.SDK_SEGMENTS_ARRIVED);
}
return true;
});
})
// Handles rejected promises at `segmentChangesFetcher`, `segments.getRegisteredSegments` and other segment storage operations.
.catch(function (error) {
if (error && error.statusCode === 403) {
// If the operation is forbidden, it may be due to permissions. Destroy the SDK instance.
// @TODO although factory status is destroyed, synchronization is not stopped
if (readiness)
readiness.setDestroyed();
log.error(constants_2.LOG_PREFIX_INSTANTIATION + ": you passed a client-side type authorizationKey, please grab an SDK Key from the Split user interface that is of type server-side.");
}
else {
log.warn(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Error while doing fetch of segments. " + error);
}
return false;
});
};
}
exports.segmentChangesUpdaterFactory = segmentChangesUpdaterFactory;