@splitsoftware/splitio-commons 2.1.1-rc.0 → 2.1.1-rc.1

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 (163) hide show
  1. package/CHANGES.txt +3 -0
  2. package/README.md +0 -1
  3. package/cjs/evaluator/combiners/and.js +6 -2
  4. package/cjs/evaluator/combiners/ifelseif.js +6 -6
  5. package/cjs/evaluator/condition/index.js +5 -6
  6. package/cjs/evaluator/index.js +7 -7
  7. package/cjs/evaluator/matchers/index.js +1 -3
  8. package/cjs/evaluator/matchers/matcherTypes.js +0 -1
  9. package/cjs/evaluator/matchersTransform/index.js +0 -4
  10. package/cjs/evaluator/parser/index.js +2 -2
  11. package/cjs/evaluator/value/sanitize.js +0 -1
  12. package/cjs/logger/constants.js +3 -4
  13. package/cjs/logger/messages/debug.js +2 -3
  14. package/cjs/logger/messages/error.js +1 -1
  15. package/cjs/logger/messages/warn.js +2 -2
  16. package/cjs/sdkClient/client.js +29 -19
  17. package/cjs/sdkClient/clientAttributesDecoration.js +19 -25
  18. package/cjs/sdkClient/clientInputValidation.js +28 -26
  19. package/cjs/services/splitApi.js +2 -2
  20. package/cjs/storages/AbstractSplitsCacheSync.js +2 -5
  21. package/cjs/storages/KeyBuilder.js +0 -9
  22. package/cjs/storages/KeyBuilderCS.js +1 -4
  23. package/cjs/storages/KeyBuilderSS.js +0 -3
  24. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +14 -9
  25. package/cjs/storages/inLocalStorage/index.js +0 -4
  26. package/cjs/storages/inMemory/InMemoryStorage.js +0 -3
  27. package/cjs/storages/inMemory/InMemoryStorageCS.js +0 -4
  28. package/cjs/storages/inRedis/index.js +0 -2
  29. package/cjs/storages/pluggable/index.js +0 -2
  30. package/cjs/storages/utils.js +1 -0
  31. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  32. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  33. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  34. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  35. package/cjs/sync/polling/updaters/splitChangesUpdater.js +35 -51
  36. package/cjs/sync/streaming/SSEHandler/index.js +0 -1
  37. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +77 -106
  38. package/cjs/sync/streaming/constants.js +1 -2
  39. package/cjs/sync/streaming/pushManager.js +16 -3
  40. package/cjs/sync/submitters/impressionsSubmitter.js +3 -2
  41. package/cjs/sync/syncManagerOnline.js +2 -2
  42. package/cjs/trackers/strategy/strategyOptimized.js +3 -0
  43. package/cjs/utils/constants/index.js +2 -3
  44. package/cjs/utils/inputValidation/eventProperties.js +12 -1
  45. package/cjs/utils/inputValidation/index.js +3 -1
  46. package/esm/evaluator/combiners/and.js +6 -2
  47. package/esm/evaluator/combiners/ifelseif.js +7 -7
  48. package/esm/evaluator/condition/index.js +5 -6
  49. package/esm/evaluator/index.js +7 -7
  50. package/esm/evaluator/matchers/index.js +1 -3
  51. package/esm/evaluator/matchers/matcherTypes.js +0 -1
  52. package/esm/evaluator/matchersTransform/index.js +0 -4
  53. package/esm/evaluator/parser/index.js +2 -2
  54. package/esm/evaluator/value/sanitize.js +0 -1
  55. package/esm/logger/constants.js +0 -1
  56. package/esm/logger/messages/debug.js +2 -3
  57. package/esm/logger/messages/error.js +1 -1
  58. package/esm/logger/messages/warn.js +2 -2
  59. package/esm/sdkClient/client.js +29 -19
  60. package/esm/sdkClient/clientAttributesDecoration.js +19 -25
  61. package/esm/sdkClient/clientInputValidation.js +29 -27
  62. package/esm/services/splitApi.js +2 -2
  63. package/esm/storages/AbstractSplitsCacheSync.js +2 -5
  64. package/esm/storages/KeyBuilder.js +0 -9
  65. package/esm/storages/KeyBuilderCS.js +1 -4
  66. package/esm/storages/KeyBuilderSS.js +0 -3
  67. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +14 -9
  68. package/esm/storages/inLocalStorage/index.js +0 -4
  69. package/esm/storages/inMemory/InMemoryStorage.js +0 -3
  70. package/esm/storages/inMemory/InMemoryStorageCS.js +0 -4
  71. package/esm/storages/inRedis/index.js +0 -2
  72. package/esm/storages/pluggable/index.js +0 -2
  73. package/esm/storages/utils.js +1 -0
  74. package/esm/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  75. package/esm/sync/polling/pollingManagerCS.js +7 -7
  76. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  77. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  78. package/esm/sync/polling/updaters/splitChangesUpdater.js +35 -51
  79. package/esm/sync/streaming/SSEHandler/index.js +1 -2
  80. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +73 -102
  81. package/esm/sync/streaming/constants.js +0 -1
  82. package/esm/sync/streaming/pushManager.js +19 -6
  83. package/esm/sync/submitters/impressionsSubmitter.js +3 -2
  84. package/esm/sync/syncManagerOnline.js +2 -2
  85. package/esm/trackers/strategy/strategyOptimized.js +3 -0
  86. package/esm/utils/constants/index.js +1 -2
  87. package/esm/utils/inputValidation/eventProperties.js +10 -0
  88. package/esm/utils/inputValidation/index.js +1 -0
  89. package/package.json +1 -1
  90. package/src/dtos/types.ts +8 -32
  91. package/src/evaluator/Engine.ts +1 -1
  92. package/src/evaluator/combiners/and.ts +4 -5
  93. package/src/evaluator/combiners/ifelseif.ts +9 -7
  94. package/src/evaluator/condition/engineUtils.ts +1 -1
  95. package/src/evaluator/condition/index.ts +12 -12
  96. package/src/evaluator/index.ts +7 -7
  97. package/src/evaluator/matchers/index.ts +1 -3
  98. package/src/evaluator/matchers/matcherTypes.ts +0 -1
  99. package/src/evaluator/matchersTransform/index.ts +0 -3
  100. package/src/evaluator/parser/index.ts +3 -3
  101. package/src/evaluator/types.ts +2 -2
  102. package/src/evaluator/value/index.ts +2 -2
  103. package/src/evaluator/value/sanitize.ts +4 -5
  104. package/src/logger/constants.ts +0 -1
  105. package/src/logger/messages/debug.ts +2 -3
  106. package/src/logger/messages/error.ts +1 -1
  107. package/src/logger/messages/warn.ts +2 -2
  108. package/src/sdkClient/client.ts +31 -21
  109. package/src/sdkClient/clientAttributesDecoration.ts +20 -27
  110. package/src/sdkClient/clientInputValidation.ts +30 -27
  111. package/src/sdkManager/index.ts +1 -1
  112. package/src/services/splitApi.ts +2 -2
  113. package/src/services/types.ts +1 -1
  114. package/src/storages/AbstractSplitsCacheSync.ts +3 -6
  115. package/src/storages/KeyBuilder.ts +0 -12
  116. package/src/storages/KeyBuilderCS.ts +1 -5
  117. package/src/storages/KeyBuilderSS.ts +0 -4
  118. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +14 -10
  119. package/src/storages/inLocalStorage/index.ts +0 -4
  120. package/src/storages/inMemory/InMemoryStorage.ts +0 -3
  121. package/src/storages/inMemory/InMemoryStorageCS.ts +0 -4
  122. package/src/storages/inRedis/index.ts +0 -2
  123. package/src/storages/pluggable/index.ts +0 -2
  124. package/src/storages/types.ts +1 -33
  125. package/src/storages/utils.ts +1 -0
  126. package/src/sync/polling/fetchers/splitChangesFetcher.ts +1 -2
  127. package/src/sync/polling/fetchers/types.ts +0 -1
  128. package/src/sync/polling/pollingManagerCS.ts +7 -7
  129. package/src/sync/polling/types.ts +2 -2
  130. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  131. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  132. package/src/sync/polling/updaters/splitChangesUpdater.ts +44 -61
  133. package/src/sync/streaming/SSEHandler/index.ts +1 -2
  134. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  135. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +68 -98
  136. package/src/sync/streaming/constants.ts +0 -1
  137. package/src/sync/streaming/parseUtils.ts +2 -2
  138. package/src/sync/streaming/pushManager.ts +18 -6
  139. package/src/sync/streaming/types.ts +2 -3
  140. package/src/sync/submitters/impressionsSubmitter.ts +3 -2
  141. package/src/sync/submitters/types.ts +23 -33
  142. package/src/sync/syncManagerOnline.ts +2 -2
  143. package/src/trackers/strategy/strategyOptimized.ts +3 -0
  144. package/src/utils/constants/index.ts +1 -2
  145. package/src/utils/inputValidation/eventProperties.ts +10 -0
  146. package/src/utils/inputValidation/index.ts +1 -0
  147. package/src/utils/lang/index.ts +1 -1
  148. package/types/splitio.d.ts +100 -35
  149. package/cjs/evaluator/matchers/rbsegment.js +0 -43
  150. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +0 -117
  151. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +0 -61
  152. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +0 -64
  153. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +0 -64
  154. package/esm/evaluator/matchers/rbsegment.js +0 -39
  155. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +0 -114
  156. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +0 -58
  157. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +0 -61
  158. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +0 -61
  159. package/src/evaluator/matchers/rbsegment.ts +0 -61
  160. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +0 -136
  161. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +0 -68
  162. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +0 -79
  163. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +0 -76
@@ -1,18 +1,16 @@
1
1
  import { ISegmentsCacheBase, IStorageBase } from '../../../storages/types';
2
2
  import { ISplitChangesFetcher } from '../fetchers/types';
3
- import { IRBSegment, ISplit, ISplitChangesResponse, ISplitFiltersValidation, MaybeThenable } from '../../../dtos/types';
3
+ import { ISplit, ISplitChangesResponse, ISplitFiltersValidation } from '../../../dtos/types';
4
4
  import { ISplitsEventEmitter } from '../../../readiness/types';
5
5
  import { timeout } from '../../../utils/promise/timeout';
6
6
  import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
7
7
  import { ILogger } from '../../../logger/types';
8
- import { SYNC_SPLITS_FETCH, SYNC_SPLITS_UPDATE, SYNC_RBS_UPDATE, SYNC_SPLITS_FETCH_FAILS, SYNC_SPLITS_FETCH_RETRY } from '../../../logger/constants';
8
+ import { SYNC_SPLITS_FETCH, SYNC_SPLITS_UPDATE, SYNC_SPLITS_FETCH_FAILS, SYNC_SPLITS_FETCH_RETRY } from '../../../logger/constants';
9
9
  import { startsWith } from '../../../utils/lang';
10
- import { IN_RULE_BASED_SEGMENT, IN_SEGMENT } from '../../../utils/constants';
10
+ import { IN_SEGMENT } from '../../../utils/constants';
11
11
  import { setToArray } from '../../../utils/lang/sets';
12
- import { SPLIT_UPDATE } from '../../streaming/constants';
13
12
 
14
- export type InstantUpdate = { payload: ISplit | IRBSegment, changeNumber: number, type: string };
15
- type SplitChangesUpdater = (noCache?: boolean, till?: number, instantUpdate?: InstantUpdate) => Promise<boolean>
13
+ type ISplitChangesUpdater = (noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit, changeNumber: number }) => Promise<boolean>
16
14
 
17
15
  // Checks that all registered segments have been fetched (changeNumber !== -1 for every segment).
18
16
  // Returns a promise that could be rejected.
@@ -29,24 +27,24 @@ function checkAllSegmentsExist(segments: ISegmentsCacheBase): Promise<boolean> {
29
27
  * Collect segments from a raw split definition.
30
28
  * Exported for testing purposes.
31
29
  */
32
- export function parseSegments(ruleEntity: ISplit | IRBSegment, matcherType: typeof IN_SEGMENT | typeof IN_RULE_BASED_SEGMENT = IN_SEGMENT): Set<string> {
33
- const { conditions, excluded } = ruleEntity as IRBSegment;
34
- const segments = new Set<string>(excluded && excluded.segments);
30
+ export function parseSegments({ conditions }: ISplit): Set<string> {
31
+ let segments = new Set<string>();
35
32
 
36
33
  for (let i = 0; i < conditions.length; i++) {
37
34
  const matchers = conditions[i].matcherGroup.matchers;
38
35
 
39
36
  matchers.forEach(matcher => {
40
- if (matcher.matcherType === matcherType) segments.add(matcher.userDefinedSegmentMatcherData.segmentName);
37
+ if (matcher.matcherType === IN_SEGMENT) segments.add(matcher.userDefinedSegmentMatcherData.segmentName);
41
38
  });
42
39
  }
43
40
 
44
41
  return segments;
45
42
  }
46
43
 
47
- interface ISplitMutations<T extends ISplit | IRBSegment> {
48
- added: T[],
49
- removed: T[]
44
+ interface ISplitMutations {
45
+ added: ISplit[],
46
+ removed: ISplit[],
47
+ segments: string[]
50
48
  }
51
49
 
52
50
  /**
@@ -75,21 +73,25 @@ function matchFilters(featureFlag: ISplit, filters: ISplitFiltersValidation) {
75
73
  * i.e., an object with added splits, removed splits and used segments.
76
74
  * Exported for testing purposes.
77
75
  */
78
- export function computeMutation<T extends ISplit | IRBSegment>(rules: Array<T>, segments: Set<string>, filters?: ISplitFiltersValidation): ISplitMutations<T> {
76
+ export function computeSplitsMutation(entries: ISplit[], filters: ISplitFiltersValidation): ISplitMutations {
77
+ const segments = new Set<string>();
78
+ const computed = entries.reduce((accum, split) => {
79
+ if (split.status === 'ACTIVE' && matchFilters(split, filters)) {
80
+ accum.added.push(split);
79
81
 
80
- return rules.reduce((accum, ruleEntity) => {
81
- if (ruleEntity.status === 'ACTIVE' && (!filters || matchFilters(ruleEntity as ISplit, filters))) {
82
- accum.added.push(ruleEntity);
83
-
84
- parseSegments(ruleEntity).forEach((segmentName: string) => {
82
+ parseSegments(split).forEach((segmentName: string) => {
85
83
  segments.add(segmentName);
86
84
  });
87
85
  } else {
88
- accum.removed.push(ruleEntity);
86
+ accum.removed.push(split);
89
87
  }
90
88
 
91
89
  return accum;
92
- }, { added: [], removed: [] } as ISplitMutations<T>);
90
+ }, { added: [], removed: [], segments: [] } as ISplitMutations);
91
+
92
+ computed.segments = setToArray(segments);
93
+
94
+ return computed;
93
95
  }
94
96
 
95
97
  /**
@@ -109,14 +111,14 @@ export function computeMutation<T extends ISplit | IRBSegment>(rules: Array<T>,
109
111
  export function splitChangesUpdaterFactory(
110
112
  log: ILogger,
111
113
  splitChangesFetcher: ISplitChangesFetcher,
112
- storage: Pick<IStorageBase, 'splits' | 'rbSegments' | 'segments'>,
114
+ storage: Pick<IStorageBase, 'splits' | 'segments'>,
113
115
  splitFiltersValidation: ISplitFiltersValidation,
114
116
  splitsEventEmitter?: ISplitsEventEmitter,
115
117
  requestTimeoutBeforeReady: number = 0,
116
118
  retriesOnFailureBeforeReady: number = 0,
117
119
  isClientSide?: boolean
118
- ): SplitChangesUpdater {
119
- const { splits, rbSegments, segments } = storage;
120
+ ): ISplitChangesUpdater {
121
+ const { splits, segments } = storage;
120
122
 
121
123
  let startingUp = true;
122
124
 
@@ -133,53 +135,34 @@ export function splitChangesUpdaterFactory(
133
135
  * @param noCache - true to revalidate data to fetch
134
136
  * @param till - query param to bypass CDN requests
135
137
  */
136
- return function splitChangesUpdater(noCache?: boolean, till?: number, instantUpdate?: InstantUpdate) {
138
+ return function splitChangesUpdater(noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit, changeNumber: number }) {
137
139
 
138
140
  /**
139
141
  * @param since - current changeNumber at splitsCache
140
142
  * @param retry - current number of retry attempts
141
143
  */
142
- function _splitChangesUpdater(sinces: [number, number], retry = 0): Promise<boolean> {
143
- const [since, rbSince] = sinces;
144
- log.debug(SYNC_SPLITS_FETCH, sinces);
145
- const fetcherPromise = Promise.resolve(
146
- instantUpdate ?
147
- instantUpdate.type === SPLIT_UPDATE ?
148
- // IFFU edge case: a change to a flag that adds an IN_RULE_BASED_SEGMENT matcher that is not present yet
149
- Promise.resolve(rbSegments.contains(parseSegments(instantUpdate.payload, IN_RULE_BASED_SEGMENT))).then((contains) => {
150
- return contains ?
151
- { ff: { d: [instantUpdate.payload as ISplit], t: instantUpdate.changeNumber } } :
152
- splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
153
- }) :
154
- { rbs: { d: [instantUpdate.payload as IRBSegment], t: instantUpdate.changeNumber } } :
155
- splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator)
144
+ function _splitChangesUpdater(since: number, retry = 0): Promise<boolean> {
145
+ log.debug(SYNC_SPLITS_FETCH, [since]);
146
+ const fetcherPromise = Promise.resolve(splitUpdateNotification ?
147
+ { splits: [splitUpdateNotification.payload], till: splitUpdateNotification.changeNumber } :
148
+ splitChangesFetcher(since, noCache, till, _promiseDecorator)
156
149
  )
157
150
  .then((splitChanges: ISplitChangesResponse) => {
158
151
  startingUp = false;
159
152
 
160
- const usedSegments = new Set<string>();
153
+ const mutation = computeSplitsMutation(splitChanges.splits, splitFiltersValidation);
161
154
 
162
- let ffUpdate: MaybeThenable<boolean> = false;
163
- if (splitChanges.ff) {
164
- const { added, removed } = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation);
165
- log.debug(SYNC_SPLITS_UPDATE, [added.length, removed.length]);
166
- ffUpdate = splits.update(added, removed, splitChanges.ff.t);
167
- }
168
-
169
- let rbsUpdate: MaybeThenable<boolean> = false;
170
- if (splitChanges.rbs) {
171
- const { added, removed } = computeMutation(splitChanges.rbs.d, usedSegments);
172
- log.debug(SYNC_RBS_UPDATE, [added.length, removed.length]);
173
- rbsUpdate = rbSegments.update(added, removed, splitChanges.rbs.t);
174
- }
155
+ log.debug(SYNC_SPLITS_UPDATE, [mutation.added.length, mutation.removed.length, mutation.segments.length]);
175
156
 
176
- return Promise.all([ffUpdate, rbsUpdate,
177
- // @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
178
- segments.registerSegments(setToArray(usedSegments))
179
- ]).then(([ffChanged, rbsChanged]) => {
157
+ // Write into storage
158
+ // @TODO call `setChangeNumber` only if the other storage operations have succeeded, in order to keep storage consistency
159
+ return Promise.all([
160
+ splits.update(mutation.added, mutation.removed, splitChanges.till),
161
+ segments.registerSegments(mutation.segments)
162
+ ]).then(([isThereUpdate]) => {
180
163
  if (splitsEventEmitter) {
181
164
  // To emit SDK_SPLITS_ARRIVED for server-side SDK, we must check that all registered segments have been fetched
182
- return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
165
+ return Promise.resolve(!splitsEventEmitter.splitsArrived || (since !== splitChanges.till && isThereUpdate && (isClientSide || checkAllSegmentsExist(segments))))
183
166
  .catch(() => false /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
184
167
  .then(emitSplitsArrivedEvent => {
185
168
  // emit SDK events
@@ -196,7 +179,7 @@ export function splitChangesUpdaterFactory(
196
179
  if (startingUp && retriesOnFailureBeforeReady > retry) {
197
180
  retry += 1;
198
181
  log.info(SYNC_SPLITS_FETCH_RETRY, [retry, error]);
199
- return _splitChangesUpdater(sinces, retry);
182
+ return _splitChangesUpdater(since, retry);
200
183
  } else {
201
184
  startingUp = false;
202
185
  }
@@ -213,7 +196,7 @@ export function splitChangesUpdaterFactory(
213
196
  return fetcherPromise;
214
197
  }
215
198
 
216
- // `getChangeNumber` never rejects or throws error
217
- return Promise.all([splits.getChangeNumber(), rbSegments.getChangeNumber()]).then(_splitChangesUpdater);
199
+ let sincePromise = Promise.resolve(splits.getChangeNumber()); // `getChangeNumber` never rejects or throws error
200
+ return sincePromise.then(_splitChangesUpdater);
218
201
  };
219
202
  }
@@ -1,6 +1,6 @@
1
1
  import { errorParser, messageParser } from './NotificationParser';
2
2
  import { notificationKeeperFactory } from './NotificationKeeper';
3
- import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, RB_SEGMENT_UPDATE } from '../constants';
3
+ import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE } from '../constants';
4
4
  import { IPushEventEmitter } from '../types';
5
5
  import { ISseEventHandler } from '../SSEClient/types';
6
6
  import { INotificationError, INotificationMessage } from './types';
@@ -84,7 +84,6 @@ export function SSEHandlerFactory(log: ILogger, pushEmitter: IPushEventEmitter,
84
84
  case MEMBERSHIPS_MS_UPDATE:
85
85
  case MEMBERSHIPS_LS_UPDATE:
86
86
  case SPLIT_KILL:
87
- case RB_SEGMENT_UPDATE:
88
87
  pushEmitter.emit(parsedData.type, parsedData);
89
88
  break;
90
89
 
@@ -1,5 +1,5 @@
1
1
  import { ControlType } from '../constants';
2
- import { SEGMENT_UPDATE, SPLIT_UPDATE, SPLIT_KILL, CONTROL, OCCUPANCY, MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE, RB_SEGMENT_UPDATE } from '../types';
2
+ import { SEGMENT_UPDATE, SPLIT_UPDATE, SPLIT_KILL, CONTROL, OCCUPANCY, MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE } from '../types';
3
3
 
4
4
  export enum Compression {
5
5
  None = 0,
@@ -42,7 +42,7 @@ export interface ISegmentUpdateData {
42
42
  }
43
43
 
44
44
  export interface ISplitUpdateData {
45
- type: SPLIT_UPDATE | RB_SEGMENT_UPDATE,
45
+ type: SPLIT_UPDATE,
46
46
  changeNumber: number,
47
47
  pcn?: number,
48
48
  d?: string,
@@ -1,16 +1,12 @@
1
- import { IRBSegment, ISplit } from '../../../dtos/types';
2
- import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants';
1
+ import { ISplit } from '../../../dtos/types';
3
2
  import { ILogger } from '../../../logger/types';
4
3
  import { SDK_SPLITS_ARRIVED } from '../../../readiness/constants';
5
4
  import { ISplitsEventEmitter } from '../../../readiness/types';
6
- import { IRBSegmentsCacheSync, ISplitsCacheSync, IStorageSync } from '../../../storages/types';
5
+ import { ISplitsCacheSync } from '../../../storages/types';
7
6
  import { ITelemetryTracker } from '../../../trackers/types';
8
7
  import { Backoff } from '../../../utils/Backoff';
9
8
  import { SPLITS } from '../../../utils/constants';
10
9
  import { ISegmentsSyncTask, ISplitsSyncTask } from '../../polling/types';
11
- import { InstantUpdate } from '../../polling/updaters/splitChangesUpdater';
12
- import { RB_SEGMENT_UPDATE } from '../constants';
13
- import { parseFFUpdatePayload } from '../parseUtils';
14
10
  import { ISplitKillData, ISplitUpdateData } from '../SSEHandler/types';
15
11
  import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES } from './constants';
16
12
  import { IUpdateWorker } from './types';
@@ -18,128 +14,102 @@ import { IUpdateWorker } from './types';
18
14
  /**
19
15
  * SplitsUpdateWorker factory
20
16
  */
21
- export function SplitsUpdateWorker(log: ILogger, storage: IStorageSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker<[updateData: ISplitUpdateData]> & { killSplit(event: ISplitKillData): void } {
17
+ export function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker<[updateData: ISplitUpdateData, payload?: ISplit]> & { killSplit(event: ISplitKillData): void } {
22
18
 
23
- const ff = SplitsUpdateWorker(storage.splits);
24
- const rbs = SplitsUpdateWorker(storage.rbSegments);
19
+ let maxChangeNumber = 0;
20
+ let handleNewEvent = false;
21
+ let isHandlingEvent: boolean;
22
+ let cdnBypass: boolean;
23
+ let payload: ISplit | undefined;
24
+ const backoff = new Backoff(__handleSplitUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
25
25
 
26
- function SplitsUpdateWorker(cache: ISplitsCacheSync | IRBSegmentsCacheSync) {
27
- let maxChangeNumber = -1;
28
- let handleNewEvent = false;
29
- let isHandlingEvent: boolean;
30
- let cdnBypass: boolean;
31
- let instantUpdate: InstantUpdate | undefined;
32
- const backoff = new Backoff(__handleSplitUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
26
+ function __handleSplitUpdateCall() {
27
+ isHandlingEvent = true;
28
+ if (maxChangeNumber > splitsCache.getChangeNumber()) {
29
+ handleNewEvent = false;
30
+ const splitUpdateNotification = payload ? { payload, changeNumber: maxChangeNumber } : undefined;
31
+ // fetch splits revalidating data if cached
32
+ splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, splitUpdateNotification).then(() => {
33
+ if (!isHandlingEvent) return; // halt if `stop` has been called
34
+ if (handleNewEvent) {
35
+ __handleSplitUpdateCall();
36
+ } else {
37
+ if (splitUpdateNotification) telemetryTracker.trackUpdatesFromSSE(SPLITS);
38
+ // fetch new registered segments for server-side API. Not retrying on error
39
+ if (segmentsSyncTask) segmentsSyncTask.execute(true);
33
40
 
34
- function __handleSplitUpdateCall() {
35
- isHandlingEvent = true;
36
- if (maxChangeNumber > cache.getChangeNumber()) {
37
- handleNewEvent = false;
38
- // fetch splits revalidating data if cached
39
- splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(() => {
40
- if (!isHandlingEvent) return; // halt if `stop` has been called
41
- if (handleNewEvent) {
42
- __handleSplitUpdateCall();
43
- } else {
44
- if (instantUpdate) telemetryTracker.trackUpdatesFromSSE(SPLITS);
45
- // fetch new registered segments for server-side API. Not retrying on error
46
- if (segmentsSyncTask) segmentsSyncTask.execute(true);
47
-
48
- const attempts = backoff.attempts + 1;
41
+ const attempts = backoff.attempts + 1;
49
42
 
50
- if (ff.isSync() && rbs.isSync()) {
51
- log.debug(`Refresh completed${cdnBypass ? ' bypassing the CDN' : ''} in ${attempts} attempts.`);
52
- isHandlingEvent = false;
53
- return;
54
- }
43
+ if (maxChangeNumber <= splitsCache.getChangeNumber()) {
44
+ log.debug(`Refresh completed${cdnBypass ? ' bypassing the CDN' : ''} in ${attempts} attempts.`);
45
+ isHandlingEvent = false;
46
+ return;
47
+ }
55
48
 
56
- if (attempts < FETCH_BACKOFF_MAX_RETRIES) {
57
- backoff.scheduleCall();
58
- return;
59
- }
49
+ if (attempts < FETCH_BACKOFF_MAX_RETRIES) {
50
+ backoff.scheduleCall();
51
+ return;
52
+ }
60
53
 
61
- if (cdnBypass) {
62
- log.debug(`No changes fetched after ${attempts} attempts with CDN bypassed.`);
63
- isHandlingEvent = false;
64
- } else {
65
- backoff.reset();
66
- cdnBypass = true;
67
- __handleSplitUpdateCall();
68
- }
54
+ if (cdnBypass) {
55
+ log.debug(`No changes fetched after ${attempts} attempts with CDN bypassed.`);
56
+ isHandlingEvent = false;
57
+ } else {
58
+ backoff.reset();
59
+ cdnBypass = true;
60
+ __handleSplitUpdateCall();
69
61
  }
70
- });
71
- } else {
72
- isHandlingEvent = false;
73
- }
62
+ }
63
+ });
64
+ } else {
65
+ isHandlingEvent = false;
74
66
  }
67
+ }
75
68
 
76
- return {
77
- /**
78
- * Invoked by NotificationProcessor on SPLIT_UPDATE or RB_SEGMENT_UPDATE event
79
- *
80
- * @param changeNumber - change number of the notification
81
- */
82
- put({ changeNumber, pcn, type }: ISplitUpdateData, payload?: ISplit | IRBSegment) {
83
- const currentChangeNumber = cache.getChangeNumber();
69
+ /**
70
+ * Invoked by NotificationProcessor on SPLIT_UPDATE event
71
+ *
72
+ * @param changeNumber - change number of the SPLIT_UPDATE notification
73
+ */
74
+ function put({ changeNumber, pcn }: ISplitUpdateData, _payload?: ISplit) {
75
+ const currentChangeNumber = splitsCache.getChangeNumber();
84
76
 
85
- if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber) return;
77
+ if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber) return;
86
78
 
87
- maxChangeNumber = changeNumber;
88
- handleNewEvent = true;
89
- cdnBypass = false;
90
- instantUpdate = undefined;
79
+ maxChangeNumber = changeNumber;
80
+ handleNewEvent = true;
81
+ cdnBypass = false;
82
+ payload = undefined;
91
83
 
92
- if (payload && currentChangeNumber === pcn) {
93
- instantUpdate = { payload, changeNumber, type };
94
- }
84
+ if (_payload && currentChangeNumber === pcn) {
85
+ payload = _payload;
86
+ }
95
87
 
96
- if (backoff.timeoutID || !isHandlingEvent) __handleSplitUpdateCall();
97
- backoff.reset();
98
- },
99
- stop() {
100
- isHandlingEvent = false;
101
- backoff.reset();
102
- },
103
- isSync() {
104
- return maxChangeNumber <= cache.getChangeNumber();
105
- }
106
- };
88
+ if (backoff.timeoutID || !isHandlingEvent) __handleSplitUpdateCall();
89
+ backoff.reset();
107
90
  }
108
91
 
109
92
  return {
110
- put(parsedData) {
111
- if (parsedData.d && parsedData.c !== undefined) {
112
- try {
113
- const payload = parseFFUpdatePayload(parsedData.c, parsedData.d);
114
- if (payload) {
115
- (parsedData.type === RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData, payload);
116
- return;
117
- }
118
- } catch (e) {
119
- log.warn(STREAMING_PARSING_SPLIT_UPDATE, [parsedData.type, e]);
120
- }
121
- }
122
- (parsedData.type === RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData);
123
- },
93
+ put,
124
94
  /**
125
95
  * Invoked by NotificationProcessor on SPLIT_KILL event
126
96
  *
127
- * @param changeNumber - change number of the notification
97
+ * @param changeNumber - change number of the SPLIT_UPDATE notification
128
98
  * @param splitName - name of split to kill
129
99
  * @param defaultTreatment - default treatment value
130
100
  */
131
101
  killSplit({ changeNumber, splitName, defaultTreatment }: ISplitKillData) {
132
- if (storage.splits.killLocally(splitName, defaultTreatment, changeNumber)) {
102
+ if (splitsCache.killLocally(splitName, defaultTreatment, changeNumber)) {
133
103
  // trigger an SDK_UPDATE if Split was killed locally
134
104
  splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, true);
135
105
  }
136
106
  // queues the SplitChanges fetch (only if changeNumber is newer)
137
- ff.put({ changeNumber } as ISplitUpdateData);
107
+ put({ changeNumber } as ISplitUpdateData);
138
108
  },
139
109
 
140
110
  stop() {
141
- ff.stop();
142
- rbs.stop();
111
+ isHandlingEvent = false;
112
+ backoff.reset();
143
113
  }
144
114
  };
145
115
  }
@@ -30,7 +30,6 @@ export const MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
30
30
  export const SEGMENT_UPDATE = 'SEGMENT_UPDATE';
31
31
  export const SPLIT_KILL = 'SPLIT_KILL';
32
32
  export const SPLIT_UPDATE = 'SPLIT_UPDATE';
33
- export const RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
34
33
 
35
34
  // Control-type push notifications, handled by NotificationKeeper
36
35
  export const CONTROL = 'CONTROL';
@@ -2,7 +2,7 @@ import { algorithms } from '../../utils/decompress';
2
2
  import { decodeFromBase64 } from '../../utils/base64';
3
3
  import { hash } from '../../utils/murmur3/murmur3';
4
4
  import { Compression, IMembershipMSUpdateData, KeyList } from './SSEHandler/types';
5
- import { IRBSegment, ISplit } from '../../dtos/types';
5
+ import { ISplit } from '../../dtos/types';
6
6
 
7
7
  const GZIP = 1;
8
8
  const ZLIB = 2;
@@ -82,7 +82,7 @@ export function isInBitmap(bitmap: Uint8Array, hash64hex: string) {
82
82
  /**
83
83
  * Parse feature flags notifications for instant feature flag updates
84
84
  */
85
- export function parseFFUpdatePayload(compression: Compression, data: string): ISplit | IRBSegment | undefined {
85
+ export function parseFFUpdatePayload(compression: Compression, data: string): ISplit | undefined {
86
86
  return compression > 0 ?
87
87
  parseKeyList(data, compression, false) :
88
88
  JSON.parse(decodeFromBase64(data));
@@ -11,10 +11,10 @@ import { authenticateFactory, hashUserKey } from './AuthClient';
11
11
  import { forOwn } from '../../utils/lang';
12
12
  import { SSEClient } from './SSEClient';
13
13
  import { getMatching } from '../../utils/key';
14
- import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
15
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE } from '../../logger/constants';
14
+ import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
15
+ import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
16
16
  import { IMembershipMSUpdateData, IMembershipLSUpdateData, KeyList, UpdateStrategy } from './SSEHandler/types';
17
- import { getDelay, isInBitmap, parseBitmap, parseKeyList } from './parseUtils';
17
+ import { getDelay, isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
18
18
  import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
19
19
  import { IAuthTokenPushEnabled } from './AuthClient/types';
20
20
  import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
@@ -56,7 +56,7 @@ export function pushManagerFactory(
56
56
  // MySegmentsUpdateWorker (client-side) are initiated in `add` method
57
57
  const segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask as ISegmentsSyncTask, storage.segments);
58
58
  // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
59
- const splitsUpdateWorker = SplitsUpdateWorker(log, storage, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
59
+ const splitsUpdateWorker = SplitsUpdateWorker(log, storage.splits, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
60
60
 
61
61
  // [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
62
62
  const userKeyHashes: Record<string, string> = {};
@@ -219,8 +219,20 @@ export function pushManagerFactory(
219
219
  /** Functions related to synchronization (Queues and Workers in the spec) */
220
220
 
221
221
  pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
222
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
223
- pushEmitter.on(RB_SEGMENT_UPDATE, splitsUpdateWorker.put);
222
+ pushEmitter.on(SPLIT_UPDATE, (parsedData) => {
223
+ if (parsedData.d && parsedData.c !== undefined) {
224
+ try {
225
+ const payload = parseFFUpdatePayload(parsedData.c, parsedData.d);
226
+ if (payload) {
227
+ splitsUpdateWorker.put(parsedData, payload);
228
+ return;
229
+ }
230
+ } catch (e) {
231
+ log.warn(STREAMING_PARSING_SPLIT_UPDATE, [e]);
232
+ }
233
+ }
234
+ splitsUpdateWorker.put(parsedData);
235
+ });
224
236
 
225
237
  function handleMySegmentsUpdate(parsedData: IMembershipMSUpdateData | IMembershipLSUpdateData) {
226
238
  switch (parsedData.u) {
@@ -16,19 +16,18 @@ export type MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
16
16
  export type SEGMENT_UPDATE = 'SEGMENT_UPDATE';
17
17
  export type SPLIT_KILL = 'SPLIT_KILL';
18
18
  export type SPLIT_UPDATE = 'SPLIT_UPDATE';
19
- export type RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
20
19
 
21
20
  // Control-type push notifications, handled by NotificationKeeper
22
21
  export type CONTROL = 'CONTROL';
23
22
  export type OCCUPANCY = 'OCCUPANCY';
24
23
 
25
- export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | RB_SEGMENT_UPDATE | ControlType.STREAMING_RESET
24
+ export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET
26
25
 
27
26
  type IParsedData<T extends IPushEvent> =
28
27
  T extends MEMBERSHIPS_MS_UPDATE ? IMembershipMSUpdateData :
29
28
  T extends MEMBERSHIPS_LS_UPDATE ? IMembershipLSUpdateData :
30
29
  T extends SEGMENT_UPDATE ? ISegmentUpdateData :
31
- T extends SPLIT_UPDATE | RB_SEGMENT_UPDATE ? ISplitUpdateData :
30
+ T extends SPLIT_UPDATE ? ISplitUpdateData :
32
31
  T extends SPLIT_KILL ? ISplitKillData : INotificationData;
33
32
 
34
33
  /**
@@ -25,8 +25,9 @@ export function fromImpressionsCollector(sendLabels: boolean, data: SplitIO.Impr
25
25
  m: entry.time, // Timestamp
26
26
  c: entry.changeNumber, // ChangeNumber
27
27
  r: sendLabels ? entry.label : undefined, // Rule
28
- b: entry.bucketingKey ? entry.bucketingKey : undefined, // Bucketing Key
29
- pt: entry.pt ? entry.pt : undefined // Previous time
28
+ b: entry.bucketingKey, // Bucketing Key
29
+ pt: entry.pt, // Previous time
30
+ properties: entry.properties // Properties
30
31
  };
31
32
 
32
33
  return keyImpression;
@@ -3,26 +3,30 @@ import { IMetadata } from '../../dtos/types';
3
3
  import SplitIO from '../../../types/splitio';
4
4
  import { ISyncTask } from '../types';
5
5
 
6
+ type ImpressionPayload = {
7
+ /** Matching Key */
8
+ k: string;
9
+ /** Bucketing Key */
10
+ b?: string;
11
+ /** Treatment */
12
+ t: string;
13
+ /** Timestamp */
14
+ m: number;
15
+ /** Change number */
16
+ c: number;
17
+ /** Rule label */
18
+ r?: string;
19
+ /** Previous time */
20
+ pt?: number;
21
+ /** Stringified JSON object with properties */
22
+ properties?: string;
23
+ };
24
+
6
25
  export type ImpressionsPayload = {
7
26
  /** Split name */
8
27
  f: string,
9
28
  /** Key Impressions */
10
- i: {
11
- /** User Key */
12
- k: string;
13
- /** Treatment */
14
- t: string;
15
- /** Timestamp */
16
- m: number;
17
- /** ChangeNumber */
18
- c: number;
19
- /** Rule label */
20
- r?: string;
21
- /** Bucketing Key */
22
- b?: string;
23
- /** Previous time */
24
- pt?: number;
25
- }[]
29
+ i: ImpressionPayload[]
26
30
  }[]
27
31
 
28
32
  export type ImpressionCountsPayload = {
@@ -60,23 +64,9 @@ export type StoredImpressionWithMetadata = {
60
64
  /** Metadata */
61
65
  m: IMetadata,
62
66
  /** Stored impression */
63
- i: {
64
- /** keyName */
65
- k: string,
66
- /** bucketingKey */
67
- b?: string,
68
- /** Split name */
69
- f: string,
70
- /** treatment */
71
- t: string,
72
- /** label */
73
- r: string,
74
- /** changeNumber */
75
- c: number,
76
- /** time */
77
- m: number
78
- /** previous time */
79
- pt?: number
67
+ i: ImpressionPayload & {
68
+ /** Feature flag name */
69
+ f: string
80
70
  }
81
71
  }
82
72
 
@@ -149,14 +149,14 @@ export function syncManagerOnlineFactory(
149
149
  if (pushManager) {
150
150
  if (pollingManager.isRunning()) {
151
151
  // if doing polling, we must start the periodic fetch of data
152
- if (storage.splits.usesSegments() || storage.rbSegments.usesSegments()) mySegmentsSyncTask.start();
152
+ if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
153
153
  } else {
154
154
  // if not polling, we must execute the sync task for the initial fetch
155
155
  // of segments since `syncAll` was already executed when starting the main client
156
156
  mySegmentsSyncTask.execute();
157
157
  }
158
158
  } else {
159
- if (storage.splits.usesSegments() || storage.rbSegments.usesSegments()) mySegmentsSyncTask.start();
159
+ if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
160
160
  }
161
161
  } else {
162
162
  if (!readinessManager.isReady()) mySegmentsSyncTask.execute();