UNPKG

@splitsoftware/splitio-commons

Version:
79 lines (78 loc) 4.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.splitChangesFetcherFactory = void 0; var constants_1 = require("../../../utils/constants"); var settingsValidation_1 = require("../../../utils/settingsValidation"); var constants_2 = require("../../../logger/constants"); var key_1 = require("../../../utils/key"); var PROXY_CHECK_INTERVAL_MILLIS_CS = 60 * 60 * 1000; // 1 hour in Client Side var PROXY_CHECK_INTERVAL_MILLIS_SS = 24 * PROXY_CHECK_INTERVAL_MILLIS_CS; // 24 hours in Server Side function sdkEndpointOverridden(settings) { return settings.urls.sdk !== settingsValidation_1.base.urls.sdk; } function isSplitChangesLegacyResponse(data) { return data.splits != null; } function partitionByStatus(items, till, since) { var updated = [], removed = []; items.forEach(function (item) { return item.status === 'ARCHIVED' ? removed.push(item.name) : updated.push(item); }); return { updated: updated, removed: removed, till: till, since: since }; } /** * Factory of SplitChanges fetcher. * SplitChanges fetcher is a wrapper around `splitChanges` API service that parses the response and handle errors. */ // @TODO breaking: drop support for Split Proxy below v5.10.0 and simplify the implementation function splitChangesFetcherFactory(params) { var fetchSplitChanges = params.serviceApi.fetchSplitChanges, settings = params.settings, storage = params.storage; var log = settings.log; var PROXY_CHECK_INTERVAL_MILLIS = (0, key_1.checkIfServerSide)(settings) ? PROXY_CHECK_INTERVAL_MILLIS_SS : PROXY_CHECK_INTERVAL_MILLIS_CS; var lastProxyCheckTimestamp; function splitChangesFetcher(since, noCache, till, rbSince, // Optional decorator for `fetchSplitChanges` promise, such as timeout or time tracker decorator) { // Recheck proxy if (lastProxyCheckTimestamp && (Date.now() - lastProxyCheckTimestamp) > PROXY_CHECK_INTERVAL_MILLIS) { settings.sync.flagSpecVersion = constants_1.FLAG_SPEC_VERSION; } var splitsPromise = fetchSplitChanges(since, noCache, till, settings.sync.flagSpecVersion === constants_1.FLAG_SPEC_VERSION ? rbSince : undefined) .catch(function (err) { // Handle proxy error with spec 1.3 if ((!err.statusCode || err.statusCode === 400) && sdkEndpointOverridden(settings) && settings.sync.flagSpecVersion === constants_1.FLAG_SPEC_VERSION) { log.error(constants_2.LOG_PREFIX_SYNC + 'Proxy error detected. Retrying with spec 1.2. If you are using Split Proxy, please upgrade to latest version'); lastProxyCheckTimestamp = Date.now(); settings.sync.flagSpecVersion = '1.2'; // fallback to 1.2 spec return fetchSplitChanges(since, noCache, till); // retry request without rbSince } throw err; }); if (decorator) splitsPromise = decorator(splitsPromise); return splitsPromise .then(function (resp) { return resp.json(); }) .then(function (data) { // Using flag spec version 1.2 or below if (isSplitChangesLegacyResponse(data)) { return { d: partitionByStatus(data.splits || [], data.till, data.since) }; } // Proxy recovery if (lastProxyCheckTimestamp) { log.info(constants_2.LOG_PREFIX_SYNC + 'Proxy error recovered'); lastProxyCheckTimestamp = undefined; return splitChangesFetcher(-1, undefined, undefined, -1) .then(function (splitChangesResponse) { return Promise.all([storage.definitions.clear(), storage.rbSegments.clear()]) .then(function () { return splitChangesResponse; }); }); } var ff = data.ff, rbs = data.rbs; return { d: (ff === null || ff === void 0 ? void 0 : ff.d) ? partitionByStatus(ff.d, ff.t, ff.s) : undefined, rbs: (rbs === null || rbs === void 0 ? void 0 : rbs.d) ? partitionByStatus(rbs.d, rbs.t, rbs.s) : undefined, }; }); } splitChangesFetcher.type = 'feature flags'; return splitChangesFetcher; } exports.splitChangesFetcherFactory = splitChangesFetcherFactory;