@splitsoftware/splitio-commons 2.8.0 → 2.8.1-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGES.txt +4 -0
  2. package/cjs/storages/AbstractMySegmentsCacheSync.js +31 -23
  3. package/cjs/storages/AbstractSplitsCacheSync.js +3 -2
  4. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +10 -28
  5. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +22 -33
  6. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +19 -29
  7. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +3 -2
  8. package/cjs/storages/inRedis/SegmentsCacheInRedis.js +1 -1
  9. package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +1 -1
  10. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  11. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +16 -5
  12. package/cjs/sync/polling/updaters/splitChangesUpdater.js +3 -3
  13. package/esm/storages/AbstractMySegmentsCacheSync.js +31 -23
  14. package/esm/storages/AbstractSplitsCacheSync.js +3 -2
  15. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +11 -29
  16. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +22 -33
  17. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +19 -29
  18. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +3 -2
  19. package/esm/storages/inRedis/SegmentsCacheInRedis.js +1 -1
  20. package/esm/sync/polling/syncTasks/segmentsSyncTask.js +1 -1
  21. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  22. package/esm/sync/polling/updaters/segmentChangesUpdater.js +16 -5
  23. package/esm/sync/polling/updaters/splitChangesUpdater.js +3 -3
  24. package/package.json +1 -1
  25. package/src/storages/AbstractMySegmentsCacheSync.ts +26 -20
  26. package/src/storages/AbstractSplitsCacheSync.ts +3 -2
  27. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +9 -24
  28. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +18 -27
  29. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +22 -29
  30. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +3 -2
  31. package/src/storages/inRedis/SegmentsCacheInRedis.ts +1 -1
  32. package/src/sync/polling/syncTasks/segmentsSyncTask.ts +2 -0
  33. package/src/sync/polling/updaters/mySegmentsUpdater.ts +3 -3
  34. package/src/sync/polling/updaters/segmentChangesUpdater.ts +17 -4
  35. package/src/sync/polling/updaters/splitChangesUpdater.ts +6 -7
  36. package/types/splitio.d.ts +0 -2
@@ -4,6 +4,7 @@ import { IReadinessManager } from '../../../readiness/types';
4
4
  import { SDK_SEGMENTS_ARRIVED } from '../../../readiness/constants';
5
5
  import { ILogger } from '../../../logger/types';
6
6
  import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC_SEGMENTS } from '../../../logger/constants';
7
+ import { timeout } from '../../../utils/promise/timeout';
7
8
 
8
9
  type ISegmentChangesUpdater = (fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number) => Promise<boolean>
9
10
 
@@ -23,11 +24,18 @@ export function segmentChangesUpdaterFactory(
23
24
  segmentChangesFetcher: ISegmentChangesFetcher,
24
25
  segments: ISegmentsCacheBase,
25
26
  readiness?: IReadinessManager,
27
+ requestTimeoutBeforeReady?: number,
28
+ retriesOnFailureBeforeReady?: number,
26
29
  ): ISegmentChangesUpdater {
27
30
 
28
31
  let readyOnAlreadyExistentState = true;
29
32
 
30
- function updateSegment(segmentName: string, noCache?: boolean, till?: number, fetchOnlyNew?: boolean): Promise<boolean> {
33
+ function _promiseDecorator<T>(promise: Promise<T>) {
34
+ if (readyOnAlreadyExistentState && requestTimeoutBeforeReady) promise = timeout(requestTimeoutBeforeReady, promise);
35
+ return promise;
36
+ }
37
+
38
+ function updateSegment(segmentName: string, noCache?: boolean, till?: number, fetchOnlyNew?: boolean, retries?: number): Promise<boolean> {
31
39
  log.debug(`${LOG_PREFIX_SYNC_SEGMENTS}Processing segment ${segmentName}`);
32
40
  let sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
33
41
 
@@ -35,13 +43,19 @@ export function segmentChangesUpdaterFactory(
35
43
  // if fetchOnlyNew flag, avoid processing already fetched segments
36
44
  return fetchOnlyNew && since !== undefined ?
37
45
  false :
38
- segmentChangesFetcher(since || -1, segmentName, noCache, till).then((changes) => {
46
+ segmentChangesFetcher(since || -1, segmentName, noCache, till, _promiseDecorator).then((changes) => {
39
47
  return Promise.all(changes.map(x => {
40
48
  log.debug(`${LOG_PREFIX_SYNC_SEGMENTS}Processing ${segmentName} with till = ${x.till}. Added: ${x.added.length}. Removed: ${x.removed.length}`);
41
49
  return segments.update(segmentName, x.added, x.removed, x.till);
42
50
  })).then((updates) => {
43
51
  return updates.some(update => update);
44
52
  });
53
+ }).catch(error => {
54
+ if (retries) {
55
+ log.warn(`${LOG_PREFIX_SYNC_SEGMENTS}Retrying fetch of segment ${segmentName} (attempt #${retries}). Reason: ${error}`);
56
+ return updateSegment(segmentName, noCache, till, fetchOnlyNew, retries - 1);
57
+ }
58
+ throw error;
45
59
  });
46
60
  });
47
61
  }
@@ -63,8 +77,7 @@ export function segmentChangesUpdaterFactory(
63
77
  let segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
64
78
 
65
79
  return segmentsPromise.then(segmentNames => {
66
- // Async fetchers
67
- const updaters = segmentNames.map(segmentName => updateSegment(segmentName, noCache, till, fetchOnlyNew));
80
+ const updaters = segmentNames.map(segmentName => updateSegment(segmentName, noCache, till, fetchOnlyNew, readyOnAlreadyExistentState ? retriesOnFailureBeforeReady : 0));
68
81
 
69
82
  return Promise.all(updaters).then(shouldUpdateFlags => {
70
83
  // if at least one segment fetch succeeded, mark segments ready
@@ -120,8 +120,8 @@ export function splitChangesUpdaterFactory(
120
120
  storage: Pick<IStorageBase, 'splits' | 'rbSegments' | 'segments' | 'save'>,
121
121
  splitFiltersValidation: ISplitFiltersValidation,
122
122
  splitsEventEmitter?: ISplitsEventEmitter,
123
- requestTimeoutBeforeReady: number = 0,
124
- retriesOnFailureBeforeReady: number = 0,
123
+ requestTimeoutBeforeReady = 0,
124
+ retriesOnFailureBeforeReady = 0,
125
125
  isClientSide?: boolean
126
126
  ): SplitChangesUpdater {
127
127
  const { splits, rbSegments, segments } = storage;
@@ -163,8 +163,6 @@ export function splitChangesUpdaterFactory(
163
163
  splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator)
164
164
  )
165
165
  .then((splitChanges: ISplitChangesResponse) => {
166
- startingUp = false;
167
-
168
166
  const usedSegments = new Set<string>();
169
167
 
170
168
  let ffUpdate: MaybeThenable<boolean> = false;
@@ -187,6 +185,8 @@ export function splitChangesUpdaterFactory(
187
185
  ]).then(([ffChanged, rbsChanged]) => {
188
186
  if (storage.save) storage.save();
189
187
 
188
+ startingUp = false;
189
+
190
190
  if (splitsEventEmitter) {
191
191
  // To emit SDK_SPLITS_ARRIVED for server-side SDK, we must check that all registered segments have been fetched
192
192
  return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
@@ -201,14 +201,13 @@ export function splitChangesUpdaterFactory(
201
201
  });
202
202
  })
203
203
  .catch(error => {
204
- log.warn(SYNC_SPLITS_FETCH_FAILS, [error]);
205
-
206
204
  if (startingUp && retriesOnFailureBeforeReady > retry) {
207
205
  retry += 1;
208
- log.info(SYNC_SPLITS_FETCH_RETRY, [retry, error]);
206
+ log.warn(SYNC_SPLITS_FETCH_RETRY, [retry, error]);
209
207
  return _splitChangesUpdater(sinces, retry);
210
208
  } else {
211
209
  startingUp = false;
210
+ log.warn(SYNC_SPLITS_FETCH_FAILS, [error]);
212
211
  }
213
212
  return false;
214
213
  });
@@ -1335,8 +1335,6 @@ declare namespace SplitIO {
1335
1335
  /**
1336
1336
  * Defines the factory function to instantiate the storage. If not provided, the default in-memory storage is used.
1337
1337
  *
1338
- * NOTE: Currently, there is no persistent storage option available for the React Native SDK; only `InLocalStorage` for the Browser SDK.
1339
- *
1340
1338
  * Example:
1341
1339
  * ```
1342
1340
  * SplitFactory({