@splitsoftware/splitio-commons 0.1.1-canary.6 → 0.1.1-rc.18

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 (269) hide show
  1. package/cjs/evaluator/matchers/matcherTypes.js +4 -4
  2. package/cjs/evaluator/matchersTransform/index.js +11 -11
  3. package/cjs/evaluator/value/sanitize.js +6 -6
  4. package/cjs/listeners/browser.js +5 -2
  5. package/cjs/listeners/node.js +9 -2
  6. package/cjs/logger/constants.js +3 -1
  7. package/cjs/logger/messages/error.js +3 -2
  8. package/cjs/logger/messages/info.js +2 -2
  9. package/cjs/logger/messages/warn.js +2 -1
  10. package/cjs/readiness/readinessManager.js +10 -7
  11. package/cjs/sdkFactory/index.js +1 -1
  12. package/cjs/services/splitApi.js +9 -1
  13. package/cjs/services/splitHttpClient.js +5 -4
  14. package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
  15. package/cjs/storages/inLocalStorage/index.js +5 -2
  16. package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
  17. package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -0
  18. package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -2
  19. package/cjs/storages/inRedis/index.js +5 -2
  20. package/cjs/storages/pluggable/SplitsCachePluggable.js +6 -2
  21. package/cjs/storages/pluggable/inMemoryWrapper.js +6 -7
  22. package/cjs/storages/pluggable/index.js +5 -2
  23. package/cjs/storages/pluggable/wrapperAdapter.js +0 -1
  24. package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +92 -89
  25. package/cjs/sync/offline/splitsParser/splitsParserFromSettings.js +45 -42
  26. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +14 -4
  27. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +0 -8
  28. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  29. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +2 -4
  30. package/cjs/sync/streaming/SSEClient/index.js +38 -20
  31. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  32. package/cjs/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  33. package/cjs/sync/streaming/SSEHandler/index.js +8 -9
  34. package/cjs/sync/streaming/SSEHandler/types.js +14 -0
  35. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  36. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  37. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  38. package/cjs/sync/streaming/constants.js +3 -1
  39. package/cjs/sync/streaming/mySegmentsV2utils.js +75 -0
  40. package/cjs/sync/streaming/pushManager.js +148 -40
  41. package/cjs/sync/submitters/metricsSyncTask.js +1 -1
  42. package/cjs/sync/submitters/submitterSyncTask.js +2 -2
  43. package/cjs/sync/syncManagerFromFile.js +15 -0
  44. package/cjs/sync/syncManagerFromObject.js +14 -0
  45. package/cjs/sync/syncManagerOffline.js +3 -3
  46. package/cjs/sync/syncManagerOnline.js +18 -5
  47. package/cjs/sync/syncTask.js +1 -1
  48. package/cjs/trackers/impressionObserver/ImpressionObserver.js +0 -2
  49. package/cjs/trackers/impressionObserver/buildKey.js +3 -9
  50. package/cjs/trackers/impressionObserver/impressionObserverCS.js +2 -2
  51. package/cjs/trackers/impressionObserver/impressionObserverSS.js +3 -3
  52. package/cjs/utils/constants/index.js +4 -1
  53. package/cjs/utils/decompress/index.js +427 -0
  54. package/cjs/utils/murmur3/{commons.js → common.js} +2 -6
  55. package/cjs/utils/murmur3/murmur3.js +11 -12
  56. package/cjs/utils/murmur3/murmur3_128.js +7 -142
  57. package/cjs/utils/murmur3/murmur3_128_x86.js +154 -0
  58. package/cjs/utils/murmur3/murmur3_64.js +36 -0
  59. package/cjs/utils/murmur3/utfx.js +100 -106
  60. package/cjs/utils/promise/wrapper.js +14 -11
  61. package/cjs/utils/settingsValidation/index.js +5 -2
  62. package/cjs/utils/settingsValidation/localhost/index.js +20 -0
  63. package/cjs/utils/settingsValidation/splitFilters.js +0 -1
  64. package/cjs/utils/settingsValidation/storage/storageCS.js +18 -8
  65. package/cjs/utils/settingsValidation/url.js +1 -1
  66. package/esm/evaluator/matchers/matcherTypes.js +2 -2
  67. package/esm/evaluator/matchersTransform/index.js +12 -12
  68. package/esm/evaluator/value/sanitize.js +7 -7
  69. package/esm/listeners/browser.js +5 -2
  70. package/esm/listeners/node.js +9 -2
  71. package/esm/logger/constants.js +2 -0
  72. package/esm/logger/messages/error.js +3 -2
  73. package/esm/logger/messages/info.js +2 -2
  74. package/esm/logger/messages/warn.js +2 -1
  75. package/esm/readiness/readinessManager.js +10 -7
  76. package/esm/sdkFactory/index.js +1 -1
  77. package/esm/services/splitApi.js +9 -1
  78. package/esm/services/splitHttpClient.js +5 -4
  79. package/esm/storages/AbstractSplitsCacheSync.js +1 -1
  80. package/esm/storages/inLocalStorage/index.js +5 -2
  81. package/esm/storages/inMemory/InMemoryStorage.js +2 -0
  82. package/esm/storages/inMemory/InMemoryStorageCS.js +2 -0
  83. package/esm/storages/inRedis/SplitsCacheInRedis.js +6 -2
  84. package/esm/storages/inRedis/index.js +5 -2
  85. package/esm/storages/pluggable/SplitsCachePluggable.js +6 -2
  86. package/esm/storages/pluggable/inMemoryWrapper.js +6 -7
  87. package/esm/storages/pluggable/index.js +5 -2
  88. package/esm/storages/pluggable/wrapperAdapter.js +0 -1
  89. package/esm/sync/offline/splitsParser/splitsParserFromFile.js +90 -88
  90. package/esm/sync/offline/splitsParser/splitsParserFromSettings.js +43 -41
  91. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +15 -5
  92. package/esm/sync/polling/fetchers/segmentChangesFetcher.js +0 -8
  93. package/esm/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  94. package/esm/sync/polling/updaters/segmentChangesUpdater.js +2 -4
  95. package/esm/sync/streaming/SSEClient/index.js +38 -20
  96. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  97. package/esm/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  98. package/esm/sync/streaming/SSEHandler/index.js +9 -10
  99. package/esm/sync/streaming/SSEHandler/types.js +13 -1
  100. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  101. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  102. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  103. package/esm/sync/streaming/constants.js +2 -0
  104. package/esm/sync/streaming/mySegmentsV2utils.js +69 -0
  105. package/esm/sync/streaming/pushManager.js +150 -42
  106. package/esm/sync/submitters/metricsSyncTask.js +1 -1
  107. package/esm/sync/submitters/submitterSyncTask.js +2 -2
  108. package/esm/sync/syncManagerFromFile.js +11 -0
  109. package/esm/sync/syncManagerFromObject.js +10 -0
  110. package/esm/sync/syncManagerOffline.js +3 -3
  111. package/esm/sync/syncManagerOnline.js +18 -5
  112. package/esm/sync/syncTask.js +1 -1
  113. package/esm/trackers/impressionObserver/ImpressionObserver.js +0 -2
  114. package/esm/trackers/impressionObserver/buildKey.js +2 -9
  115. package/esm/trackers/impressionObserver/impressionObserverCS.js +2 -2
  116. package/esm/trackers/impressionObserver/impressionObserverSS.js +3 -3
  117. package/esm/utils/constants/index.js +3 -0
  118. package/esm/utils/decompress/index.js +424 -0
  119. package/esm/utils/murmur3/{commons.js → common.js} +1 -4
  120. package/esm/utils/murmur3/murmur3.js +1 -2
  121. package/esm/utils/murmur3/murmur3_128.js +7 -142
  122. package/esm/utils/murmur3/murmur3_128_x86.js +150 -0
  123. package/esm/utils/murmur3/murmur3_64.js +32 -0
  124. package/esm/utils/murmur3/utfx.js +96 -106
  125. package/esm/utils/promise/wrapper.js +14 -11
  126. package/esm/utils/settingsValidation/index.js +5 -2
  127. package/esm/utils/settingsValidation/localhost/index.js +16 -0
  128. package/esm/utils/settingsValidation/splitFilters.js +0 -1
  129. package/esm/utils/settingsValidation/storage/storageCS.js +16 -7
  130. package/esm/utils/settingsValidation/url.js +1 -1
  131. package/package.json +5 -5
  132. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  133. package/src/evaluator/matchersTransform/index.ts +12 -12
  134. package/src/evaluator/value/sanitize.ts +7 -7
  135. package/src/listeners/browser.ts +5 -2
  136. package/src/listeners/node.ts +14 -2
  137. package/src/logger/constants.ts +2 -0
  138. package/src/logger/messages/error.ts +3 -2
  139. package/src/logger/messages/info.ts +2 -2
  140. package/src/logger/messages/warn.ts +3 -1
  141. package/src/readiness/readinessManager.ts +9 -7
  142. package/src/sdkFactory/index.ts +1 -1
  143. package/src/sdkFactory/types.ts +4 -5
  144. package/src/services/splitApi.ts +12 -3
  145. package/src/services/splitHttpClient.ts +6 -5
  146. package/src/services/types.ts +7 -3
  147. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  148. package/src/storages/inLocalStorage/index.ts +8 -4
  149. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  150. package/src/storages/inMemory/InMemoryStorageCS.ts +3 -0
  151. package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -1
  152. package/src/storages/inRedis/index.ts +8 -4
  153. package/src/storages/pluggable/SegmentsCachePluggable.ts +1 -1
  154. package/src/storages/pluggable/SplitsCachePluggable.ts +3 -1
  155. package/src/storages/pluggable/inMemoryWrapper.ts +6 -7
  156. package/src/storages/pluggable/index.ts +8 -4
  157. package/src/storages/pluggable/wrapperAdapter.ts +0 -1
  158. package/src/storages/types.ts +18 -15
  159. package/src/sync/offline/splitsParser/splitsParserFromFile.ts +110 -105
  160. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +45 -41
  161. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +15 -5
  162. package/src/sync/polling/fetchers/segmentChangesFetcher.ts +0 -7
  163. package/src/sync/polling/types.ts +2 -1
  164. package/src/sync/polling/updaters/mySegmentsUpdater.ts +28 -10
  165. package/src/sync/polling/updaters/segmentChangesUpdater.ts +2 -3
  166. package/src/sync/streaming/AuthClient/types.ts +3 -0
  167. package/src/sync/streaming/SSEClient/index.ts +43 -23
  168. package/src/sync/streaming/SSEClient/types.ts +0 -1
  169. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +8 -0
  170. package/src/sync/streaming/SSEHandler/NotificationParser.ts +4 -2
  171. package/src/sync/streaming/SSEHandler/index.ts +11 -20
  172. package/src/sync/streaming/SSEHandler/types.ts +37 -3
  173. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -6
  174. package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +2 -1
  175. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +4 -3
  176. package/src/sync/streaming/UpdateWorkers/types.ts +1 -1
  177. package/src/sync/streaming/constants.ts +2 -0
  178. package/src/sync/streaming/mySegmentsV2utils.ts +77 -0
  179. package/src/sync/streaming/pushManager.ts +145 -42
  180. package/src/sync/streaming/types.ts +14 -22
  181. package/src/sync/submitters/metricsSyncTask.ts +1 -1
  182. package/src/sync/submitters/submitterSyncTask.ts +2 -1
  183. package/src/sync/syncManagerFromFile.ts +13 -0
  184. package/src/sync/syncManagerFromObject.ts +12 -0
  185. package/src/sync/syncManagerOffline.ts +3 -3
  186. package/src/sync/syncManagerOnline.ts +19 -5
  187. package/src/sync/syncTask.ts +1 -1
  188. package/src/sync/types.ts +3 -1
  189. package/src/trackers/impressionObserver/ImpressionObserver.ts +4 -6
  190. package/src/trackers/impressionObserver/buildKey.ts +2 -16
  191. package/src/trackers/impressionObserver/impressionObserverCS.ts +2 -2
  192. package/src/trackers/impressionObserver/impressionObserverSS.ts +3 -3
  193. package/src/types.ts +16 -2
  194. package/src/utils/constants/index.ts +6 -1
  195. package/src/utils/decompress/index.ts +429 -0
  196. package/src/utils/lang/index.ts +1 -1
  197. package/src/utils/murmur3/{commons.ts → common.ts} +1 -5
  198. package/src/utils/murmur3/murmur3.ts +5 -5
  199. package/src/utils/murmur3/murmur3_128.ts +7 -180
  200. package/src/utils/murmur3/murmur3_128_x86.ts +188 -0
  201. package/src/utils/murmur3/murmur3_64.ts +36 -0
  202. package/src/utils/murmur3/utfx.ts +92 -110
  203. package/src/utils/promise/wrapper.ts +12 -9
  204. package/src/utils/settingsValidation/index.ts +8 -4
  205. package/src/utils/settingsValidation/localhost/index.ts +19 -0
  206. package/src/utils/settingsValidation/splitFilters.ts +0 -1
  207. package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
  208. package/src/utils/settingsValidation/types.ts +2 -11
  209. package/src/utils/settingsValidation/url.ts +1 -1
  210. package/types/evaluator/matchers/matcherTypes.d.ts +2 -2
  211. package/types/listeners/browser.d.ts +3 -3
  212. package/types/listeners/node.d.ts +3 -2
  213. package/types/logger/constants.d.ts +2 -0
  214. package/types/sdkFactory/types.d.ts +4 -5
  215. package/types/services/types.d.ts +4 -0
  216. package/types/storages/inLocalStorage/index.d.ts +2 -2
  217. package/types/storages/inMemory/InMemoryStorage.d.ts +3 -0
  218. package/types/storages/inMemory/InMemoryStorageCS.d.ts +3 -0
  219. package/types/storages/inRedis/index.d.ts +2 -2
  220. package/types/storages/pluggable/index.d.ts +2 -2
  221. package/types/storages/types.d.ts +15 -15
  222. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -7
  223. package/types/sync/offline/splitsParser/splitsParserFromSettings.d.ts +1 -5
  224. package/types/sync/polling/types.d.ts +2 -1
  225. package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
  226. package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
  227. package/types/sync/streaming/AuthClient/types.d.ts +2 -0
  228. package/types/sync/streaming/SSEClient/index.d.ts +9 -12
  229. package/types/sync/streaming/SSEClient/types.d.ts +0 -1
  230. package/types/sync/streaming/SSEHandler/NotificationParser.d.ts +3 -2
  231. package/types/sync/streaming/SSEHandler/types.d.ts +30 -2
  232. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -3
  233. package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
  234. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
  235. package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -1
  236. package/types/sync/streaming/constants.d.ts +3 -1
  237. package/types/sync/streaming/mySegmentsV2utils.d.ts +27 -0
  238. package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
  239. package/types/sync/streaming/types.d.ts +9 -5
  240. package/types/sync/submitters/submitterSyncTask.d.ts +1 -1
  241. package/types/sync/syncManagerFromFile.d.ts +2 -0
  242. package/types/sync/syncManagerFromObject.d.ts +2 -0
  243. package/types/sync/syncManagerOffline.d.ts +1 -1
  244. package/types/sync/syncTask.d.ts +1 -1
  245. package/types/sync/types.d.ts +2 -0
  246. package/types/trackers/impressionObserver/ImpressionObserver.d.ts +2 -2
  247. package/types/trackers/impressionObserver/buildKey.d.ts +1 -1
  248. package/types/trackers/impressionObserver/impressionObserverCS.d.ts +2 -2
  249. package/types/trackers/impressionObserver/impressionObserverSS.d.ts +2 -2
  250. package/types/types.d.ts +16 -2
  251. package/types/utils/constants/index.d.ts +5 -1
  252. package/types/utils/decompress/index.d.ts +16 -0
  253. package/types/utils/lang/index.d.ts +1 -1
  254. package/types/utils/murmur3/common.d.ts +12 -0
  255. package/types/utils/murmur3/murmur3.d.ts +2 -2
  256. package/types/utils/murmur3/murmur3_128.d.ts +5 -0
  257. package/types/utils/murmur3/murmur3_128_x86.d.ts +7 -0
  258. package/types/utils/murmur3/murmur3_64.d.ts +10 -0
  259. package/types/utils/murmur3/utfx.d.ts +24 -6
  260. package/types/utils/settingsValidation/index.d.ts +3 -2
  261. package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
  262. package/types/utils/settingsValidation/storage/storageCS.d.ts +7 -1
  263. package/types/utils/settingsValidation/types.d.ts +2 -10
  264. package/cjs/sync/streaming/pushManagerCS.js +0 -178
  265. package/cjs/sync/streaming/pushManagerSS.js +0 -128
  266. package/esm/sync/streaming/pushManagerCS.js +0 -174
  267. package/esm/sync/streaming/pushManagerSS.js +0 -124
  268. package/src/sync/streaming/pushManagerCS.ts +0 -237
  269. package/src/sync/streaming/pushManagerSS.ts +0 -177
@@ -1,178 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var tslib_1 = require("tslib");
4
- var object_assign_1 = tslib_1.__importDefault(require("object-assign"));
5
- var constants_1 = require("./constants");
6
- var Backoff_1 = tslib_1.__importDefault(require("../../utils/Backoff"));
7
- var SSEHandler_1 = tslib_1.__importDefault(require("./SSEHandler"));
8
- var MySegmentsUpdateWorker_1 = tslib_1.__importDefault(require("./UpdateWorkers/MySegmentsUpdateWorker"));
9
- var SplitsUpdateWorker_1 = tslib_1.__importDefault(require("./UpdateWorkers/SplitsUpdateWorker"));
10
- var AuthClient_1 = require("./AuthClient");
11
- var lang_1 = require("../../utils/lang");
12
- var SSEClient_1 = tslib_1.__importDefault(require("./SSEClient"));
13
- var key_1 = require("../../utils/key");
14
- var constants_2 = require("../../logger/constants");
15
- /**
16
- * PushManager factory for client-side, with support for multiple clients.
17
- * It assumes settings contains a key.
18
- */
19
- function pushManagerCSFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
20
- var log = settings.log;
21
- var sseClient;
22
- try {
23
- sseClient = new SSEClient_1.default(settings.urls.streaming, platform.getEventSource);
24
- }
25
- catch (e) {
26
- log.warn(constants_2.STREAMING_FALLBACK, [e]);
27
- return;
28
- }
29
- var authenticate = AuthClient_1.authenticateFactory(fetchAuth);
30
- // init feedback loop
31
- var pushEmitter = new platform.EventEmitter();
32
- var sseHandler = SSEHandler_1.default(log, pushEmitter);
33
- sseClient.setEventHandler(sseHandler);
34
- // [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
35
- var userKeyHashes = {};
36
- var userKey = key_1.getMatching(settings.core.key); // matching key of main client
37
- var hash = AuthClient_1.hashUserKey(userKey);
38
- userKeyHashes[hash] = userKey;
39
- // [Only for client-side] map of user keys to their corresponding MySegmentsUpdateWorkers. It has a two-fold intention:
40
- // - stop workers all together when push is disconnected
41
- // - keep the current list of user keys to authenticate
42
- var workers = {};
43
- // init workers
44
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker_1.default(pollingManager.segmentsSyncTask);
45
- workers[userKey] = mySegmentsUpdateWorker;
46
- var splitsUpdateWorker = new SplitsUpdateWorker_1.default(storage.splits, pollingManager.splitsSyncTask, readiness.splits);
47
- // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
48
- var connectForNewClient = false;
49
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
50
- // It is used to halt the `connectPush` process if it was in progress.
51
- var disconnected;
52
- /** PushManager functions related to initialization */
53
- var connectPushRetryBackoff = new Backoff_1.default(connectPush, settings.scheduler.pushRetryBackoffBase);
54
- var timeoutId;
55
- function scheduleTokenRefresh(issuedAt, expirationTime) {
56
- // clear scheduled token refresh if exists (needed when resuming PUSH)
57
- if (timeoutId)
58
- clearTimeout(timeoutId);
59
- // Set token refresh 10 minutes before expirationTime
60
- var delayInSeconds = expirationTime - issuedAt - constants_1.SECONDS_BEFORE_EXPIRATION;
61
- log.info(constants_2.STREAMING_REFRESH_TOKEN, [delayInSeconds]);
62
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
63
- }
64
- function connectPush() {
65
- disconnected = false;
66
- log.info(constants_2.STREAMING_CONNECTING);
67
- var userKeys = Object.keys(workers); // [Only for client-side]
68
- authenticate(userKeys).then(function (authData) {
69
- if (disconnected)
70
- return;
71
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
72
- // close the sseClient in case the org has been bloqued while the instance was connected to streaming
73
- if (!authData.pushEnabled) {
74
- log.info(constants_2.STREAMING_DISABLED);
75
- pushEmitter.emit(constants_1.PUSH_NONRETRYABLE_ERROR);
76
- return;
77
- }
78
- // [Only for client-side] don't open SSE connection if a new shared client was added, since it means that a new authentication is taking place
79
- if (userKeys && userKeys.length < Object.keys(workers).length)
80
- return;
81
- // Connect to SSE and schedule refresh token
82
- var decodedToken = authData.decodedToken;
83
- sseClient.open(authData);
84
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
85
- }).catch(function (error) {
86
- if (disconnected)
87
- return;
88
- log.error(constants_2.ERROR_STREAMING_AUTH, [error.message]);
89
- // Handle 4XX HTTP errors: 401 (invalid API Key) or 400 (using incorrect API Key, i.e., client-side API Key on server-side)
90
- if (error.statusCode >= 400 && error.statusCode < 500) {
91
- pushEmitter.emit(constants_1.PUSH_NONRETRYABLE_ERROR);
92
- return;
93
- }
94
- // Handle other HTTP and network errors as recoverable errors
95
- pushEmitter.emit(constants_1.PUSH_RETRYABLE_ERROR);
96
- });
97
- }
98
- // close SSE connection and cancel scheduled tasks
99
- function disconnectPush() {
100
- disconnected = true;
101
- log.info(constants_2.STREAMING_DISCONNECTING);
102
- sseClient.close();
103
- if (timeoutId)
104
- clearTimeout(timeoutId);
105
- connectPushRetryBackoff.reset();
106
- stopWorkers();
107
- }
108
- // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
109
- function stopWorkers() {
110
- splitsUpdateWorker.backoff.reset();
111
- lang_1.forOwn(workers, function (worker) { return worker.backoff.reset(); });
112
- }
113
- pushEmitter.on(constants_1.PUSH_SUBSYSTEM_DOWN, stopWorkers);
114
- // restart backoff retry counter once push is connected
115
- pushEmitter.on(constants_1.PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
116
- /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
117
- pushEmitter.on(constants_1.PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
118
- // Note: `stopWorkers` is been called twice, but it is not harmful
119
- disconnectPush();
120
- pushEmitter.emit(constants_1.PUSH_SUBSYSTEM_DOWN); // no harm if polling already
121
- });
122
- /** Fallbacking with retry due to recoverable SSE and Authentication errors */
123
- pushEmitter.on(constants_1.PUSH_RETRYABLE_ERROR, function handleRetryableError() {
124
- // SSE connection is closed to avoid repeated errors due to retries
125
- sseClient.close();
126
- // retry streaming reconnect with backoff algorithm
127
- var delayInMillis = connectPushRetryBackoff.scheduleCall();
128
- log.info(constants_2.STREAMING_RECONNECT, [delayInMillis / 1000]);
129
- pushEmitter.emit(constants_1.PUSH_SUBSYSTEM_DOWN); // no harm if polling already
130
- });
131
- /** Functions related to synchronization (Queues and Workers in the spec) */
132
- pushEmitter.on(constants_1.SPLIT_KILL, splitsUpdateWorker.killSplit);
133
- pushEmitter.on(constants_1.SPLIT_UPDATE, splitsUpdateWorker.put);
134
- // [Only for client-side]
135
- pushEmitter.on(constants_1.MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
136
- var userKeyHash = channel.split('_')[2];
137
- var userKey = userKeyHashes[userKeyHash];
138
- if (userKey && workers[userKey]) { // check context since it can be undefined if client has been destroyed
139
- var mySegmentsUpdateWorker_1 = workers[userKey];
140
- mySegmentsUpdateWorker_1.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
141
- }
142
- });
143
- return object_assign_1.default(
144
- // Expose Event Emitter functionality and Event constants
145
- Object.create(pushEmitter), {
146
- // Expose functionality for starting and stoping push mode:
147
- stop: disconnectPush,
148
- start: function () {
149
- // Run in next event-loop cycle for optimization: if multiple clients are created in the same cycle than the factory, only one authentication is performed.
150
- setTimeout(connectPush);
151
- },
152
- // [Only for client-side]
153
- add: function (userKey, mySegmentsSyncTask) {
154
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker_1.default(mySegmentsSyncTask);
155
- workers[userKey] = mySegmentsUpdateWorker;
156
- var hash = AuthClient_1.hashUserKey(userKey);
157
- if (!userKeyHashes[hash]) {
158
- userKeyHashes[hash] = userKey;
159
- connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
160
- }
161
- // Reconnects in case of a new client.
162
- // Run in next event-loop cycle to save authentication calls
163
- // in case the user is creating several clients in the current cycle.
164
- setTimeout(function checkForReconnect() {
165
- if (connectForNewClient) {
166
- connectForNewClient = false;
167
- connectPush();
168
- }
169
- }, 0);
170
- },
171
- // [Only for client-side]
172
- remove: function (userKey) {
173
- var hash = AuthClient_1.hashUserKey(userKey);
174
- delete userKeyHashes[hash];
175
- }
176
- });
177
- }
178
- exports.default = pushManagerCSFactory;
@@ -1,128 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var tslib_1 = require("tslib");
4
- var object_assign_1 = tslib_1.__importDefault(require("object-assign"));
5
- var constants_1 = require("./constants");
6
- var Backoff_1 = tslib_1.__importDefault(require("../../utils/Backoff"));
7
- var SSEHandler_1 = tslib_1.__importDefault(require("./SSEHandler"));
8
- var SegmentsUpdateWorker_1 = tslib_1.__importDefault(require("./UpdateWorkers/SegmentsUpdateWorker"));
9
- var SplitsUpdateWorker_1 = tslib_1.__importDefault(require("./UpdateWorkers/SplitsUpdateWorker"));
10
- var AuthClient_1 = require("./AuthClient");
11
- var SSEClient_1 = tslib_1.__importDefault(require("./SSEClient"));
12
- var constants_2 = require("../../logger/constants");
13
- /**
14
- * PushManager factory for server-side
15
- */
16
- function pushManagerSSFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
17
- var log = settings.log;
18
- var sseClient;
19
- try {
20
- sseClient = new SSEClient_1.default(settings.urls.streaming, platform.getEventSource);
21
- }
22
- catch (e) {
23
- log.warn(constants_2.STREAMING_FALLBACK, [e]);
24
- return;
25
- }
26
- var authenticate = AuthClient_1.authenticateFactory(fetchAuth);
27
- // init feedback loop (pushEmitter)
28
- var pushEmitter = new platform.EventEmitter();
29
- var sseHandler = SSEHandler_1.default(log, pushEmitter);
30
- sseClient.setEventHandler(sseHandler);
31
- // init workers
32
- var splitsUpdateWorker = new SplitsUpdateWorker_1.default(storage.splits, pollingManager.splitsSyncTask, readiness.splits, pollingManager.segmentsSyncTask);
33
- var segmentsUpdateWorker = new SegmentsUpdateWorker_1.default(storage.segments, pollingManager.segmentsSyncTask);
34
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
35
- // It is used to halt the `connectPush` process if it was in progress.
36
- var disconnected;
37
- /** PushManager functions related to initialization */
38
- var connectPushRetryBackoff = new Backoff_1.default(connectPush, settings.scheduler.pushRetryBackoffBase);
39
- var timeoutId;
40
- function scheduleTokenRefresh(issuedAt, expirationTime) {
41
- // clear scheduled token refresh if exists (needed when resuming PUSH)
42
- if (timeoutId)
43
- clearTimeout(timeoutId);
44
- // Set token refresh 10 minutes before expirationTime
45
- var delayInSeconds = expirationTime - issuedAt - constants_1.SECONDS_BEFORE_EXPIRATION;
46
- log.info(constants_2.STREAMING_REFRESH_TOKEN, [delayInSeconds]);
47
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
48
- }
49
- function connectPush() {
50
- disconnected = false;
51
- log.info(constants_2.STREAMING_CONNECTING);
52
- authenticate().then(function (authData) {
53
- if (disconnected)
54
- return;
55
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
56
- // close the sseClient in case the org has been bloqued while the instance was connected to streaming
57
- if (!authData.pushEnabled) {
58
- log.info(constants_2.STREAMING_DISABLED);
59
- pushEmitter.emit(constants_1.PUSH_NONRETRYABLE_ERROR);
60
- return;
61
- }
62
- // Connect to SSE and schedule refresh token
63
- var decodedToken = authData.decodedToken;
64
- sseClient.open(authData);
65
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
66
- }).catch(function (error) {
67
- if (disconnected)
68
- return;
69
- log.error(constants_2.ERROR_STREAMING_AUTH, [error.message]);
70
- // Handle 4XX HTTP errors: 401 (invalid API Key) or 400 (using incorrect API Key, i.e., client-side API Key on server-side)
71
- if (error.statusCode >= 400 && error.statusCode < 500) {
72
- pushEmitter.emit(constants_1.PUSH_NONRETRYABLE_ERROR);
73
- return;
74
- }
75
- // Handle other HTTP and network errors as recoverable errors
76
- pushEmitter.emit(constants_1.PUSH_RETRYABLE_ERROR);
77
- });
78
- }
79
- // close SSE connection and cancel scheduled tasks
80
- function disconnectPush() {
81
- disconnected = true;
82
- log.info(constants_2.STREAMING_DISCONNECTING);
83
- sseClient.close();
84
- if (timeoutId)
85
- clearTimeout(timeoutId);
86
- connectPushRetryBackoff.reset();
87
- stopWorkers();
88
- }
89
- // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
90
- function stopWorkers() {
91
- splitsUpdateWorker.backoff.reset();
92
- segmentsUpdateWorker.backoff.reset();
93
- }
94
- pushEmitter.on(constants_1.PUSH_SUBSYSTEM_DOWN, stopWorkers);
95
- // restart backoff retry counter once push is connected
96
- pushEmitter.on(constants_1.PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
97
- /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
98
- pushEmitter.on(constants_1.PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
99
- // Note: `stopWorkers` is been called twice, but it is not harmful
100
- disconnectPush();
101
- pushEmitter.emit(constants_1.PUSH_SUBSYSTEM_DOWN); // no harm if polling already
102
- });
103
- /** Fallbacking with retry due to recoverable SSE and Authentication errors */
104
- pushEmitter.on(constants_1.PUSH_RETRYABLE_ERROR, function handleRetryableError() {
105
- // SSE connection is closed to avoid repeated errors due to retries
106
- sseClient.close();
107
- // retry streaming reconnect with backoff algorithm
108
- var delayInMillis = connectPushRetryBackoff.scheduleCall();
109
- log.info(constants_2.STREAMING_RECONNECT, [delayInMillis / 1000]);
110
- pushEmitter.emit(constants_1.PUSH_SUBSYSTEM_DOWN); // no harm if polling already
111
- });
112
- /** Functions related to synchronization (Queues and Workers in the spec) */
113
- pushEmitter.on(constants_1.SPLIT_KILL, splitsUpdateWorker.killSplit);
114
- pushEmitter.on(constants_1.SPLIT_UPDATE, splitsUpdateWorker.put);
115
- // [Only for server-side]
116
- pushEmitter.on(constants_1.SEGMENT_UPDATE, segmentsUpdateWorker.put);
117
- return object_assign_1.default(
118
- // Expose Event Emitter functionality and Event constants
119
- Object.create(pushEmitter), {
120
- // Expose functionality for starting and stoping push mode:
121
- stop: disconnectPush,
122
- start: function () {
123
- // Run in next event-loop cycle as in browser
124
- setTimeout(connectPush);
125
- }
126
- });
127
- }
128
- exports.default = pushManagerSSFactory;
@@ -1,174 +0,0 @@
1
- import objectAssign from 'object-assign';
2
- import { MY_SEGMENTS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP } from './constants';
3
- import Backoff from '../../utils/Backoff';
4
- import SSEHandlerFactory from './SSEHandler';
5
- import MySegmentsUpdateWorker from './UpdateWorkers/MySegmentsUpdateWorker';
6
- import SplitsUpdateWorker from './UpdateWorkers/SplitsUpdateWorker';
7
- import { authenticateFactory, hashUserKey } from './AuthClient';
8
- import { forOwn } from '../../utils/lang';
9
- import SSEClient from './SSEClient';
10
- import { getMatching } from '../../utils/key';
11
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT } from '../../logger/constants';
12
- /**
13
- * PushManager factory for client-side, with support for multiple clients.
14
- * It assumes settings contains a key.
15
- */
16
- export default function pushManagerCSFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
17
- var log = settings.log;
18
- var sseClient;
19
- try {
20
- sseClient = new SSEClient(settings.urls.streaming, platform.getEventSource);
21
- }
22
- catch (e) {
23
- log.warn(STREAMING_FALLBACK, [e]);
24
- return;
25
- }
26
- var authenticate = authenticateFactory(fetchAuth);
27
- // init feedback loop
28
- var pushEmitter = new platform.EventEmitter();
29
- var sseHandler = SSEHandlerFactory(log, pushEmitter);
30
- sseClient.setEventHandler(sseHandler);
31
- // [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
32
- var userKeyHashes = {};
33
- var userKey = getMatching(settings.core.key); // matching key of main client
34
- var hash = hashUserKey(userKey);
35
- userKeyHashes[hash] = userKey;
36
- // [Only for client-side] map of user keys to their corresponding MySegmentsUpdateWorkers. It has a two-fold intention:
37
- // - stop workers all together when push is disconnected
38
- // - keep the current list of user keys to authenticate
39
- var workers = {};
40
- // init workers
41
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker(pollingManager.segmentsSyncTask);
42
- workers[userKey] = mySegmentsUpdateWorker;
43
- var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits);
44
- // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
45
- var connectForNewClient = false;
46
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
47
- // It is used to halt the `connectPush` process if it was in progress.
48
- var disconnected;
49
- /** PushManager functions related to initialization */
50
- var connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
51
- var timeoutId;
52
- function scheduleTokenRefresh(issuedAt, expirationTime) {
53
- // clear scheduled token refresh if exists (needed when resuming PUSH)
54
- if (timeoutId)
55
- clearTimeout(timeoutId);
56
- // Set token refresh 10 minutes before expirationTime
57
- var delayInSeconds = expirationTime - issuedAt - SECONDS_BEFORE_EXPIRATION;
58
- log.info(STREAMING_REFRESH_TOKEN, [delayInSeconds]);
59
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
60
- }
61
- function connectPush() {
62
- disconnected = false;
63
- log.info(STREAMING_CONNECTING);
64
- var userKeys = Object.keys(workers); // [Only for client-side]
65
- authenticate(userKeys).then(function (authData) {
66
- if (disconnected)
67
- return;
68
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
69
- // close the sseClient in case the org has been bloqued while the instance was connected to streaming
70
- if (!authData.pushEnabled) {
71
- log.info(STREAMING_DISABLED);
72
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
73
- return;
74
- }
75
- // [Only for client-side] don't open SSE connection if a new shared client was added, since it means that a new authentication is taking place
76
- if (userKeys && userKeys.length < Object.keys(workers).length)
77
- return;
78
- // Connect to SSE and schedule refresh token
79
- var decodedToken = authData.decodedToken;
80
- sseClient.open(authData);
81
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
82
- }).catch(function (error) {
83
- if (disconnected)
84
- return;
85
- log.error(ERROR_STREAMING_AUTH, [error.message]);
86
- // Handle 4XX HTTP errors: 401 (invalid API Key) or 400 (using incorrect API Key, i.e., client-side API Key on server-side)
87
- if (error.statusCode >= 400 && error.statusCode < 500) {
88
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
89
- return;
90
- }
91
- // Handle other HTTP and network errors as recoverable errors
92
- pushEmitter.emit(PUSH_RETRYABLE_ERROR);
93
- });
94
- }
95
- // close SSE connection and cancel scheduled tasks
96
- function disconnectPush() {
97
- disconnected = true;
98
- log.info(STREAMING_DISCONNECTING);
99
- sseClient.close();
100
- if (timeoutId)
101
- clearTimeout(timeoutId);
102
- connectPushRetryBackoff.reset();
103
- stopWorkers();
104
- }
105
- // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
106
- function stopWorkers() {
107
- splitsUpdateWorker.backoff.reset();
108
- forOwn(workers, function (worker) { return worker.backoff.reset(); });
109
- }
110
- pushEmitter.on(PUSH_SUBSYSTEM_DOWN, stopWorkers);
111
- // restart backoff retry counter once push is connected
112
- pushEmitter.on(PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
113
- /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
114
- pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
115
- // Note: `stopWorkers` is been called twice, but it is not harmful
116
- disconnectPush();
117
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
118
- });
119
- /** Fallbacking with retry due to recoverable SSE and Authentication errors */
120
- pushEmitter.on(PUSH_RETRYABLE_ERROR, function handleRetryableError() {
121
- // SSE connection is closed to avoid repeated errors due to retries
122
- sseClient.close();
123
- // retry streaming reconnect with backoff algorithm
124
- var delayInMillis = connectPushRetryBackoff.scheduleCall();
125
- log.info(STREAMING_RECONNECT, [delayInMillis / 1000]);
126
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
127
- });
128
- /** Functions related to synchronization (Queues and Workers in the spec) */
129
- pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
130
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
131
- // [Only for client-side]
132
- pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
133
- var userKeyHash = channel.split('_')[2];
134
- var userKey = userKeyHashes[userKeyHash];
135
- if (userKey && workers[userKey]) { // check context since it can be undefined if client has been destroyed
136
- var mySegmentsUpdateWorker_1 = workers[userKey];
137
- mySegmentsUpdateWorker_1.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
138
- }
139
- });
140
- return objectAssign(
141
- // Expose Event Emitter functionality and Event constants
142
- Object.create(pushEmitter), {
143
- // Expose functionality for starting and stoping push mode:
144
- stop: disconnectPush,
145
- start: function () {
146
- // Run in next event-loop cycle for optimization: if multiple clients are created in the same cycle than the factory, only one authentication is performed.
147
- setTimeout(connectPush);
148
- },
149
- // [Only for client-side]
150
- add: function (userKey, mySegmentsSyncTask) {
151
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker(mySegmentsSyncTask);
152
- workers[userKey] = mySegmentsUpdateWorker;
153
- var hash = hashUserKey(userKey);
154
- if (!userKeyHashes[hash]) {
155
- userKeyHashes[hash] = userKey;
156
- connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
157
- }
158
- // Reconnects in case of a new client.
159
- // Run in next event-loop cycle to save authentication calls
160
- // in case the user is creating several clients in the current cycle.
161
- setTimeout(function checkForReconnect() {
162
- if (connectForNewClient) {
163
- connectForNewClient = false;
164
- connectPush();
165
- }
166
- }, 0);
167
- },
168
- // [Only for client-side]
169
- remove: function (userKey) {
170
- var hash = hashUserKey(userKey);
171
- delete userKeyHashes[hash];
172
- }
173
- });
174
- }
@@ -1,124 +0,0 @@
1
- import objectAssign from 'object-assign';
2
- import { PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP } from './constants';
3
- import Backoff from '../../utils/Backoff';
4
- import SSEHandlerFactory from './SSEHandler';
5
- import SegmentsUpdateWorker from './UpdateWorkers/SegmentsUpdateWorker';
6
- import SplitsUpdateWorker from './UpdateWorkers/SplitsUpdateWorker';
7
- import { authenticateFactory } from './AuthClient';
8
- import SSEClient from './SSEClient';
9
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT } from '../../logger/constants';
10
- /**
11
- * PushManager factory for server-side
12
- */
13
- export default function pushManagerSSFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
14
- var log = settings.log;
15
- var sseClient;
16
- try {
17
- sseClient = new SSEClient(settings.urls.streaming, platform.getEventSource);
18
- }
19
- catch (e) {
20
- log.warn(STREAMING_FALLBACK, [e]);
21
- return;
22
- }
23
- var authenticate = authenticateFactory(fetchAuth);
24
- // init feedback loop (pushEmitter)
25
- var pushEmitter = new platform.EventEmitter();
26
- var sseHandler = SSEHandlerFactory(log, pushEmitter);
27
- sseClient.setEventHandler(sseHandler);
28
- // init workers
29
- var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits, pollingManager.segmentsSyncTask);
30
- var segmentsUpdateWorker = new SegmentsUpdateWorker(storage.segments, pollingManager.segmentsSyncTask);
31
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
32
- // It is used to halt the `connectPush` process if it was in progress.
33
- var disconnected;
34
- /** PushManager functions related to initialization */
35
- var connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
36
- var timeoutId;
37
- function scheduleTokenRefresh(issuedAt, expirationTime) {
38
- // clear scheduled token refresh if exists (needed when resuming PUSH)
39
- if (timeoutId)
40
- clearTimeout(timeoutId);
41
- // Set token refresh 10 minutes before expirationTime
42
- var delayInSeconds = expirationTime - issuedAt - SECONDS_BEFORE_EXPIRATION;
43
- log.info(STREAMING_REFRESH_TOKEN, [delayInSeconds]);
44
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
45
- }
46
- function connectPush() {
47
- disconnected = false;
48
- log.info(STREAMING_CONNECTING);
49
- authenticate().then(function (authData) {
50
- if (disconnected)
51
- return;
52
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
53
- // close the sseClient in case the org has been bloqued while the instance was connected to streaming
54
- if (!authData.pushEnabled) {
55
- log.info(STREAMING_DISABLED);
56
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
57
- return;
58
- }
59
- // Connect to SSE and schedule refresh token
60
- var decodedToken = authData.decodedToken;
61
- sseClient.open(authData);
62
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
63
- }).catch(function (error) {
64
- if (disconnected)
65
- return;
66
- log.error(ERROR_STREAMING_AUTH, [error.message]);
67
- // Handle 4XX HTTP errors: 401 (invalid API Key) or 400 (using incorrect API Key, i.e., client-side API Key on server-side)
68
- if (error.statusCode >= 400 && error.statusCode < 500) {
69
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
70
- return;
71
- }
72
- // Handle other HTTP and network errors as recoverable errors
73
- pushEmitter.emit(PUSH_RETRYABLE_ERROR);
74
- });
75
- }
76
- // close SSE connection and cancel scheduled tasks
77
- function disconnectPush() {
78
- disconnected = true;
79
- log.info(STREAMING_DISCONNECTING);
80
- sseClient.close();
81
- if (timeoutId)
82
- clearTimeout(timeoutId);
83
- connectPushRetryBackoff.reset();
84
- stopWorkers();
85
- }
86
- // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
87
- function stopWorkers() {
88
- splitsUpdateWorker.backoff.reset();
89
- segmentsUpdateWorker.backoff.reset();
90
- }
91
- pushEmitter.on(PUSH_SUBSYSTEM_DOWN, stopWorkers);
92
- // restart backoff retry counter once push is connected
93
- pushEmitter.on(PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
94
- /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
95
- pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
96
- // Note: `stopWorkers` is been called twice, but it is not harmful
97
- disconnectPush();
98
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
99
- });
100
- /** Fallbacking with retry due to recoverable SSE and Authentication errors */
101
- pushEmitter.on(PUSH_RETRYABLE_ERROR, function handleRetryableError() {
102
- // SSE connection is closed to avoid repeated errors due to retries
103
- sseClient.close();
104
- // retry streaming reconnect with backoff algorithm
105
- var delayInMillis = connectPushRetryBackoff.scheduleCall();
106
- log.info(STREAMING_RECONNECT, [delayInMillis / 1000]);
107
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
108
- });
109
- /** Functions related to synchronization (Queues and Workers in the spec) */
110
- pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
111
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
112
- // [Only for server-side]
113
- pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker.put);
114
- return objectAssign(
115
- // Expose Event Emitter functionality and Event constants
116
- Object.create(pushEmitter), {
117
- // Expose functionality for starting and stoping push mode:
118
- stop: disconnectPush,
119
- start: function () {
120
- // Run in next event-loop cycle as in browser
121
- setTimeout(connectPush);
122
- }
123
- });
124
- }