-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathpollingManagerCS.ts
More file actions
116 lines (94 loc) · 3.79 KB
/
pollingManagerCS.ts
File metadata and controls
116 lines (94 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { IMySegmentsSyncTask, IPollingManagerCS } from './types';
import { forOwn } from '../../utils/lang';
import { IReadinessManager } from '../../readiness/types';
import { IStorageSync } from '../../storages/types';
import { mySegmentsSyncTaskFactory } from './syncTasks/mySegmentsSyncTask';
import { splitsSyncTaskFactory } from './syncTasks/splitsSyncTask';
import { getMatching } from '../../utils/key';
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
import { POLLING_SMART_PAUSING, POLLING_START, POLLING_STOP } from '../../logger/constants';
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
import { usesSegmentsSync } from '../../storages/AbstractSplitsCacheSync';
/**
* Expose start / stop mechanism for polling data from services.
* For client-side API with multiple clients.
*/
export function pollingManagerCSFactory(
params: ISdkFactoryContextSync
): IPollingManagerCS {
const { splitApi, storage, readiness, settings } = params;
const log = settings.log;
const splitsSyncTask = splitsSyncTaskFactory(splitApi.fetchSplitChanges, storage, readiness, settings, true);
// Map of matching keys to their corresponding MySegmentsSyncTask.
const mySegmentsSyncTasks: Record<string, IMySegmentsSyncTask> = {};
const matchingKey = getMatching(settings.core.key);
const mySegmentsSyncTask = add(matchingKey, readiness, storage);
function startMySegmentsSyncTasks() {
forOwn(mySegmentsSyncTasks, (mySegmentsSyncTask) => {
mySegmentsSyncTask.start();
});
}
function stopMySegmentsSyncTasks() {
forOwn(mySegmentsSyncTasks, (mySegmentsSyncTask) => {
if (mySegmentsSyncTask.isRunning()) mySegmentsSyncTask.stop();
});
}
// smart pausing
readiness.splits.on(SDK_SPLITS_ARRIVED, () => {
if (!splitsSyncTask.isRunning()) return; // noop if not doing polling
const usingSegments = usesSegmentsSync(storage);
if (usingSegments !== mySegmentsSyncTask.isRunning()) {
log.info(POLLING_SMART_PAUSING, [usingSegments ? 'ON' : 'OFF']);
if (usingSegments) {
startMySegmentsSyncTasks();
} else {
stopMySegmentsSyncTasks();
}
}
});
function add(matchingKey: string, readiness: IReadinessManager, storage: IStorageSync) {
const mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
// smart ready
function smartReady() {
if (!readiness.isReady() && !usesSegmentsSync(storage)) readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
}
if (!usesSegmentsSync(storage)) setTimeout(smartReady, 0);
else readiness.splits.once(SDK_SPLITS_ARRIVED, smartReady);
mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
return mySegmentsSyncTask;
}
return {
splitsSyncTask,
segmentsSyncTask: mySegmentsSyncTask,
// Start periodic fetching (polling)
start() {
log.info(POLLING_START);
splitsSyncTask.start();
if (usesSegmentsSync(storage)) startMySegmentsSyncTasks();
},
// Stop periodic fetching (polling)
stop() {
log.info(POLLING_STOP);
if (splitsSyncTask.isRunning()) splitsSyncTask.stop();
stopMySegmentsSyncTasks();
},
// Used by SyncManager to know if running in polling mode.
isRunning: splitsSyncTask.isRunning,
// fetch splits and segments
syncAll() {
const promises = [splitsSyncTask.execute()];
forOwn(mySegmentsSyncTasks, (mySegmentsSyncTask) => {
promises.push(mySegmentsSyncTask.execute());
});
return Promise.all(promises);
},
// Support for handling mySegments sync of multiple clients
add,
remove(matchingKey: string) {
delete mySegmentsSyncTasks[matchingKey];
},
get(matchingKey: string) {
return mySegmentsSyncTasks[matchingKey];
}
};
}