@resolveio/server-lib 9.8.12 → 9.9.0

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.
@@ -19,7 +19,7 @@ export declare class SubscriptionManager {
19
19
  private _heapLimit;
20
20
  constructor(mainServer: any, wss: WebSocket.Server, serverConfig: any);
21
21
  private addToQueue;
22
- invalidatePubsCache(collection: any, type: any, addToQueue?: boolean): void;
22
+ invalidatePubsCache(collection: any, type: any): void;
23
23
  publications(method: SubscriptionModel): void;
24
24
  loggedInLatency(ws: WebSocket): Promise<void>;
25
25
  subscribe(messageDate: Date, ws: WebSocket, messageId: number, publication: string, ...subscriptionData: any[]): void;
@@ -28,7 +28,7 @@ export declare class SubscriptionManager {
28
28
  unsubscribeAll(ws: WebSocket): Promise<void>;
29
29
  private getPublicationCollections;
30
30
  private tailOpLog;
31
- private sendPubDataOnce;
32
- private sendPubData;
31
+ private sendDataToOne;
32
+ private sendDataToAll;
33
33
  private sendWS;
34
34
  }
@@ -128,7 +128,7 @@ var SubscriptionManager = /** @class */ (function () {
128
128
  report_builder_dashboard_builders_1.loadReportBuilderDashboardBuilderPublications(this);
129
129
  this.tailOpLog();
130
130
  setInterval(function () { return __awaiter(_this, void 0, void 0, function () {
131
- var _loop_1, this_1, i, queueArr, i, mongoQueue, j, client, ws;
131
+ var _loop_1, this_1, i, queueArr, _loop_2, this_2, i;
132
132
  var _this = this;
133
133
  return __generator(this, function (_a) {
134
134
  if (!this._runningQueue) {
@@ -168,33 +168,58 @@ var SubscriptionManager = /** @class */ (function () {
168
168
  // result: 'Done'
169
169
  // });
170
170
  }
171
- queueArr = this._mongoQueue.filter(function (a) { return !a.running; });
171
+ queueArr = this._mongoQueue.filter(function (a) { return !a.running && (!a.subscription.next_run || a.subscription.next_run.getTime() <= Date.now()); });
172
172
  if (queueArr.length) {
173
173
  queueArr.forEach(function (entry) {
174
174
  entry.running = true;
175
175
  });
176
- // let startDate = new Date();
177
- for (i = queueArr.length - 1; i >= 0; i--) {
178
- mongoQueue = queueArr[i];
179
- if (this._publications[mongoQueue.subscription.publication].ws_specific) {
180
- for (j = 0; j < mongoQueue.subscription.clients.length; j++) {
181
- client = mongoQueue.subscription.clients[j];
182
- ws = this._mainServer.getWS(client.id_socket);
176
+ _loop_2 = function (i) {
177
+ var mongoQueue = queueArr[i];
178
+ if (this_2._publications[mongoQueue.subscription.publication].ws_specific) {
179
+ for (var j = 0; j < mongoQueue.subscription.clients.length; j++) {
180
+ var client = mongoQueue.subscription.clients[j];
181
+ var ws = this_2._mainServer.getWS(client.id_socket);
183
182
  if (ws && ws['id_socket'] === client.id_socket) {
184
- this.sendPubDataOnce(ws, client.messageId, mongoQueue.subscription, mongoQueue.type, mongoQueue.collection);
183
+ this_2.sendDataToOne(ws, client.messageId, mongoQueue.subscription, mongoQueue.type, mongoQueue.collection).then(function () {
184
+ if (mongoQueue.run_again) {
185
+ mongoQueue.running = false;
186
+ mongoQueue.run_again = false;
187
+ }
188
+ else {
189
+ if (_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id) >= 0) {
190
+ _this._mongoQueue.splice(_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id), 1);
191
+ }
192
+ }
193
+ }, function () {
194
+ if (_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id) >= 0) {
195
+ _this._mongoQueue.splice(_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id), 1);
196
+ }
197
+ });
185
198
  }
186
199
  }
187
200
  }
188
201
  else {
189
- this.sendPubData(mongoQueue.subscription, mongoQueue.type, mongoQueue.collection);
190
- }
191
- if (mongoQueue.run_again) {
192
- mongoQueue.running = false;
193
- mongoQueue.run_again = false;
194
- }
195
- else {
196
- this._mongoQueue.splice(this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id), 1);
202
+ this_2.sendDataToAll(mongoQueue).then(function () {
203
+ if (mongoQueue.run_again) {
204
+ mongoQueue.running = false;
205
+ mongoQueue.run_again = false;
206
+ }
207
+ else {
208
+ if (_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id) >= 0) {
209
+ _this._mongoQueue.splice(_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id), 1);
210
+ }
211
+ }
212
+ }, function () {
213
+ if (_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id) >= 0) {
214
+ _this._mongoQueue.splice(_this._mongoQueue.map(function (a) { return a._id; }).indexOf(mongoQueue._id), 1);
215
+ }
216
+ });
197
217
  }
218
+ };
219
+ this_2 = this;
220
+ // let startDate = new Date();
221
+ for (i = queueArr.length - 1; i >= 0; i--) {
222
+ _loop_2(i);
198
223
  }
199
224
  // let endDate = new Date();
200
225
  // this.currentPerfomanceMonitor.push({
@@ -214,7 +239,7 @@ var SubscriptionManager = /** @class */ (function () {
214
239
  });
215
240
  }); }, 1);
216
241
  setInterval(function () { return __awaiter(_this, void 0, void 0, function () {
217
- var _a, userCopy, _loop_2, this_2, i, i, sub, _loop_3, this_3, j;
242
+ var _a, userCopy, _loop_3, this_3, i, i, sub, _loop_4, this_4, j;
218
243
  return __generator(this, function (_b) {
219
244
  switch (_b.label) {
220
245
  case 0:
@@ -223,14 +248,14 @@ var SubscriptionManager = /** @class */ (function () {
223
248
  case 1:
224
249
  _a._loggedInUsers = _b.sent();
225
250
  userCopy = common_1.deepCopy(this._loggedInUsers);
226
- _loop_2 = function (i) {
251
+ _loop_3 = function (i) {
227
252
  var loggedInUser = userCopy[i];
228
253
  if (!loggedInUser.date || moment().diff(moment(loggedInUser.date), 'seconds') >= 30) {
229
- if (this_2._mainServer.getWS(loggedInUser.id_ws)) {
230
- this_2.unsubscribeAll(this_2._mainServer.getWS(loggedInUser.id_ws));
254
+ if (this_3._mainServer.getWS(loggedInUser.id_ws)) {
255
+ this_3.unsubscribeAll(this_3._mainServer.getWS(loggedInUser.id_ws));
231
256
  }
232
257
  else {
233
- this_2._subscriptions.forEach(function (sub) {
258
+ this_3._subscriptions.forEach(function (sub) {
234
259
  for (var j = sub.clients.length - 1; j >= 0; j--) {
235
260
  var client = sub.clients[j];
236
261
  if (client.id_socket === loggedInUser.id_ws) {
@@ -239,27 +264,27 @@ var SubscriptionManager = /** @class */ (function () {
239
264
  }
240
265
  });
241
266
  logged_in_users_collection_1.LoggedInUsers.deleteOne({ _id: loggedInUser._id });
242
- if (this_2._loggedInUsers.findIndex(function (a) { return a._id === loggedInUser._id; }) >= 0) {
243
- this_2._loggedInUsers.splice(this_2._loggedInUsers.findIndex(function (a) { return a._id === loggedInUser._id; }), 1);
267
+ if (this_3._loggedInUsers.findIndex(function (a) { return a._id === loggedInUser._id; }) >= 0) {
268
+ this_3._loggedInUsers.splice(this_3._loggedInUsers.findIndex(function (a) { return a._id === loggedInUser._id; }), 1);
244
269
  }
245
270
  }
246
271
  }
247
272
  };
248
- this_2 = this;
273
+ this_3 = this;
249
274
  for (i = this._loggedInUsers.length - 1; i >= 0; i--) {
250
- _loop_2(i);
275
+ _loop_3(i);
251
276
  }
252
277
  for (i = 0; i < this._subscriptions.length; i++) {
253
278
  sub = this._subscriptions[i];
254
- _loop_3 = function (j) {
279
+ _loop_4 = function (j) {
255
280
  var client = sub.clients[j];
256
- if (!this_3._loggedInUsers.some(function (a) { return a.id_ws === client.id_socket; })) {
281
+ if (!this_4._loggedInUsers.some(function (a) { return a.id_ws === client.id_socket; })) {
257
282
  sub.clients.splice(j, 1);
258
283
  }
259
284
  };
260
- this_3 = this;
285
+ this_4 = this;
261
286
  for (j = sub.clients.length - 1; j >= 0; j--) {
262
- _loop_3(j);
287
+ _loop_4(j);
263
288
  }
264
289
  }
265
290
  return [2 /*return*/];
@@ -319,27 +344,19 @@ var SubscriptionManager = /** @class */ (function () {
319
344
  // });
320
345
  }
321
346
  };
322
- SubscriptionManager.prototype.invalidatePubsCache = function (collection, type, addToQueue) {
323
- if (addToQueue === void 0) { addToQueue = true; }
347
+ SubscriptionManager.prototype.invalidatePubsCache = function (collection, type) {
324
348
  // let startDate = new Date();
325
- index_1.ResolveIOServer.getMongoManager().invalidateQueryCache(collection);
326
349
  var collSubs = this._subscriptions.filter(function (a) { return a.collections.includes(collection); });
327
350
  for (var i = collSubs.length - 1; i >= 0; i--) {
328
351
  var sub = collSubs[i];
329
- if (sub.cacheId) {
330
- this._nodeCache.del(sub.cacheId);
331
- sub.cacheId = 0;
332
- }
333
- if (addToQueue) {
334
- this.addToQueue({
335
- _id: 0,
336
- type: type,
337
- collection: collection,
338
- subscription: sub,
339
- running: false,
340
- run_again: false
341
- });
342
- }
352
+ this.addToQueue({
353
+ _id: 0,
354
+ type: type,
355
+ collection: collection,
356
+ subscription: sub,
357
+ running: false,
358
+ run_again: false
359
+ });
343
360
  }
344
361
  // let endDate = new Date();
345
362
  // this.currentPerfomanceMonitor.push({
@@ -442,7 +459,8 @@ var SubscriptionManager = /** @class */ (function () {
442
459
  messageId: messageId,
443
460
  id_socket: ws['id_socket']
444
461
  }],
445
- cacheId: 0
462
+ cacheId: 0,
463
+ next_run: null
446
464
  });
447
465
  if (publication === 'userWithId' && subscriptionData[0] !== ws['id_user']) {
448
466
  this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'], 'SENDING INCORRECT USER FOR USERWITHID - 5!! Sub : ' + JSON.stringify(this._subscriptions[this._subscriptions.length - 1], null, 2) + ', Socket User: ' + ws['id_user'] + ', All Subs: ' + JSON.stringify(this._subscriptions, null, 2));
@@ -474,7 +492,7 @@ var SubscriptionManager = /** @class */ (function () {
474
492
  // });
475
493
  }
476
494
  else if (sub_1.cacheId) {
477
- this.sendPubDataOnce(ws, messageId, sub_1, 'newSub', publication);
495
+ this.sendDataToOne(ws, messageId, sub_1, 'newSub', publication);
478
496
  // let endDate = new Date();
479
497
  // this.currentPerfomanceMonitor.push({
480
498
  // _id: this.idPerformance++,
@@ -711,7 +729,7 @@ var SubscriptionManager = /** @class */ (function () {
711
729
  });
712
730
  };
713
731
  // Fetch pub once, send to all clients linked to this pub
714
- SubscriptionManager.prototype.sendPubDataOnce = function (ws, messageId, subscription, type, collection) {
732
+ SubscriptionManager.prototype.sendDataToOne = function (ws, messageId, subscription, type, collection) {
715
733
  var _this = this;
716
734
  return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
717
735
  var cacheData, serverRes;
@@ -748,7 +766,7 @@ var SubscriptionManager = /** @class */ (function () {
748
766
  // let endDate = new Date();
749
767
  // this.currentPerfomanceMonitor.push({
750
768
  // _id: this.idPerformance++,
751
- // function: 'sendPubDataOnce',
769
+ // function: 'sendDataToOne',
752
770
  // publication: subscription.publication,
753
771
  // // subscriptionData: subscription.subscriptionData,
754
772
  // subscriptionData: [],
@@ -760,13 +778,13 @@ var SubscriptionManager = /** @class */ (function () {
760
778
  resolve(true);
761
779
  }
762
780
  else {
763
- this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'], 'Error Detected During SendPubDataOnce - No Cache! - ' + subscription.publication + '\n\nData \n' + JSON.stringify(subscription.subscriptionData, null, 2));
781
+ this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'], 'Error Detected During sendDataToOne - No Cache! - ' + subscription.publication + '\n\nData \n' + JSON.stringify(subscription.subscriptionData, null, 2));
764
782
  resolve(false);
765
783
  }
766
784
  }
767
785
  else { // Pub is different for each user (Look at users publication) [MUCH SLOWER, RE-RUNS FOR EACH USER]
768
786
  (_a = this._publications[subscription.publication].function).call.apply(_a, __spreadArrays([Object.assign({}, this, SubscriptionManager.prototype), ws['id_user']], subscription.subscriptionData)).catch(function (methodErrs) {
769
- _this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + _this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + subscription.publication + ' - (sendPubDataOnce - WS)\n\nData \n' + JSON.stringify(subscription.subscriptionData, null, 2) + '\n\nErrors\n' + JSON.stringify(methodErrs, null, 2));
787
+ _this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + _this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + subscription.publication + ' - (sendDataToOne - WS)\n\nData \n' + JSON.stringify(subscription.subscriptionData, null, 2) + '\n\nErrors\n' + JSON.stringify(methodErrs, null, 2));
770
788
  })
771
789
  .then(function (res) {
772
790
  var serverRes = {
@@ -782,7 +800,7 @@ var SubscriptionManager = /** @class */ (function () {
782
800
  // let endDate = new Date();
783
801
  // this.currentPerfomanceMonitor.push({
784
802
  // _id: this.idPerformance++,
785
- // function: 'sendPubDataOnce',
803
+ // function: 'sendDataToOne',
786
804
  // publication: subscription.publication,
787
805
  // // subscriptionData: subscription.subscriptionData,
788
806
  // subscriptionData: [],
@@ -808,33 +826,38 @@ var SubscriptionManager = /** @class */ (function () {
808
826
  }); });
809
827
  };
810
828
  // Fetch pub once, send to all clients linked to this pub
811
- SubscriptionManager.prototype.sendPubData = function (subscription, type, collection) {
829
+ SubscriptionManager.prototype.sendDataToAll = function (mongoQueue) {
812
830
  var _this = this;
813
831
  return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
814
832
  var _a;
815
833
  var _this = this;
816
834
  return __generator(this, function (_b) {
817
835
  // let startDate = new Date();
818
- if (!subscription.clients.length) {
819
- if (subscription.cacheId) {
820
- this._nodeCache.del(subscription.cacheId);
836
+ if (!mongoQueue.subscription.clients.length) {
837
+ if (mongoQueue.subscription.cacheId) {
838
+ this._nodeCache.del(mongoQueue.subscription.cacheId);
839
+ }
840
+ if (this._subscriptions.findIndex(function (a) { return a.publication === mongoQueue.subscription.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(mongoQueue.subscription.subscriptionData); }) >= 0) {
841
+ this._subscriptions.splice(this._subscriptions.findIndex(function (a) { return a.publication === mongoQueue.subscription.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(mongoQueue.subscription.subscriptionData); }), 1);
821
842
  }
822
- this._subscriptions.splice(this._subscriptions.findIndex(function (a) { return a.publication === subscription.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscription.subscriptionData); }), 1);
823
843
  resolve(false);
824
844
  }
825
845
  else {
826
- if (subscription.publication !== 'superadminAPM' && subscription.publication !== 'loggedInUsers') {
827
- this._mainServer.getMethodManager().callMethodInternal.call(this._mainServer.getMethodManager(), 'insertSubscriptionLog', type, subscription.publication, collection, JSON.stringify(subscription.subscriptionData));
846
+ if (mongoQueue.subscription.publication !== 'superadminAPM' && mongoQueue.subscription.publication !== 'loggedInUsers') {
847
+ this._mainServer.getMethodManager().callMethodInternal.call(this._mainServer.getMethodManager(), 'insertSubscriptionLog', mongoQueue.type, mongoQueue.subscription.publication, mongoQueue.collection, JSON.stringify(mongoQueue.subscription.subscriptionData));
828
848
  }
829
- (_a = this._publications[subscription.publication].function).call.apply(_a, __spreadArrays([Object.assign({}, this, SubscriptionManager.prototype)], subscription.subscriptionData)).catch(function (methodErrs) {
830
- _this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + _this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + subscription.publication + ' - (sendPubData)\n\nData \n' + JSON.stringify(subscription.subscriptionData, null, 2) + '\n\nErrors\n' + JSON.stringify(methodErrs, null, 2));
849
+ (_a = this._publications[mongoQueue.subscription.publication].function).call.apply(_a, __spreadArrays([Object.assign({}, this, SubscriptionManager.prototype)], mongoQueue.subscription.subscriptionData)).catch(function (methodErrs) {
850
+ _this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + _this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + mongoQueue.subscription.publication + ' - (sendPubData)\n\nData \n' + JSON.stringify(mongoQueue.subscription.subscriptionData, null, 2) + '\n\nErrors\n' + JSON.stringify(methodErrs, null, 2));
831
851
  })
832
852
  .then(function (res) {
833
- if (!subscription.clients.length) {
834
- if (subscription.cacheId) {
835
- _this._nodeCache.del(subscription.cacheId);
853
+ mongoQueue.subscription.next_run = moment().add(1, 'second').toDate();
854
+ if (!mongoQueue.subscription.clients.length) {
855
+ if (mongoQueue.subscription.cacheId) {
856
+ _this._nodeCache.del(mongoQueue.subscription.cacheId);
857
+ }
858
+ if (_this._subscriptions.findIndex(function (a) { return a.publication === mongoQueue.subscription.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(mongoQueue.subscription.subscriptionData); }) >= 0) {
859
+ _this._subscriptions.splice(_this._subscriptions.findIndex(function (a) { return a.publication === mongoQueue.subscription.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(mongoQueue.subscription.subscriptionData); }), 1);
836
860
  }
837
- _this._subscriptions.splice(_this._subscriptions.findIndex(function (a) { return a.publication === subscription.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscription.subscriptionData); }), 1);
838
861
  // let endDate = new Date();
839
862
  // this.currentPerfomanceMonitor.push({
840
863
  // _id: this.idPerformance++,
@@ -850,8 +873,8 @@ var SubscriptionManager = /** @class */ (function () {
850
873
  resolve(false);
851
874
  }
852
875
  else {
853
- if (!subscription.cacheId || _this._nodeCache.get(subscription.cacheId) !== JSON.stringify(res)) {
854
- subscription.clients.forEach(function (client) {
876
+ if (!mongoQueue.subscription.cacheId || _this._nodeCache.get(mongoQueue.subscription.cacheId) !== JSON.stringify(res)) {
877
+ mongoQueue.subscription.clients.forEach(function (client) {
855
878
  var ws = _this._mainServer.getWS(client.id_socket);
856
879
  if (ws) {
857
880
  var serverRes = {
@@ -859,8 +882,8 @@ var SubscriptionManager = /** @class */ (function () {
859
882
  hasError: false,
860
883
  data: res
861
884
  };
862
- if (subscription.publication === 'userWithId' && client.id_user !== ws['id_user']) {
863
- _this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + _this.serverConfig['CLIENT_NAME'], 'SENDING INCORRECT USER FOR USERWITHID!! Client User: ' + client.id_user + ', Socket User: ' + ws['id_user'] + ', Sub: ' + JSON.stringify(subscription, null, 2) + ', All Subs: ' + JSON.stringify(_this._subscriptions, null, 2));
885
+ if (mongoQueue.subscription.publication === 'userWithId' && client.id_user !== ws['id_user']) {
886
+ _this._mainServer.getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + _this.serverConfig['CLIENT_NAME'], 'SENDING INCORRECT USER FOR USERWITHID!! Client User: ' + client.id_user + ', Socket User: ' + ws['id_user'] + ', Sub: ' + JSON.stringify(mongoQueue.subscription, null, 2) + ', All Subs: ' + JSON.stringify(_this._subscriptions, null, 2));
864
887
  }
865
888
  _this.sendWS(ws, serverRes);
866
889
  }
@@ -878,15 +901,15 @@ var SubscriptionManager = /** @class */ (function () {
878
901
  break;
879
902
  }
880
903
  }
881
- console.log('Sub Cache: ' + 'Too Big - ' + subscription.publication + ' - Deleted: ' + deleteCount + ' - ' + nodeCacheSize);
904
+ console.log('Sub Cache: ' + 'Too Big - ' + mongoQueue.subscription.publication + ' - Deleted: ' + deleteCount + ' - ' + nodeCacheSize);
882
905
  }
883
- if (subscription.cacheId) {
884
- _this._nodeCache.del(subscription.cacheId);
906
+ if (mongoQueue.subscription.cacheId) {
907
+ _this._nodeCache.del(mongoQueue.subscription.cacheId);
885
908
  }
886
909
  var cacheId = _this._cacheId;
887
910
  _this._cacheId += 1;
888
911
  _this._nodeCache.set(cacheId, JSON.stringify(res));
889
- subscription.cacheId = cacheId;
912
+ mongoQueue.subscription.cacheId = cacheId;
890
913
  // let endDate = new Date();
891
914
  // this.currentPerfomanceMonitor.push({
892
915
  // _id: this.idPerformance++,
@@ -903,7 +926,7 @@ var SubscriptionManager = /** @class */ (function () {
903
926
  resolve(true);
904
927
  }
905
928
  }, function (err) {
906
- subscription.clients.forEach(function (client) {
929
+ mongoQueue.subscription.clients.forEach(function (client) {
907
930
  var ws = _this._mainServer.getWS(client.id_socket);
908
931
  if (ws) {
909
932
  if (ws['id_socket'] === client.id_socket) {