@resolveio/server-lib 22.0.0 → 22.0.2
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/managers/subscription.manager.d.ts +7 -0
- package/managers/subscription.manager.js +169 -16
- package/managers/subscription.manager.js.map +1 -1
- package/managers/worker-dispatcher.manager.js +28 -0
- package/managers/worker-dispatcher.manager.js.map +1 -1
- package/package.json +1 -1
- package/server-app.js +17 -1
- package/server-app.js.map +1 -1
|
@@ -41,6 +41,9 @@ export declare class SubscriptionManager {
|
|
|
41
41
|
private _subSendLogThresholdMs;
|
|
42
42
|
private _subSendLogBytes;
|
|
43
43
|
private _subSendLogSampleRate;
|
|
44
|
+
private _aiWorkerDebug;
|
|
45
|
+
private _aiSubscriptionDebug;
|
|
46
|
+
private _aiSubLastAt;
|
|
44
47
|
private _oplogRetryCount;
|
|
45
48
|
private _lastResumeToken;
|
|
46
49
|
private _lastResumeTokenSaveMs;
|
|
@@ -106,11 +109,15 @@ export declare class SubscriptionManager {
|
|
|
106
109
|
private resolveSubSendLogThresholdMs;
|
|
107
110
|
private resolveSubSendLogBytes;
|
|
108
111
|
private resolveSubSendLogSampleRate;
|
|
112
|
+
private resolveAiSubscriptionDebug;
|
|
109
113
|
private parseDebugFlag;
|
|
110
114
|
private parsePositiveNumber;
|
|
111
115
|
private parseSampleRate;
|
|
112
116
|
private shouldLogSubSend;
|
|
113
117
|
private logSubSend;
|
|
118
|
+
private isAiPublication;
|
|
119
|
+
private logAiSubSend;
|
|
120
|
+
private logAiSubscriptionEvent;
|
|
114
121
|
private connectDebug;
|
|
115
122
|
private parsePositiveFloat;
|
|
116
123
|
private isChangeStreamUnsupported;
|
|
@@ -151,6 +151,9 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
151
151
|
this._subSendLogThresholdMs = 0;
|
|
152
152
|
this._subSendLogBytes = 0;
|
|
153
153
|
this._subSendLogSampleRate = 1;
|
|
154
|
+
this._aiWorkerDebug = false;
|
|
155
|
+
this._aiSubscriptionDebug = false;
|
|
156
|
+
this._aiSubLastAt = new Map();
|
|
154
157
|
this._oplogRetryCount = 0;
|
|
155
158
|
this._lastResumeToken = null;
|
|
156
159
|
this._lastResumeTokenSaveMs = 0;
|
|
@@ -237,6 +240,8 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
237
240
|
this._subSendLogThresholdMs = this.resolveSubSendLogThresholdMs();
|
|
238
241
|
this._subSendLogBytes = this.resolveSubSendLogBytes();
|
|
239
242
|
this._subSendLogSampleRate = this.resolveSubSendLogSampleRate();
|
|
243
|
+
this._aiWorkerDebug = this.parseDebugFlag(process.env.AI_ASSISTANT_WORKER_DEBUG);
|
|
244
|
+
this._aiSubscriptionDebug = this.resolveAiSubscriptionDebug();
|
|
240
245
|
this._oplogMode = this.resolveOplogMode();
|
|
241
246
|
this._localOplogResyncIntervalMs = this.resolveLocalOplogResyncIntervalMs();
|
|
242
247
|
this.registerCorePublications();
|
|
@@ -956,8 +961,9 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
956
961
|
return __awaiter(this, void 0, void 0, function () {
|
|
957
962
|
var pub, valObj, valKeys, rootKeys, i, staleRouteMessage, urlData, urlModule_1, urlNext, otherRouteSubs, normalizedSubscriptionData, subscriptionKey_1, sub;
|
|
958
963
|
var _this = this;
|
|
959
|
-
|
|
960
|
-
|
|
964
|
+
var _a;
|
|
965
|
+
return __generator(this, function (_b) {
|
|
966
|
+
switch (_b.label) {
|
|
961
967
|
case 0:
|
|
962
968
|
this._debugSubHits += 1;
|
|
963
969
|
this.connectDebug('Subscribe request', {
|
|
@@ -1083,6 +1089,15 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1083
1089
|
sub = this._subscriptions.find(function (a) { return a.publication === publication && a.subscriptionKey === subscriptionKey_1; });
|
|
1084
1090
|
}
|
|
1085
1091
|
this.ensureDependencyContainers(sub);
|
|
1092
|
+
this.logAiSubscriptionEvent('sub', {
|
|
1093
|
+
publication: publication,
|
|
1094
|
+
subscriptionKey: subscriptionKey_1,
|
|
1095
|
+
messageId: messageId,
|
|
1096
|
+
id_socket: ws ? ws['id_socket'] : null,
|
|
1097
|
+
messageRoute: messageRoute,
|
|
1098
|
+
clients: ((_a = sub === null || sub === void 0 ? void 0 : sub.clients) === null || _a === void 0 ? void 0 : _a.length) || 0,
|
|
1099
|
+
subscriptionData: normalizedSubscriptionData
|
|
1100
|
+
});
|
|
1086
1101
|
if (this._enableDebug) {
|
|
1087
1102
|
console.log(new Date(), 'New Sub', sub.publication, sub.running, sub.runAgain, sub.clients.length);
|
|
1088
1103
|
}
|
|
@@ -1090,8 +1105,8 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1090
1105
|
return [4 /*yield*/, this.processSubscription(sub, ws, messageId)];
|
|
1091
1106
|
case 2:
|
|
1092
1107
|
// Immediately send data to the new client
|
|
1093
|
-
|
|
1094
|
-
|
|
1108
|
+
_b.sent();
|
|
1109
|
+
_b.label = 3;
|
|
1095
1110
|
case 3: return [2 /*return*/];
|
|
1096
1111
|
}
|
|
1097
1112
|
});
|
|
@@ -1140,6 +1155,15 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1140
1155
|
sub.clients.splice(i, 1);
|
|
1141
1156
|
}
|
|
1142
1157
|
}
|
|
1158
|
+
this.logAiSubscriptionEvent('unsub', {
|
|
1159
|
+
publication: publication,
|
|
1160
|
+
subscriptionKey: subscriptionKey_2,
|
|
1161
|
+
messageId: messageId,
|
|
1162
|
+
id_socket: ws ? ws['id_socket'] : null,
|
|
1163
|
+
messageRoute: messageRoute,
|
|
1164
|
+
clients: sub.clients.length,
|
|
1165
|
+
subscriptionData: normalizedSubscriptionData
|
|
1166
|
+
});
|
|
1143
1167
|
if (this._enableDebug) {
|
|
1144
1168
|
console.log(new Date(), 'Unsub', sub.publication, sub.running, sub.runAgain, sub.clients.length);
|
|
1145
1169
|
}
|
|
@@ -1285,6 +1309,14 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1285
1309
|
|| config['SUBSCRIPTION_SEND_LOG_SAMPLE_RATE'];
|
|
1286
1310
|
return this.parseSampleRate(raw, this._subSendLogSampleRate);
|
|
1287
1311
|
};
|
|
1312
|
+
SubscriptionManager.prototype.resolveAiSubscriptionDebug = function () {
|
|
1313
|
+
var config = this.serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
|
|
1314
|
+
var raw = process.env.AI_ASSISTANT_SUB_DEBUG
|
|
1315
|
+
|| process.env.AI_TERMINAL_SUB_DEBUG
|
|
1316
|
+
|| config['AI_ASSISTANT_SUB_DEBUG']
|
|
1317
|
+
|| config['AI_TERMINAL_SUB_DEBUG'];
|
|
1318
|
+
return this.parseDebugFlag(raw);
|
|
1319
|
+
};
|
|
1288
1320
|
SubscriptionManager.prototype.parseDebugFlag = function (value) {
|
|
1289
1321
|
if (value === true) {
|
|
1290
1322
|
return true;
|
|
@@ -1355,6 +1387,55 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1355
1387
|
type: details.type
|
|
1356
1388
|
}));
|
|
1357
1389
|
};
|
|
1390
|
+
SubscriptionManager.prototype.isAiPublication = function (publication) {
|
|
1391
|
+
return publication === 'aiTerminalMessages' || publication === 'aiTerminalConversations';
|
|
1392
|
+
};
|
|
1393
|
+
SubscriptionManager.prototype.logAiSubSend = function (details) {
|
|
1394
|
+
var _a;
|
|
1395
|
+
if (!this._aiWorkerDebug) {
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
if (!this.isAiPublication(details.publication)) {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
console.log(new Date(), '[AI Worker Debug] subSend', JSON.stringify({
|
|
1402
|
+
publication: details.publication,
|
|
1403
|
+
subscriptionKey: details.subscriptionKey,
|
|
1404
|
+
messageId: details.messageId,
|
|
1405
|
+
id_socket: details.id_socket,
|
|
1406
|
+
clients: details.clients,
|
|
1407
|
+
payloadBytes: details.payloadBytes,
|
|
1408
|
+
packed: details.packed,
|
|
1409
|
+
cacheHit: (_a = details.cacheHit) !== null && _a !== void 0 ? _a : false,
|
|
1410
|
+
collection: details.collection,
|
|
1411
|
+
type: details.type,
|
|
1412
|
+
subscriptionData: details.subscriptionData
|
|
1413
|
+
}));
|
|
1414
|
+
};
|
|
1415
|
+
SubscriptionManager.prototype.logAiSubscriptionEvent = function (event, details) {
|
|
1416
|
+
if (!this._aiSubscriptionDebug) {
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
if (!this.isAiPublication(details.publication)) {
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
var wsId = details.id_socket || 'unknown';
|
|
1423
|
+
var key = "".concat(event, ":").concat(wsId, ":").concat(details.publication, ":").concat(details.subscriptionKey);
|
|
1424
|
+
var now = Date.now();
|
|
1425
|
+
var lastAt = this._aiSubLastAt.get(key);
|
|
1426
|
+
var deltaMs = lastAt ? now - lastAt : null;
|
|
1427
|
+
this._aiSubLastAt.set(key, now);
|
|
1428
|
+
console.log(new Date(), "[AI Sub Debug] ".concat(event), JSON.stringify({
|
|
1429
|
+
publication: details.publication,
|
|
1430
|
+
subscriptionKey: details.subscriptionKey,
|
|
1431
|
+
messageId: details.messageId,
|
|
1432
|
+
messageRoute: details.messageRoute,
|
|
1433
|
+
id_socket: wsId,
|
|
1434
|
+
clients: details.clients,
|
|
1435
|
+
deltaMs: deltaMs,
|
|
1436
|
+
subscriptionData: details.subscriptionData
|
|
1437
|
+
}));
|
|
1438
|
+
};
|
|
1358
1439
|
SubscriptionManager.prototype.connectDebug = function (message, details) {
|
|
1359
1440
|
if (!this._connectDebug) {
|
|
1360
1441
|
return;
|
|
@@ -2195,6 +2276,19 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2195
2276
|
console.log(new Date(), 'Process Sub, Cache (packed)', sub.publication);
|
|
2196
2277
|
}
|
|
2197
2278
|
this._websocketManager.sendPackedBuffer(ws, messageId, false, cachedBuffer, 'msgpack');
|
|
2279
|
+
this.logAiSubSend({
|
|
2280
|
+
publication: sub.publication,
|
|
2281
|
+
subscriptionKey: sub.subscriptionKey,
|
|
2282
|
+
messageId: messageId,
|
|
2283
|
+
id_socket: ws['id_socket'],
|
|
2284
|
+
clients: 1,
|
|
2285
|
+
payloadBytes: cachedBuffer.byteLength,
|
|
2286
|
+
packed: true,
|
|
2287
|
+
cacheHit: true,
|
|
2288
|
+
collection: '',
|
|
2289
|
+
type: 'cache',
|
|
2290
|
+
subscriptionData: sub.subscriptionData
|
|
2291
|
+
});
|
|
2198
2292
|
}
|
|
2199
2293
|
else {
|
|
2200
2294
|
cacheData = this.decodeCachePayload(cachedRaw);
|
|
@@ -2210,6 +2304,19 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2210
2304
|
console.log(new Date(), 'Process Sub, Cache', sub.publication);
|
|
2211
2305
|
}
|
|
2212
2306
|
this.sendWS(ws, serverRes);
|
|
2307
|
+
this.logAiSubSend({
|
|
2308
|
+
publication: sub.publication,
|
|
2309
|
+
subscriptionKey: sub.subscriptionKey,
|
|
2310
|
+
messageId: messageId,
|
|
2311
|
+
id_socket: ws['id_socket'],
|
|
2312
|
+
clients: 1,
|
|
2313
|
+
payloadBytes: cacheData ? Buffer.byteLength(JSON.stringify(cacheData)) : null,
|
|
2314
|
+
packed: false,
|
|
2315
|
+
cacheHit: true,
|
|
2316
|
+
collection: '',
|
|
2317
|
+
type: 'cache',
|
|
2318
|
+
subscriptionData: sub.subscriptionData
|
|
2319
|
+
});
|
|
2213
2320
|
}
|
|
2214
2321
|
return [3 /*break*/, 4];
|
|
2215
2322
|
case 2:
|
|
@@ -2251,25 +2358,27 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2251
2358
|
};
|
|
2252
2359
|
SubscriptionManager.prototype.sendDataToOne = function (ws, messageId, sub, collection, type) {
|
|
2253
2360
|
return __awaiter(this, void 0, void 0, function () {
|
|
2254
|
-
var monitor, dependencySnapshot, res, execution, serverRes, err_1, _a, normalizedError, correlationId, serverRes, errorPayload;
|
|
2255
|
-
var _b;
|
|
2256
|
-
return __generator(this, function (
|
|
2257
|
-
switch (
|
|
2361
|
+
var monitor, dependencySnapshot, res, execution, packedRes, payloadBytes, serverRes, err_1, _a, normalizedError, correlationId, serverRes, errorPayload;
|
|
2362
|
+
var _b, _c;
|
|
2363
|
+
return __generator(this, function (_d) {
|
|
2364
|
+
switch (_d.label) {
|
|
2258
2365
|
case 0:
|
|
2259
2366
|
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
2260
2367
|
return [2 /*return*/];
|
|
2261
2368
|
}
|
|
2262
2369
|
monitor = this._monitorManagerFunction.startMonitorFunction('User Specific Publication', sub.publication, '', '', sub.subscriptionData);
|
|
2263
|
-
|
|
2370
|
+
_d.label = 1;
|
|
2264
2371
|
case 1:
|
|
2265
|
-
|
|
2372
|
+
_d.trys.push([1, 3, 5, 7]);
|
|
2266
2373
|
resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager().callMethod.call(resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager(), 'insertSubscriptionLog', type, sub.publication, collection, JSON.stringify(sub.subscriptionData));
|
|
2267
2374
|
return [4 /*yield*/, this.runPublicationExecution(sub, ws['id_user'])];
|
|
2268
2375
|
case 2:
|
|
2269
|
-
execution =
|
|
2376
|
+
execution = _d.sent();
|
|
2270
2377
|
res = execution.result;
|
|
2271
2378
|
dependencySnapshot = execution.snapshot;
|
|
2272
2379
|
this.updateSubscriptionDependencies(sub, dependencySnapshot);
|
|
2380
|
+
packedRes = (_b = execution.packedResult) !== null && _b !== void 0 ? _b : this.packCachePayload(res);
|
|
2381
|
+
payloadBytes = packedRes ? packedRes.byteLength : null;
|
|
2273
2382
|
if (execution.packedResult) {
|
|
2274
2383
|
this._websocketManager.sendPackedBuffer(ws, messageId, false, execution.packedResult, execution.encoding || 'msgpack', { passThrough: !!execution.workerUsed });
|
|
2275
2384
|
}
|
|
@@ -2281,9 +2390,22 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2281
2390
|
};
|
|
2282
2391
|
this.sendWS(ws, serverRes);
|
|
2283
2392
|
}
|
|
2393
|
+
this.logAiSubSend({
|
|
2394
|
+
publication: sub.publication,
|
|
2395
|
+
subscriptionKey: sub.subscriptionKey,
|
|
2396
|
+
messageId: messageId,
|
|
2397
|
+
id_socket: ws['id_socket'],
|
|
2398
|
+
clients: 1,
|
|
2399
|
+
payloadBytes: payloadBytes,
|
|
2400
|
+
packed: !!execution.packedResult,
|
|
2401
|
+
cacheHit: false,
|
|
2402
|
+
collection: collection,
|
|
2403
|
+
type: type,
|
|
2404
|
+
subscriptionData: sub.subscriptionData
|
|
2405
|
+
});
|
|
2284
2406
|
return [3 /*break*/, 7];
|
|
2285
2407
|
case 3:
|
|
2286
|
-
err_1 =
|
|
2408
|
+
err_1 = _d.sent();
|
|
2287
2409
|
_a = (0, error_tracking_1.ensureErrorWithCorrelation)(err_1), normalizedError = _a.error, correlationId = _a.correlationId;
|
|
2288
2410
|
serverRes = {
|
|
2289
2411
|
messageId: messageId,
|
|
@@ -2309,7 +2431,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2309
2431
|
return [4 /*yield*/, error_reporter_1.ErrorReporter.report({
|
|
2310
2432
|
sourceApp: 'subscription-manager',
|
|
2311
2433
|
message: 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
|
|
2312
|
-
environment: (
|
|
2434
|
+
environment: (_c = this.serverConfig) === null || _c === void 0 ? void 0 : _c.ROOT_URL,
|
|
2313
2435
|
clientSlug: resolveio_server_app_1.ResolveIOServer.getClientName(),
|
|
2314
2436
|
clientName: this.serverConfig['CLIENT_NAME'],
|
|
2315
2437
|
stack: normalizedError === null || normalizedError === void 0 ? void 0 : normalizedError.stack,
|
|
@@ -2322,11 +2444,11 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2322
2444
|
correlationId: correlationId
|
|
2323
2445
|
})];
|
|
2324
2446
|
case 4:
|
|
2325
|
-
|
|
2447
|
+
_d.sent();
|
|
2326
2448
|
return [3 /*break*/, 7];
|
|
2327
2449
|
case 5: return [4 /*yield*/, this._monitorManagerFunction.finishMonitorFunction(monitor)];
|
|
2328
2450
|
case 6:
|
|
2329
|
-
|
|
2451
|
+
_d.sent();
|
|
2330
2452
|
return [7 /*endfinally*/];
|
|
2331
2453
|
case 7: return [2 /*return*/];
|
|
2332
2454
|
}
|
|
@@ -2336,7 +2458,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2336
2458
|
// Fetch pub once, send to all clients linked to this pub
|
|
2337
2459
|
SubscriptionManager.prototype.sendDataToAll = function (sub, collection, type) {
|
|
2338
2460
|
return __awaiter(this, void 0, void 0, function () {
|
|
2339
|
-
var activeClients, _a, _b, client, ws, subIndex, monitor, res, dependencySnapshot, execution, packedRes, passThrough, payloadBytes, shouldCache, cachedBuffer, isSame, sendStartMs, sentClients, activeClients_1, activeClients_1_1, entry, client, ws, serverRes, sendStartMs, sentClients, activeClients_2, activeClients_2_1, entry, client, ws, serverRes, nodeCacheSize, deleteCount, subArr, zz, err_2, _c, normalizedError, correlationId, _d, _e, client, ws, serverRes, errorPayload;
|
|
2461
|
+
var activeClients, _a, _b, client, ws, subIndex, monitor, res, dependencySnapshot, execution, packedRes, passThrough, payloadBytes, shouldCache, isAiPublication, cachedBuffer, isSame, sendStartMs, sentClients, activeClients_1, activeClients_1_1, entry, client, ws, serverRes, sendStartMs, sentClients, activeClients_2, activeClients_2_1, entry, client, ws, serverRes, nodeCacheSize, deleteCount, subArr, zz, err_2, _c, normalizedError, correlationId, _d, _e, client, ws, serverRes, errorPayload;
|
|
2340
2462
|
var e_6, _f, e_7, _g, e_8, _h, e_9, _j;
|
|
2341
2463
|
var _k, _l;
|
|
2342
2464
|
return __generator(this, function (_m) {
|
|
@@ -2394,6 +2516,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2394
2516
|
passThrough = !!execution.workerUsed;
|
|
2395
2517
|
payloadBytes = packedRes ? packedRes.byteLength : null;
|
|
2396
2518
|
shouldCache = this.shouldCachePayload(sub, packedRes);
|
|
2519
|
+
isAiPublication = this.isAiPublication(sub.publication);
|
|
2397
2520
|
if (sub.cacheId) {
|
|
2398
2521
|
cachedBuffer = this.getCacheBuffer(this._nodeCache.get(sub.cacheId));
|
|
2399
2522
|
isSame = this.buffersEqual(cachedBuffer, packedRes);
|
|
@@ -2415,6 +2538,21 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2415
2538
|
};
|
|
2416
2539
|
this.sendWS(ws, serverRes);
|
|
2417
2540
|
}
|
|
2541
|
+
if (isAiPublication) {
|
|
2542
|
+
this.logAiSubSend({
|
|
2543
|
+
publication: sub.publication,
|
|
2544
|
+
subscriptionKey: sub.subscriptionKey,
|
|
2545
|
+
messageId: client.messageId,
|
|
2546
|
+
id_socket: ws['id_socket'],
|
|
2547
|
+
clients: activeClients.length,
|
|
2548
|
+
payloadBytes: payloadBytes,
|
|
2549
|
+
packed: !!packedRes,
|
|
2550
|
+
cacheHit: false,
|
|
2551
|
+
collection: collection,
|
|
2552
|
+
type: type,
|
|
2553
|
+
subscriptionData: sub.subscriptionData
|
|
2554
|
+
});
|
|
2555
|
+
}
|
|
2418
2556
|
sentClients += 1;
|
|
2419
2557
|
}
|
|
2420
2558
|
}
|
|
@@ -2466,6 +2604,21 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2466
2604
|
};
|
|
2467
2605
|
this.sendWS(ws, serverRes);
|
|
2468
2606
|
}
|
|
2607
|
+
if (isAiPublication) {
|
|
2608
|
+
this.logAiSubSend({
|
|
2609
|
+
publication: sub.publication,
|
|
2610
|
+
subscriptionKey: sub.subscriptionKey,
|
|
2611
|
+
messageId: client.messageId,
|
|
2612
|
+
id_socket: ws['id_socket'],
|
|
2613
|
+
clients: activeClients.length,
|
|
2614
|
+
payloadBytes: payloadBytes,
|
|
2615
|
+
packed: !!packedRes,
|
|
2616
|
+
cacheHit: false,
|
|
2617
|
+
collection: collection,
|
|
2618
|
+
type: type,
|
|
2619
|
+
subscriptionData: sub.subscriptionData
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2469
2622
|
sentClients += 1;
|
|
2470
2623
|
}
|
|
2471
2624
|
}
|