@webex/internal-plugin-presence 2.59.2 → 2.59.3-next.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.
- package/.eslintrc.js +6 -6
- package/README.md +42 -42
- package/babel.config.js +3 -3
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/presence-batcher.js +42 -42
- package/dist/presence-batcher.js.map +1 -1
- package/dist/presence-worker.js +43 -43
- package/dist/presence-worker.js.map +1 -1
- package/dist/presence.js +75 -75
- package/dist/presence.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +19 -18
- package/process +1 -1
- package/src/config.js +11 -11
- package/src/constants.js +19 -19
- package/src/index.js +41 -41
- package/src/presence-batcher.js +100 -100
- package/src/presence-worker.js +268 -268
- package/src/presence.js +262 -262
- package/test/integration/spec/presence.js +213 -213
- package/test/unit/spec/presence-worker.js +264 -264
- package/test/unit/spec/presence.js +68 -68
package/src/presence-worker.js
CHANGED
|
@@ -1,268 +1,268 @@
|
|
|
1
|
-
import {debounce} from 'lodash';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
FETCH_DELAY,
|
|
5
|
-
GROUNDSKEEPER_INTERVAL,
|
|
6
|
-
SUBSCRIPTION_DELAY,
|
|
7
|
-
UPDATE_PRESENCE_DELAY,
|
|
8
|
-
EXPIRED_PRESENCE_TIME,
|
|
9
|
-
PREMATURE_EXPIRATION_SUBSCRIPTION_TIME,
|
|
10
|
-
DEFAULT_SUBSCRIPTION_TTL,
|
|
11
|
-
APHELEIA_SUBSCRIPTION_UPDATE,
|
|
12
|
-
PRESENCE_UPDATE,
|
|
13
|
-
ENVELOPE_TYPE,
|
|
14
|
-
} from './constants';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Presence Worker
|
|
18
|
-
* Manages fetches and subscriptions for presence
|
|
19
|
-
* @class
|
|
20
|
-
*/
|
|
21
|
-
export default class PresenceWorker {
|
|
22
|
-
/**
|
|
23
|
-
* Constructs a presence worker to execute and
|
|
24
|
-
* maintain tasks related to presence upkeep.
|
|
25
|
-
* @returns {undefined}
|
|
26
|
-
*/
|
|
27
|
-
constructor() {
|
|
28
|
-
this.presences = {}; // current presence objects; updated time
|
|
29
|
-
this.watchers = {}; // counter of visible presence-required objects
|
|
30
|
-
this.fetchers = {}; // waiting to get presence object
|
|
31
|
-
this.flights = {}; // in flight to get presence object
|
|
32
|
-
this.campers = {}; // waiting to subscribe; updated time
|
|
33
|
-
this.subscribers = {}; // current subscriptions; expiration time
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Connect to the mercury for presence and starts worker.
|
|
38
|
-
* @param {object} webex
|
|
39
|
-
* @returns {undefined}
|
|
40
|
-
*/
|
|
41
|
-
initialize(webex) {
|
|
42
|
-
if (!webex || !webex.internal) {
|
|
43
|
-
throw new Error('Must initialize Presence Worker with webex!');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
this.webex = webex;
|
|
47
|
-
|
|
48
|
-
const mercury = this.webex.internal.mercury.connected
|
|
49
|
-
? Promise.resolve()
|
|
50
|
-
: this.webex.internal.mercury.connect();
|
|
51
|
-
|
|
52
|
-
mercury.then(() => {
|
|
53
|
-
this.webex.internal.mercury.on(
|
|
54
|
-
APHELEIA_SUBSCRIPTION_UPDATE,
|
|
55
|
-
this.subscriptionUpdate.bind(this)
|
|
56
|
-
);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
setInterval(this.groundskeeper.bind(this), GROUNDSKEEPER_INTERVAL);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Trigger a subscription update event.
|
|
64
|
-
* @param {string} event
|
|
65
|
-
* @returns {undefined}
|
|
66
|
-
*/
|
|
67
|
-
subscriptionUpdate(event) {
|
|
68
|
-
this.presences[event.data.subject] = new Date().getTime();
|
|
69
|
-
|
|
70
|
-
this.webex.internal.presence.emitEvent(PRESENCE_UPDATE, {
|
|
71
|
-
type: ENVELOPE_TYPE.SUBSCRIPTION,
|
|
72
|
-
payload: event.data,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Retrieves and subscribes to a user's presence.
|
|
78
|
-
* @param {string} id
|
|
79
|
-
* @returns {undefined}
|
|
80
|
-
*/
|
|
81
|
-
enqueue(id) {
|
|
82
|
-
const now = new Date().getTime();
|
|
83
|
-
|
|
84
|
-
if (this.watchers[id]) {
|
|
85
|
-
this.watchers[id] += 1;
|
|
86
|
-
} else {
|
|
87
|
-
this.watchers[id] = 1;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (this.subscribers[id]) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!this.campers[id]) {
|
|
95
|
-
this.campers[id] = now;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Retrieve presence if:
|
|
99
|
-
// not in flight or
|
|
100
|
-
// don't already have the presence or
|
|
101
|
-
// presence has gone stale
|
|
102
|
-
if (
|
|
103
|
-
!this.flights[id] &&
|
|
104
|
-
(!this.presences[id] || this.presences[id] < now - UPDATE_PRESENCE_DELAY)
|
|
105
|
-
) {
|
|
106
|
-
this.fetchers[id] = id;
|
|
107
|
-
this.debouncedFetch();
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Retract from subscribing to a user's presence.
|
|
113
|
-
* @param {string} id
|
|
114
|
-
* @returns {undefined}
|
|
115
|
-
*/
|
|
116
|
-
dequeue(id) {
|
|
117
|
-
if (this.watchers[id]) {
|
|
118
|
-
this.watchers[id] -= 1;
|
|
119
|
-
|
|
120
|
-
if (this.watchers[id] <= 0) {
|
|
121
|
-
delete this.watchers[id];
|
|
122
|
-
delete this.fetchers[id];
|
|
123
|
-
delete this.campers[id];
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Retrieve users' presences.
|
|
130
|
-
* @returns {undefined}
|
|
131
|
-
*/
|
|
132
|
-
checkFetchers() {
|
|
133
|
-
const boarding = this.fetchers;
|
|
134
|
-
|
|
135
|
-
Object.assign(this.flights, boarding);
|
|
136
|
-
this.fetchers = {};
|
|
137
|
-
|
|
138
|
-
this.webex.internal.presence.list(Object.keys(boarding)).then((response) => {
|
|
139
|
-
const now = new Date().getTime();
|
|
140
|
-
|
|
141
|
-
response.statusList.forEach((presence) => {
|
|
142
|
-
const id = presence.subject;
|
|
143
|
-
|
|
144
|
-
delete this.flights[id];
|
|
145
|
-
this.presences[id] = now;
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
this.webex.internal.presence.emitEvent(PRESENCE_UPDATE, {
|
|
149
|
-
type: ENVELOPE_TYPE.PRESENCE,
|
|
150
|
-
payload: response,
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
debouncedFetch = debounce(this.checkFetchers, FETCH_DELAY);
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Determine if we should subscribe to users' presences.
|
|
159
|
-
* @returns {Array}: User ids to subscribe.
|
|
160
|
-
*/
|
|
161
|
-
checkCampers() {
|
|
162
|
-
const now = new Date().getTime();
|
|
163
|
-
const subscribers = [];
|
|
164
|
-
|
|
165
|
-
Object.entries(this.campers).forEach((camper) => {
|
|
166
|
-
const id = camper[0];
|
|
167
|
-
const time = camper[1];
|
|
168
|
-
|
|
169
|
-
// Subscribe if they've been camping for a minute
|
|
170
|
-
if (time < now - SUBSCRIPTION_DELAY) {
|
|
171
|
-
delete this.campers[id];
|
|
172
|
-
this.subscribers[id] = null;
|
|
173
|
-
subscribers.push(id);
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
return subscribers;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Determine if we should re-subscribe or remove users' subscriptions.
|
|
182
|
-
* @returns {Array}: User ids to re-subscribe.
|
|
183
|
-
*/
|
|
184
|
-
checkSubscriptions() {
|
|
185
|
-
const now = new Date().getTime();
|
|
186
|
-
|
|
187
|
-
const renewIds = [];
|
|
188
|
-
|
|
189
|
-
Object.entries(this.subscribers).forEach((subscription) => {
|
|
190
|
-
const id = subscription[0];
|
|
191
|
-
const expiration = subscription[1];
|
|
192
|
-
|
|
193
|
-
if (expiration) {
|
|
194
|
-
// Renew subscription if they're about to expire
|
|
195
|
-
if (this.watchers[id] && now > expiration - PREMATURE_EXPIRATION_SUBSCRIPTION_TIME) {
|
|
196
|
-
renewIds.push(id);
|
|
197
|
-
} else if (now > expiration) {
|
|
198
|
-
delete this.subscribers[id];
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
return renewIds;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Remove expired presence objects.
|
|
208
|
-
* @returns {undefined}
|
|
209
|
-
*/
|
|
210
|
-
cleanPresences() {
|
|
211
|
-
const trash = [];
|
|
212
|
-
const tenMinutesAgo = new Date().getTime() - EXPIRED_PRESENCE_TIME;
|
|
213
|
-
|
|
214
|
-
Object.entries(this.presences).forEach((presence) => {
|
|
215
|
-
const id = presence[0];
|
|
216
|
-
const lastUpdated = presence[1];
|
|
217
|
-
|
|
218
|
-
// Delete the object if it is stale
|
|
219
|
-
if (lastUpdated < tenMinutesAgo) {
|
|
220
|
-
delete this.presences[id];
|
|
221
|
-
trash.push(id);
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// Tells client to delete it too
|
|
226
|
-
if (trash.length) {
|
|
227
|
-
this.webex.internal.presence.emitEvent(PRESENCE_UPDATE, {
|
|
228
|
-
type: ENVELOPE_TYPE.DELETE,
|
|
229
|
-
payload: trash,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Execute chores on an interval.
|
|
236
|
-
* Checks if we should make new subscribe,
|
|
237
|
-
* checks if we should re-subscribe,
|
|
238
|
-
* removes expired subscriptions,
|
|
239
|
-
* removes expired presence objects.
|
|
240
|
-
* @returns {undefined}
|
|
241
|
-
*/
|
|
242
|
-
groundskeeper() {
|
|
243
|
-
const campers = this.checkCampers();
|
|
244
|
-
const renewSubscriptions = this.checkSubscriptions();
|
|
245
|
-
|
|
246
|
-
const ids = [...campers, ...renewSubscriptions];
|
|
247
|
-
|
|
248
|
-
if (ids.length) {
|
|
249
|
-
this.webex.internal.presence.subscribe(ids).then((body) => {
|
|
250
|
-
const now = new Date().getTime();
|
|
251
|
-
|
|
252
|
-
body.responses.forEach((response) => {
|
|
253
|
-
if (response.responseCode === 200) {
|
|
254
|
-
const ttl = response.subscriptionTtl * 1000;
|
|
255
|
-
|
|
256
|
-
this.subscribers[response.subject] = now + ttl;
|
|
257
|
-
this.presences[response.status.subject] = now;
|
|
258
|
-
} else {
|
|
259
|
-
// If it errored for any reason, set the ttl so we clean it out eventually
|
|
260
|
-
this.subscribers[response.subject] = now + DEFAULT_SUBSCRIPTION_TTL;
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
this.cleanPresences();
|
|
267
|
-
}
|
|
268
|
-
}
|
|
1
|
+
import {debounce} from 'lodash';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
FETCH_DELAY,
|
|
5
|
+
GROUNDSKEEPER_INTERVAL,
|
|
6
|
+
SUBSCRIPTION_DELAY,
|
|
7
|
+
UPDATE_PRESENCE_DELAY,
|
|
8
|
+
EXPIRED_PRESENCE_TIME,
|
|
9
|
+
PREMATURE_EXPIRATION_SUBSCRIPTION_TIME,
|
|
10
|
+
DEFAULT_SUBSCRIPTION_TTL,
|
|
11
|
+
APHELEIA_SUBSCRIPTION_UPDATE,
|
|
12
|
+
PRESENCE_UPDATE,
|
|
13
|
+
ENVELOPE_TYPE,
|
|
14
|
+
} from './constants';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Presence Worker
|
|
18
|
+
* Manages fetches and subscriptions for presence
|
|
19
|
+
* @class
|
|
20
|
+
*/
|
|
21
|
+
export default class PresenceWorker {
|
|
22
|
+
/**
|
|
23
|
+
* Constructs a presence worker to execute and
|
|
24
|
+
* maintain tasks related to presence upkeep.
|
|
25
|
+
* @returns {undefined}
|
|
26
|
+
*/
|
|
27
|
+
constructor() {
|
|
28
|
+
this.presences = {}; // current presence objects; updated time
|
|
29
|
+
this.watchers = {}; // counter of visible presence-required objects
|
|
30
|
+
this.fetchers = {}; // waiting to get presence object
|
|
31
|
+
this.flights = {}; // in flight to get presence object
|
|
32
|
+
this.campers = {}; // waiting to subscribe; updated time
|
|
33
|
+
this.subscribers = {}; // current subscriptions; expiration time
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Connect to the mercury for presence and starts worker.
|
|
38
|
+
* @param {object} webex
|
|
39
|
+
* @returns {undefined}
|
|
40
|
+
*/
|
|
41
|
+
initialize(webex) {
|
|
42
|
+
if (!webex || !webex.internal) {
|
|
43
|
+
throw new Error('Must initialize Presence Worker with webex!');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this.webex = webex;
|
|
47
|
+
|
|
48
|
+
const mercury = this.webex.internal.mercury.connected
|
|
49
|
+
? Promise.resolve()
|
|
50
|
+
: this.webex.internal.mercury.connect();
|
|
51
|
+
|
|
52
|
+
mercury.then(() => {
|
|
53
|
+
this.webex.internal.mercury.on(
|
|
54
|
+
APHELEIA_SUBSCRIPTION_UPDATE,
|
|
55
|
+
this.subscriptionUpdate.bind(this)
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
setInterval(this.groundskeeper.bind(this), GROUNDSKEEPER_INTERVAL);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Trigger a subscription update event.
|
|
64
|
+
* @param {string} event
|
|
65
|
+
* @returns {undefined}
|
|
66
|
+
*/
|
|
67
|
+
subscriptionUpdate(event) {
|
|
68
|
+
this.presences[event.data.subject] = new Date().getTime();
|
|
69
|
+
|
|
70
|
+
this.webex.internal.presence.emitEvent(PRESENCE_UPDATE, {
|
|
71
|
+
type: ENVELOPE_TYPE.SUBSCRIPTION,
|
|
72
|
+
payload: event.data,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Retrieves and subscribes to a user's presence.
|
|
78
|
+
* @param {string} id
|
|
79
|
+
* @returns {undefined}
|
|
80
|
+
*/
|
|
81
|
+
enqueue(id) {
|
|
82
|
+
const now = new Date().getTime();
|
|
83
|
+
|
|
84
|
+
if (this.watchers[id]) {
|
|
85
|
+
this.watchers[id] += 1;
|
|
86
|
+
} else {
|
|
87
|
+
this.watchers[id] = 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (this.subscribers[id]) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!this.campers[id]) {
|
|
95
|
+
this.campers[id] = now;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Retrieve presence if:
|
|
99
|
+
// not in flight or
|
|
100
|
+
// don't already have the presence or
|
|
101
|
+
// presence has gone stale
|
|
102
|
+
if (
|
|
103
|
+
!this.flights[id] &&
|
|
104
|
+
(!this.presences[id] || this.presences[id] < now - UPDATE_PRESENCE_DELAY)
|
|
105
|
+
) {
|
|
106
|
+
this.fetchers[id] = id;
|
|
107
|
+
this.debouncedFetch();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Retract from subscribing to a user's presence.
|
|
113
|
+
* @param {string} id
|
|
114
|
+
* @returns {undefined}
|
|
115
|
+
*/
|
|
116
|
+
dequeue(id) {
|
|
117
|
+
if (this.watchers[id]) {
|
|
118
|
+
this.watchers[id] -= 1;
|
|
119
|
+
|
|
120
|
+
if (this.watchers[id] <= 0) {
|
|
121
|
+
delete this.watchers[id];
|
|
122
|
+
delete this.fetchers[id];
|
|
123
|
+
delete this.campers[id];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Retrieve users' presences.
|
|
130
|
+
* @returns {undefined}
|
|
131
|
+
*/
|
|
132
|
+
checkFetchers() {
|
|
133
|
+
const boarding = this.fetchers;
|
|
134
|
+
|
|
135
|
+
Object.assign(this.flights, boarding);
|
|
136
|
+
this.fetchers = {};
|
|
137
|
+
|
|
138
|
+
this.webex.internal.presence.list(Object.keys(boarding)).then((response) => {
|
|
139
|
+
const now = new Date().getTime();
|
|
140
|
+
|
|
141
|
+
response.statusList.forEach((presence) => {
|
|
142
|
+
const id = presence.subject;
|
|
143
|
+
|
|
144
|
+
delete this.flights[id];
|
|
145
|
+
this.presences[id] = now;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
this.webex.internal.presence.emitEvent(PRESENCE_UPDATE, {
|
|
149
|
+
type: ENVELOPE_TYPE.PRESENCE,
|
|
150
|
+
payload: response,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
debouncedFetch = debounce(this.checkFetchers, FETCH_DELAY);
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Determine if we should subscribe to users' presences.
|
|
159
|
+
* @returns {Array}: User ids to subscribe.
|
|
160
|
+
*/
|
|
161
|
+
checkCampers() {
|
|
162
|
+
const now = new Date().getTime();
|
|
163
|
+
const subscribers = [];
|
|
164
|
+
|
|
165
|
+
Object.entries(this.campers).forEach((camper) => {
|
|
166
|
+
const id = camper[0];
|
|
167
|
+
const time = camper[1];
|
|
168
|
+
|
|
169
|
+
// Subscribe if they've been camping for a minute
|
|
170
|
+
if (time < now - SUBSCRIPTION_DELAY) {
|
|
171
|
+
delete this.campers[id];
|
|
172
|
+
this.subscribers[id] = null;
|
|
173
|
+
subscribers.push(id);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return subscribers;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Determine if we should re-subscribe or remove users' subscriptions.
|
|
182
|
+
* @returns {Array}: User ids to re-subscribe.
|
|
183
|
+
*/
|
|
184
|
+
checkSubscriptions() {
|
|
185
|
+
const now = new Date().getTime();
|
|
186
|
+
|
|
187
|
+
const renewIds = [];
|
|
188
|
+
|
|
189
|
+
Object.entries(this.subscribers).forEach((subscription) => {
|
|
190
|
+
const id = subscription[0];
|
|
191
|
+
const expiration = subscription[1];
|
|
192
|
+
|
|
193
|
+
if (expiration) {
|
|
194
|
+
// Renew subscription if they're about to expire
|
|
195
|
+
if (this.watchers[id] && now > expiration - PREMATURE_EXPIRATION_SUBSCRIPTION_TIME) {
|
|
196
|
+
renewIds.push(id);
|
|
197
|
+
} else if (now > expiration) {
|
|
198
|
+
delete this.subscribers[id];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
return renewIds;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Remove expired presence objects.
|
|
208
|
+
* @returns {undefined}
|
|
209
|
+
*/
|
|
210
|
+
cleanPresences() {
|
|
211
|
+
const trash = [];
|
|
212
|
+
const tenMinutesAgo = new Date().getTime() - EXPIRED_PRESENCE_TIME;
|
|
213
|
+
|
|
214
|
+
Object.entries(this.presences).forEach((presence) => {
|
|
215
|
+
const id = presence[0];
|
|
216
|
+
const lastUpdated = presence[1];
|
|
217
|
+
|
|
218
|
+
// Delete the object if it is stale
|
|
219
|
+
if (lastUpdated < tenMinutesAgo) {
|
|
220
|
+
delete this.presences[id];
|
|
221
|
+
trash.push(id);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Tells client to delete it too
|
|
226
|
+
if (trash.length) {
|
|
227
|
+
this.webex.internal.presence.emitEvent(PRESENCE_UPDATE, {
|
|
228
|
+
type: ENVELOPE_TYPE.DELETE,
|
|
229
|
+
payload: trash,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Execute chores on an interval.
|
|
236
|
+
* Checks if we should make new subscribe,
|
|
237
|
+
* checks if we should re-subscribe,
|
|
238
|
+
* removes expired subscriptions,
|
|
239
|
+
* removes expired presence objects.
|
|
240
|
+
* @returns {undefined}
|
|
241
|
+
*/
|
|
242
|
+
groundskeeper() {
|
|
243
|
+
const campers = this.checkCampers();
|
|
244
|
+
const renewSubscriptions = this.checkSubscriptions();
|
|
245
|
+
|
|
246
|
+
const ids = [...campers, ...renewSubscriptions];
|
|
247
|
+
|
|
248
|
+
if (ids.length) {
|
|
249
|
+
this.webex.internal.presence.subscribe(ids).then((body) => {
|
|
250
|
+
const now = new Date().getTime();
|
|
251
|
+
|
|
252
|
+
body.responses.forEach((response) => {
|
|
253
|
+
if (response.responseCode === 200) {
|
|
254
|
+
const ttl = response.subscriptionTtl * 1000;
|
|
255
|
+
|
|
256
|
+
this.subscribers[response.subject] = now + ttl;
|
|
257
|
+
this.presences[response.status.subject] = now;
|
|
258
|
+
} else {
|
|
259
|
+
// If it errored for any reason, set the ttl so we clean it out eventually
|
|
260
|
+
this.subscribers[response.subject] = now + DEFAULT_SUBSCRIPTION_TTL;
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
this.cleanPresences();
|
|
267
|
+
}
|
|
268
|
+
}
|