@resolveio/server-lib 20.14.37 → 20.14.39

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.
@@ -20,12 +20,24 @@ export declare class WebSocketManager {
20
20
  private _wsSendLogThresholdMs;
21
21
  private _wsSendLogBytes;
22
22
  private _wsSendLogBufferedBytes;
23
+ private _sendQueues;
24
+ private _sendQueueTimers;
25
+ private _sendThrottleMs;
26
+ private _sendBackpressureBytes;
27
+ private _sendMaxBatchesPerTick;
23
28
  constructor();
24
29
  static create(mainServer: any, maxMessageSize?: number, messageDelay?: number, chunkThresholdBytes?: number, chunkSizeBytes?: number): WebSocketManager;
25
30
  initialize(mainServer: any, maxMessageSize?: number, messageDelay?: number, chunkThresholdBytes?: number, chunkSizeBytes?: number): void;
26
31
  private parseDebugFlag;
27
32
  private parseBoolean;
28
33
  private parsePositiveInt;
34
+ private isBackpressured;
35
+ private shouldQueueSend;
36
+ private getQueueDelayMs;
37
+ private enqueueSend;
38
+ private scheduleSendDrain;
39
+ private drainSendQueue;
40
+ private scheduleNextChunk;
29
41
  private shouldLogSend;
30
42
  private getBufferedAmount;
31
43
  private logWsSend;
@@ -42,6 +54,7 @@ export declare class WebSocketManager {
42
54
  private decodePackedPayload;
43
55
  private sendChunkSequence;
44
56
  private transmitBatch;
57
+ private transmitBatchNow;
45
58
  private generateChunkId;
46
59
  private toBase64;
47
60
  }
@@ -27,6 +27,11 @@ var WebSocketManager = /** @class */ (function () {
27
27
  this._wsSendLogThresholdMs = 2000;
28
28
  this._wsSendLogBytes = 2 * 1024 * 1024;
29
29
  this._wsSendLogBufferedBytes = 4 * 1024 * 1024;
30
+ this._sendQueues = new Map();
31
+ this._sendQueueTimers = new Map();
32
+ this._sendThrottleMs = 0;
33
+ this._sendBackpressureBytes = 0;
34
+ this._sendMaxBatchesPerTick = 10;
30
35
  }
31
36
  WebSocketManager.create = function (mainServer, maxMessageSize, messageDelay, chunkThresholdBytes, chunkSizeBytes) {
32
37
  if (maxMessageSize === void 0) { maxMessageSize = 20480; }
@@ -52,6 +57,9 @@ var WebSocketManager = /** @class */ (function () {
52
57
  this._wsSendLogThresholdMs = this.parsePositiveInt(process.env.WS_SEND_LOG_THRESHOLD_MS, this._wsSendLogThresholdMs);
53
58
  this._wsSendLogBytes = this.parsePositiveInt(process.env.WS_SEND_LOG_BYTES, this._wsSendLogBytes);
54
59
  this._wsSendLogBufferedBytes = this.parsePositiveInt(process.env.WS_SEND_LOG_BUFFERED_BYTES, this._wsSendLogBufferedBytes);
60
+ this._sendThrottleMs = this.parsePositiveInt(process.env.WS_SEND_THROTTLE_MS, this._sendThrottleMs);
61
+ this._sendBackpressureBytes = this.parsePositiveInt(process.env.WS_SEND_BACKPRESSURE_BYTES, this._sendBackpressureBytes);
62
+ this._sendMaxBatchesPerTick = this.parsePositiveInt(process.env.WS_SEND_MAX_BATCHES_PER_TICK, this._sendMaxBatchesPerTick);
55
63
  };
56
64
  WebSocketManager.prototype.parseDebugFlag = function (value) {
57
65
  if (value === true) {
@@ -82,6 +90,86 @@ var WebSocketManager = /** @class */ (function () {
82
90
  }
83
91
  return parsed;
84
92
  };
93
+ WebSocketManager.prototype.isBackpressured = function (ws) {
94
+ if (this._sendBackpressureBytes <= 0) {
95
+ return false;
96
+ }
97
+ var buffered = this.getBufferedAmount(ws);
98
+ return buffered !== null && buffered >= this._sendBackpressureBytes;
99
+ };
100
+ WebSocketManager.prototype.shouldQueueSend = function (ws) {
101
+ return this._sendThrottleMs > 0 || this.isBackpressured(ws);
102
+ };
103
+ WebSocketManager.prototype.getQueueDelayMs = function (ws) {
104
+ if (this._sendThrottleMs > 0) {
105
+ return this._sendThrottleMs;
106
+ }
107
+ if (this.isBackpressured(ws)) {
108
+ return 25;
109
+ }
110
+ return 0;
111
+ };
112
+ WebSocketManager.prototype.enqueueSend = function (ws, batch) {
113
+ if (!batch || !batch.length) {
114
+ return;
115
+ }
116
+ var wsId = ws['id_socket'];
117
+ var queue = this._sendQueues.get(wsId);
118
+ if (!queue) {
119
+ queue = [];
120
+ this._sendQueues.set(wsId, queue);
121
+ }
122
+ queue.push(batch);
123
+ this.scheduleSendDrain(ws);
124
+ };
125
+ WebSocketManager.prototype.scheduleSendDrain = function (ws) {
126
+ var _this = this;
127
+ var wsId = ws['id_socket'];
128
+ if (this._sendQueueTimers.has(wsId)) {
129
+ return;
130
+ }
131
+ var delay = this.getQueueDelayMs(ws);
132
+ var timer = setTimeout(function () {
133
+ _this._sendQueueTimers.delete(wsId);
134
+ _this.drainSendQueue(ws);
135
+ }, delay);
136
+ this._sendQueueTimers.set(wsId, timer);
137
+ };
138
+ WebSocketManager.prototype.drainSendQueue = function (ws) {
139
+ var wsId = ws['id_socket'];
140
+ var queue = this._sendQueues.get(wsId);
141
+ if (!queue || !queue.length) {
142
+ this._sendQueues.delete(wsId);
143
+ return;
144
+ }
145
+ var sent = 0;
146
+ while (queue.length > 0 && sent < this._sendMaxBatchesPerTick && !this.isBackpressured(ws)) {
147
+ var batch = queue.shift();
148
+ if (batch && batch.length) {
149
+ this.transmitBatchNow(ws, batch);
150
+ }
151
+ sent += 1;
152
+ }
153
+ if (queue.length > 0) {
154
+ this.scheduleSendDrain(ws);
155
+ }
156
+ else {
157
+ this._sendQueues.delete(wsId);
158
+ }
159
+ };
160
+ WebSocketManager.prototype.scheduleNextChunk = function (ws, next) {
161
+ var _a, _b;
162
+ var wsId = ws['id_socket'];
163
+ var queueSize = (_b = (_a = this._sendQueues.get(wsId)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
164
+ var baseDelay = this.getQueueDelayMs(ws);
165
+ var delay = queueSize >= this._sendMaxBatchesPerTick ? Math.max(baseDelay, 25) : baseDelay;
166
+ if (delay > 0) {
167
+ setTimeout(next, delay);
168
+ }
169
+ else {
170
+ setImmediate(next);
171
+ }
172
+ };
85
173
  WebSocketManager.prototype.shouldLogSend = function (durationMs, totalBytes, bufferedAmount) {
86
174
  if (this._wsSendDebug) {
87
175
  return true;
@@ -259,9 +347,9 @@ var WebSocketManager = /** @class */ (function () {
259
347
  _b)
260
348
  };
261
349
  _this.transmitBatch(ws, [chunkMessage]);
262
- setImmediate(function () { return sendChunk(index + 1); });
350
+ _this.scheduleNextChunk(ws, function () { return sendChunk(index + 1); });
263
351
  };
264
- setImmediate(function () { return sendChunk(0); });
352
+ this.scheduleNextChunk(ws, function () { return sendChunk(0); });
265
353
  };
266
354
  WebSocketManager.prototype.flushMessages = function (ws) {
267
355
  var wsId = ws['id_socket'];
@@ -335,6 +423,11 @@ var WebSocketManager = /** @class */ (function () {
335
423
  clearTimeout(this._batchingTimers.get(wsId));
336
424
  this._batchingTimers.delete(wsId);
337
425
  }
426
+ this._sendQueues.delete(wsId);
427
+ if (this._sendQueueTimers.has(wsId)) {
428
+ clearTimeout(this._sendQueueTimers.get(wsId));
429
+ this._sendQueueTimers.delete(wsId);
430
+ }
338
431
  process.nextTick(function () {
339
432
  if ([ws_1.WebSocket.OPEN, ws_1.WebSocket.CLOSING].includes(ws.readyState)) {
340
433
  // Socket still hangs, hard close
@@ -385,7 +478,8 @@ var WebSocketManager = /** @class */ (function () {
385
478
  }
386
479
  };
387
480
  WebSocketManager.prototype.sendChunkSequence = function (ws, original, chunkContext) {
388
- var _a, _b, _c;
481
+ var _a;
482
+ var _this = this;
389
483
  var chunkId = this.generateChunkId();
390
484
  var totalChunks = Math.ceil(chunkContext.buffer.byteLength / this._chunkSizeBytes);
391
485
  var startMessage = {
@@ -402,16 +496,33 @@ var WebSocketManager = /** @class */ (function () {
402
496
  _a)
403
497
  };
404
498
  this.transmitBatch(ws, [startMessage]);
405
- for (var index = 0; index < totalChunks; index++) {
406
- var start = index * this._chunkSizeBytes;
407
- var end = Math.min(chunkContext.buffer.byteLength, start + this._chunkSizeBytes);
499
+ var sendChunk = function (index) {
500
+ var _a, _b;
501
+ if (!ws || ws.readyState !== ws_1.WebSocket.OPEN) {
502
+ return;
503
+ }
504
+ if (index >= totalChunks) {
505
+ var endMessage = {
506
+ messageId: original.messageId,
507
+ hasError: original.hasError,
508
+ data: (_a = {},
509
+ _a[_this._chunkMetaFlag] = true,
510
+ _a.chunkId = chunkId,
511
+ _a.chunkStatus = 'end',
512
+ _a)
513
+ };
514
+ _this.transmitBatch(ws, [endMessage]);
515
+ return;
516
+ }
517
+ var start = index * _this._chunkSizeBytes;
518
+ var end = Math.min(chunkContext.buffer.byteLength, start + _this._chunkSizeBytes);
408
519
  var slice = chunkContext.buffer.subarray(start, end);
409
520
  var chunkPayload = slice;
410
521
  var chunkMessage = {
411
522
  messageId: original.messageId,
412
523
  hasError: original.hasError,
413
524
  data: (_b = {},
414
- _b[this._chunkMetaFlag] = true,
525
+ _b[_this._chunkMetaFlag] = true,
415
526
  _b.chunkId = chunkId,
416
527
  _b.chunkStatus = 'chunk',
417
528
  _b.chunkIndex = index,
@@ -419,20 +530,23 @@ var WebSocketManager = /** @class */ (function () {
419
530
  _b.encoding = chunkContext.encoding,
420
531
  _b)
421
532
  };
422
- this.transmitBatch(ws, [chunkMessage]);
423
- }
424
- var endMessage = {
425
- messageId: original.messageId,
426
- hasError: original.hasError,
427
- data: (_c = {},
428
- _c[this._chunkMetaFlag] = true,
429
- _c.chunkId = chunkId,
430
- _c.chunkStatus = 'end',
431
- _c)
533
+ _this.transmitBatch(ws, [chunkMessage]);
534
+ _this.scheduleNextChunk(ws, function () { return sendChunk(index + 1); });
432
535
  };
433
- this.transmitBatch(ws, [endMessage]);
536
+ this.scheduleNextChunk(ws, function () { return sendChunk(0); });
434
537
  };
435
538
  WebSocketManager.prototype.transmitBatch = function (ws, batch) {
539
+ if (!batch || !batch.length) {
540
+ return;
541
+ }
542
+ var wsId = ws['id_socket'];
543
+ if (this.shouldQueueSend(ws) || this._sendQueues.has(wsId)) {
544
+ this.enqueueSend(ws, batch);
545
+ return;
546
+ }
547
+ this.transmitBatchNow(ws, batch);
548
+ };
549
+ WebSocketManager.prototype.transmitBatchNow = function (ws, batch) {
436
550
  var _this = this;
437
551
  var _a;
438
552
  if (!batch || !batch.length) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/managers/websocket.manager.ts"],"names":[],"mappings":"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","file":"websocket.manager.js","sourcesContent":["import { randomBytes } from 'crypto';\nimport { pack, unpack } from 'msgpackr';\nimport { TextDecoder } from 'util';\nimport { WebSocket } from 'ws';\n\ninterface ServerResponseModel {\n\tmessageId: number;\n\thasError: boolean;\n\tdata: any;\n}\n\nexport class WebSocketManager {\n\tprivate _mainServer;\n\tprivate _messageBuffers: Map<string, ServerResponseModel[]> = new Map();\n\tprivate _batchingTimers: Map<string, NodeJS.Timeout> = new Map();\n\tprivate _maxMessageSize: number;\n\tprivate _messageDelay: number;\n\tprivate _webSockets: Map<string, WebSocket> = new Map();\n\tprivate _chunkThresholdBytes: number;\n\tprivate _chunkSizeBytes: number;\n\tprivate readonly _chunkMetaFlag = '__chunked';\n\tprivate _chunkingEnabled: boolean;\n\tprivate readonly _textDecoder = new TextDecoder();\n\tprivate _wsSendDebug = false;\n\tprivate _wsSendLogThresholdMs = 2000;\n\tprivate _wsSendLogBytes = 2 * 1024 * 1024;\n\tprivate _wsSendLogBufferedBytes = 4 * 1024 * 1024;\n\n\tconstructor() {}\n\t\n\tstatic create(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 512 * 1024, chunkSizeBytes: number = 1024 * 1024) {\n\t\tconst websocketManager = new WebSocketManager();\n\t\twebsocketManager.initialize(mainServer, maxMessageSize, messageDelay, chunkThresholdBytes, chunkSizeBytes);\n\t\treturn websocketManager;\n\t}\n\n\tpublic initialize(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 3 * 1024 * 1024, chunkSizeBytes: number = 4 * 1024 * 1024) {\n\t\tthis._mainServer = mainServer;\n\t\tthis._maxMessageSize = maxMessageSize;\n\t\tthis._messageDelay = messageDelay;\n\t\tthis._chunkingEnabled = this.parseBoolean(process.env.WS_CHUNKING_ENABLED, true);\n\t\tthis._chunkThresholdBytes = this.parsePositiveInt(process.env.WS_CHUNK_THRESHOLD_BYTES, chunkThresholdBytes);\n\t\tthis._chunkSizeBytes = this.parsePositiveInt(process.env.WS_CHUNK_SIZE_BYTES, chunkSizeBytes);\n\t\tthis._wsSendDebug = this.parseDebugFlag(process.env.WS_SEND_DEBUG);\n\t\tthis._wsSendLogThresholdMs = this.parsePositiveInt(process.env.WS_SEND_LOG_THRESHOLD_MS, this._wsSendLogThresholdMs);\n\t\tthis._wsSendLogBytes = this.parsePositiveInt(process.env.WS_SEND_LOG_BYTES, this._wsSendLogBytes);\n\t\tthis._wsSendLogBufferedBytes = this.parsePositiveInt(process.env.WS_SEND_LOG_BUFFERED_BYTES, this._wsSendLogBufferedBytes);\n\t}\n\n\tprivate parseDebugFlag(value: any): boolean {\n\t\tif (value === true) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (value === false || value === null || value === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (typeof value === 'number') {\n\t\t\treturn value === 1;\n\t\t}\n\n\t\tif (typeof value === 'string') {\n\t\t\tconst normalized = value.trim().toLowerCase();\n\t\t\treturn ['1', 'true', 'yes', 'y', 'on'].includes(normalized);\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate parseBoolean(value: any, fallback: boolean): boolean {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn fallback;\n\t\t}\n\n\t\treturn this.parseDebugFlag(value);\n\t}\n\n\tprivate parsePositiveInt(value: any, fallback: number): number {\n\t\tconst parsed = parseInt(value ?? '', 10);\n\t\tif (Number.isNaN(parsed) || parsed <= 0) {\n\t\t\treturn fallback;\n\t\t}\n\t\treturn parsed;\n\t}\n\n\tprivate shouldLogSend(durationMs: number | null, totalBytes: number | null, bufferedAmount: number | null): boolean {\n\t\tif (this._wsSendDebug) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (durationMs !== null && durationMs >= this._wsSendLogThresholdMs) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (totalBytes !== null && totalBytes >= this._wsSendLogBytes) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (bufferedAmount !== null && bufferedAmount >= this._wsSendLogBufferedBytes) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate getBufferedAmount(ws: WebSocket): number | null {\n\t\tif (!ws) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst buffered = (ws as any).bufferedAmount;\n\t\treturn typeof buffered === 'number' ? buffered : null;\n\t}\n\n\tprivate logWsSend(event: string, ws: WebSocket, details: Record<string, any>): void {\n\t\tif (!this._wsSendDebug) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst payload = Object.assign({\n\t\t\tts: new Date().toISOString(),\n\t\t\tevent,\n\t\t\tid_ws: ws ? ws['id_socket'] : null,\n\t\t\tuser: ws ? ws['user'] : null\n\t\t}, details);\n\n\t\tconsole.log(JSON.stringify(payload));\n\t}\n\n\tpublic addWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.set(wsId, ws);\n\t}\n\n\tpublic removeWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.delete(wsId);\n\t\tthis.closeConnection(ws);\n\t}\n\n\tpublic getWebSocket(id_socket: string): WebSocket | undefined {\n\t\treturn this._webSockets.get(id_socket);\n\t}\n\n\tpublic send(ws: WebSocket, data: ServerResponseModel | string): void {\n\t\tconst wsId = ws['id_socket'];\n\n\t\tif (!this._messageBuffers.has(wsId)) {\n\t\t\tthis._messageBuffers.set(wsId, []);\n\t\t}\n\n\t\tif (typeof data === 'string') {\n\t\t\tif (ws && ws.readyState === WebSocket.OPEN) {\n\t\t\t\tws.send(data, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\t// Handle string messages like 'ping' or 'pong'\n\t\t\tconst chunkContext = this.prepareChunkContext(data);\n\t\t\tif (chunkContext) {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t\tthis.sendChunkSequence(ws, data, chunkContext);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._messageBuffers.get(wsId).push(data);\n\t\t}\n\n\t\tif (!this._batchingTimers.has(wsId)) {\n\t\t\t// Set a timer to send the batch after a short delay\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t}, this._messageDelay);\n\t\t\tthis._batchingTimers.set(wsId, timer);\n\t\t}\n\t}\n\n\tpublic sendPackedBuffer(ws: WebSocket, messageId: number, hasError: boolean, packedData: Uint8Array | Buffer, encoding: 'msgpack' | 'json' = 'msgpack'): void {\n\t\tif (!ws || ws.readyState !== WebSocket.OPEN || !packedData || !packedData.byteLength) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst shouldChunk = this._chunkingEnabled && packedData.byteLength > this._chunkThresholdBytes;\n\t\tif (!shouldChunk) {\n\t\t\tconst decoded = this.decodePackedPayload(packedData, encoding);\n\t\t\tif (decoded !== undefined) {\n\t\t\t\tthis.send(ws, { messageId, hasError, data: decoded });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!this._chunkingEnabled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst sendStartMs = Date.now();\n\t\tconst bufferedStart = this.getBufferedAmount(ws);\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.max(1, Math.ceil(packedData.byteLength / this._chunkSizeBytes));\n\t\tconst chunkSize = this._chunkSizeBytes;\n\n\t\tif (this.shouldLogSend(null, packedData.byteLength, bufferedStart)) {\n\t\t\tthis.logWsSend('wsSendStart', ws, {\n\t\t\t\tmessageId,\n\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\ttotalChunks,\n\t\t\t\tchunkSize,\n\t\t\t\tencoding,\n\t\t\t\tbufferedAmount: bufferedStart\n\t\t\t});\n\t\t}\n\n\t\t// Flush any buffered messages so the chunk stream starts immediately.\n\t\tthis.flushMessages(ws);\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: messageId,\n\t\t\thasError: hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\tchunkSize: chunkSize,\n\t\t\t\tencoding: encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage]);\n\n\t\tconst sendChunk = (index: number) => {\n\t\t\tif (!ws || ws.readyState !== WebSocket.OPEN) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= totalChunks) {\n\t\t\t\tconst endMessage: ServerResponseModel = {\n\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\thasError: hasError,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\t\tchunkStatus: 'end'\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.transmitBatch(ws, [endMessage]);\n\t\t\t\tconst durationMs = Date.now() - sendStartMs;\n\t\t\t\tconst bufferedEnd = this.getBufferedAmount(ws);\n\t\t\t\tif (this.shouldLogSend(durationMs, packedData.byteLength, bufferedEnd)) {\n\t\t\t\t\tthis.logWsSend('wsSendEnd', ws, {\n\t\t\t\t\t\tmessageId,\n\t\t\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\t\t\ttotalChunks,\n\t\t\t\t\t\tchunkSize,\n\t\t\t\t\t\tencoding,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\tbufferedAmount: bufferedEnd\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst start = index * chunkSize;\n\t\t\tconst end = Math.min(packedData.byteLength, start + chunkSize);\n\t\t\tconst slice = packedData.subarray(start, end);\n\t\t\tconst payload = encoding === 'msgpack' ? slice : this.toBase64(slice);\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: payload,\n\t\t\t\t\tencoding: encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage]);\n\n\t\t\tsetImmediate(() => sendChunk(index + 1));\n\t\t};\n\n\t\tsetImmediate(() => sendChunk(0));\n\t}\n\n\tprivate flushMessages(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tconst messages = this._messageBuffers.get(wsId);\n\n\t\tif (messages && messages.length > 0) {\n\t\t\t// Combine messages into one payload\n\t\t\tthis.transmitBatch(ws, messages);\n\n\t\t\tthis._messageBuffers.delete(wsId);\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n\t}\n\n\tprivate sendMessagesInChunksBinary(ws: WebSocket, messages: ServerResponseModel[]): void {\n\t\tlet chunk: ServerResponseModel[] = [];\n\t\tlet chunkSize = 0;\n\n\t\tfor (const message of messages) {\n\t\t\tconst packedMessage = Buffer.from(<any>pack([message]));\n\t\t\tconst messageSize = packedMessage.byteLength;\n\n\t\t\tif (chunkSize + messageSize > this._maxMessageSize) {\n\t\t\t\tconst packedChunk = Buffer.from(<any>pack(chunk));\n\t\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tchunk = [message];\n\t\t\t\tchunkSize = messageSize;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tchunk.push(message);\n\t\t\t\tchunkSize += messageSize;\n\t\t\t}\n\t\t}\n\n\t\tif (chunk.length > 0) {\n\t\t\tconst packedChunk = Buffer.from(<any>pack(chunk));\n\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleSendError(ws: WebSocket, error: Error): void {\n\t\tif (this._mainServer.getSubscriptionManager()) {\n\t\t\t// Handle send error, e.g., unsubscribe, close connection\n\t\t\tif (this._mainServer.getSubscriptionManager().getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Unsub WS', ws['user'], ws['id_socket'], error);\n\t\t\t}\n\t\t\tthis._mainServer.getSubscriptionManager().unsubscribeAll(ws);\n\t\t\tthis.removeWebSocket(ws);\n\t\t}\n\t}\n\n\tpublic closeConnection(ws: WebSocket): void {\n\t\tws.close();\n\t\tconst wsId = ws['id_socket'];\n\t\t// Clean up buffers and timers\n\t\tthis._messageBuffers.delete(wsId);\n\t\tif (this._batchingTimers.has(wsId)) {\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n \n process.nextTick(() => {\n if ([WebSocket.OPEN, WebSocket.CLOSING].includes(<any>ws.readyState)) {\n // Socket still hangs, hard close\n ws.terminate();\n }\n });\n\t}\n\n\tprivate prepareChunkContext(message: ServerResponseModel): { buffer: Buffer, encoding: 'msgpack' | 'json' } | null {\n\t\tif (!this._chunkingEnabled) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (!message || message.hasError) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = message.data;\n\t\tif (data === undefined || data === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\tconst packed = Buffer.from(<any>pack(data));\n\t\t\tif (packed.byteLength > this._chunkThresholdBytes) {\n\t\t\t\treturn { buffer: packed, encoding: 'msgpack' };\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\tif (this._mainServer.getSubscriptionManager()?.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Chunking pack failed', err?.message || err);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate decodePackedPayload(packedData: Uint8Array | Buffer, encoding: 'msgpack' | 'json'): any | undefined {\n\t\ttry {\n\t\t\tconst source = packedData as Uint8Array;\n\t\t\tif (encoding === 'msgpack') {\n\t\t\t\treturn unpack(source);\n\t\t\t}\n\n\t\t\tconst text = this._textDecoder.decode(source);\n\t\t\treturn JSON.parse(text);\n\t\t}\n\t\tcatch (err) {\n\t\t\tif (this._mainServer.getSubscriptionManager()?.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Packed decode failed', err?.message || err);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate sendChunkSequence(ws: WebSocket, original: ServerResponseModel, chunkContext: { buffer: Buffer, encoding: 'msgpack' | 'json' }): void {\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.ceil(chunkContext.buffer.byteLength / this._chunkSizeBytes);\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: original.messageId,\n\t\t\thasError: original.hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: chunkContext.buffer.byteLength,\n\t\t\t\tchunkSize: this._chunkSizeBytes,\n\t\t\t\tencoding: chunkContext.encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage]);\n\n\t\tfor (let index = 0; index < totalChunks; index++) {\n\t\t\tconst start = index * this._chunkSizeBytes;\n\t\t\tconst end = Math.min(chunkContext.buffer.byteLength, start + this._chunkSizeBytes);\n\t\t\tconst slice = chunkContext.buffer.subarray(start, end);\n\t\t\tconst chunkPayload = slice;\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: original.messageId,\n\t\t\t\thasError: original.hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: chunkPayload,\n\t\t\t\t\tencoding: chunkContext.encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage]);\n\t\t}\n\n\t\tconst endMessage: ServerResponseModel = {\n\t\t\tmessageId: original.messageId,\n\t\t\thasError: original.hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'end'\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [endMessage]);\n\t}\n\n\tprivate transmitBatch(ws: WebSocket, batch: ServerResponseModel[]): void {\n\t\tif (!batch || !batch.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isChunkEnvelope = batch.length === 1 && batch[0]?.data && typeof batch[0].data === 'object' && batch[0].data[this._chunkMetaFlag];\n\n\t\tconst packedData = Buffer.from(<any>pack(batch));\n\t\tconst dataSize = packedData.byteLength;\n\t\tconst bufferedAmount = this.getBufferedAmount(ws);\n\n\t\tif (!isChunkEnvelope && dataSize > this._maxMessageSize) {\n\t\t\tthis.sendMessagesInChunksBinary(ws, batch);\n\t\t}\n\t\telse {\n\t\t\tws.send(packedData, (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (this.shouldLogSend(null, dataSize, bufferedAmount)) {\n\t\t\tthis.logWsSend('wsBatchSend', ws, {\n\t\t\t\tbatchSize: batch.length,\n\t\t\t\tdataSize,\n\t\t\t\tisChunkEnvelope,\n\t\t\t\tbufferedAmount\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate generateChunkId(): string {\n\t\treturn randomBytes(8).toString('hex');\n\t}\n\n\tprivate toBase64(data: Uint8Array | Buffer): string {\n\t\tif (Buffer.isBuffer(data)) {\n\t\t\treturn data.toString('base64');\n\t\t}\n\n\t\treturn Buffer.from(data).toString('base64');\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../../src/managers/websocket.manager.ts"],"names":[],"mappings":"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","file":"websocket.manager.js","sourcesContent":["import { randomBytes } from 'crypto';\nimport { pack, unpack } from 'msgpackr';\nimport { TextDecoder } from 'util';\nimport { WebSocket } from 'ws';\n\ninterface ServerResponseModel {\n\tmessageId: number;\n\thasError: boolean;\n\tdata: any;\n}\n\nexport class WebSocketManager {\n\tprivate _mainServer;\n\tprivate _messageBuffers: Map<string, ServerResponseModel[]> = new Map();\n\tprivate _batchingTimers: Map<string, NodeJS.Timeout> = new Map();\n\tprivate _maxMessageSize: number;\n\tprivate _messageDelay: number;\n\tprivate _webSockets: Map<string, WebSocket> = new Map();\n\tprivate _chunkThresholdBytes: number;\n\tprivate _chunkSizeBytes: number;\n\tprivate readonly _chunkMetaFlag = '__chunked';\n\tprivate _chunkingEnabled: boolean;\n\tprivate readonly _textDecoder = new TextDecoder();\n\tprivate _wsSendDebug = false;\n\tprivate _wsSendLogThresholdMs = 2000;\n\tprivate _wsSendLogBytes = 2 * 1024 * 1024;\n\tprivate _wsSendLogBufferedBytes = 4 * 1024 * 1024;\n\tprivate _sendQueues: Map<string, ServerResponseModel[][]> = new Map();\n\tprivate _sendQueueTimers: Map<string, NodeJS.Timeout> = new Map();\n\tprivate _sendThrottleMs = 0;\n\tprivate _sendBackpressureBytes = 0;\n\tprivate _sendMaxBatchesPerTick = 10;\n\n\tconstructor() {}\n\t\n\tstatic create(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 512 * 1024, chunkSizeBytes: number = 1024 * 1024) {\n\t\tconst websocketManager = new WebSocketManager();\n\t\twebsocketManager.initialize(mainServer, maxMessageSize, messageDelay, chunkThresholdBytes, chunkSizeBytes);\n\t\treturn websocketManager;\n\t}\n\n\tpublic initialize(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 3 * 1024 * 1024, chunkSizeBytes: number = 4 * 1024 * 1024) {\n\t\tthis._mainServer = mainServer;\n\t\tthis._maxMessageSize = maxMessageSize;\n\t\tthis._messageDelay = messageDelay;\n\t\tthis._chunkingEnabled = this.parseBoolean(process.env.WS_CHUNKING_ENABLED, true);\n\t\tthis._chunkThresholdBytes = this.parsePositiveInt(process.env.WS_CHUNK_THRESHOLD_BYTES, chunkThresholdBytes);\n\t\tthis._chunkSizeBytes = this.parsePositiveInt(process.env.WS_CHUNK_SIZE_BYTES, chunkSizeBytes);\n\t\tthis._wsSendDebug = this.parseDebugFlag(process.env.WS_SEND_DEBUG);\n\t\tthis._wsSendLogThresholdMs = this.parsePositiveInt(process.env.WS_SEND_LOG_THRESHOLD_MS, this._wsSendLogThresholdMs);\n\t\tthis._wsSendLogBytes = this.parsePositiveInt(process.env.WS_SEND_LOG_BYTES, this._wsSendLogBytes);\n\t\tthis._wsSendLogBufferedBytes = this.parsePositiveInt(process.env.WS_SEND_LOG_BUFFERED_BYTES, this._wsSendLogBufferedBytes);\n\t\tthis._sendThrottleMs = this.parsePositiveInt(process.env.WS_SEND_THROTTLE_MS, this._sendThrottleMs);\n\t\tthis._sendBackpressureBytes = this.parsePositiveInt(process.env.WS_SEND_BACKPRESSURE_BYTES, this._sendBackpressureBytes);\n\t\tthis._sendMaxBatchesPerTick = this.parsePositiveInt(process.env.WS_SEND_MAX_BATCHES_PER_TICK, this._sendMaxBatchesPerTick);\n\t}\n\n\tprivate parseDebugFlag(value: any): boolean {\n\t\tif (value === true) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (value === false || value === null || value === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (typeof value === 'number') {\n\t\t\treturn value === 1;\n\t\t}\n\n\t\tif (typeof value === 'string') {\n\t\t\tconst normalized = value.trim().toLowerCase();\n\t\t\treturn ['1', 'true', 'yes', 'y', 'on'].includes(normalized);\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate parseBoolean(value: any, fallback: boolean): boolean {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn fallback;\n\t\t}\n\n\t\treturn this.parseDebugFlag(value);\n\t}\n\n\tprivate parsePositiveInt(value: any, fallback: number): number {\n\t\tconst parsed = parseInt(value ?? '', 10);\n\t\tif (Number.isNaN(parsed) || parsed <= 0) {\n\t\t\treturn fallback;\n\t\t}\n\t\treturn parsed;\n\t}\n\n\tprivate isBackpressured(ws: WebSocket): boolean {\n\t\tif (this._sendBackpressureBytes <= 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst buffered = this.getBufferedAmount(ws);\n\t\treturn buffered !== null && buffered >= this._sendBackpressureBytes;\n\t}\n\n\tprivate shouldQueueSend(ws: WebSocket): boolean {\n\t\treturn this._sendThrottleMs > 0 || this.isBackpressured(ws);\n\t}\n\n\tprivate getQueueDelayMs(ws: WebSocket): number {\n\t\tif (this._sendThrottleMs > 0) {\n\t\t\treturn this._sendThrottleMs;\n\t\t}\n\n\t\tif (this.isBackpressured(ws)) {\n\t\t\treturn 25;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\tprivate enqueueSend(ws: WebSocket, batch: ServerResponseModel[]): void {\n\t\tif (!batch || !batch.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst wsId = ws['id_socket'];\n\t\tlet queue = this._sendQueues.get(wsId);\n\t\tif (!queue) {\n\t\t\tqueue = [];\n\t\t\tthis._sendQueues.set(wsId, queue);\n\t\t}\n\n\t\tqueue.push(batch);\n\t\tthis.scheduleSendDrain(ws);\n\t}\n\n\tprivate scheduleSendDrain(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tif (this._sendQueueTimers.has(wsId)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst delay = this.getQueueDelayMs(ws);\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis._sendQueueTimers.delete(wsId);\n\t\t\tthis.drainSendQueue(ws);\n\t\t}, delay);\n\n\t\tthis._sendQueueTimers.set(wsId, timer);\n\t}\n\n\tprivate drainSendQueue(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tconst queue = this._sendQueues.get(wsId);\n\t\tif (!queue || !queue.length) {\n\t\t\tthis._sendQueues.delete(wsId);\n\t\t\treturn;\n\t\t}\n\n\t\tlet sent = 0;\n\t\twhile (queue.length > 0 && sent < this._sendMaxBatchesPerTick && !this.isBackpressured(ws)) {\n\t\t\tconst batch = queue.shift();\n\t\t\tif (batch && batch.length) {\n\t\t\t\tthis.transmitBatchNow(ws, batch);\n\t\t\t}\n\t\t\tsent += 1;\n\t\t}\n\n\t\tif (queue.length > 0) {\n\t\t\tthis.scheduleSendDrain(ws);\n\t\t}\n\t\telse {\n\t\t\tthis._sendQueues.delete(wsId);\n\t\t}\n\t}\n\n\tprivate scheduleNextChunk(ws: WebSocket, next: () => void): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tconst queueSize = this._sendQueues.get(wsId)?.length ?? 0;\n\t\tconst baseDelay = this.getQueueDelayMs(ws);\n\t\tconst delay = queueSize >= this._sendMaxBatchesPerTick ? Math.max(baseDelay, 25) : baseDelay;\n\t\tif (delay > 0) {\n\t\t\tsetTimeout(next, delay);\n\t\t}\n\t\telse {\n\t\t\tsetImmediate(next);\n\t\t}\n\t}\n\n\tprivate shouldLogSend(durationMs: number | null, totalBytes: number | null, bufferedAmount: number | null): boolean {\n\t\tif (this._wsSendDebug) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (durationMs !== null && durationMs >= this._wsSendLogThresholdMs) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (totalBytes !== null && totalBytes >= this._wsSendLogBytes) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (bufferedAmount !== null && bufferedAmount >= this._wsSendLogBufferedBytes) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate getBufferedAmount(ws: WebSocket): number | null {\n\t\tif (!ws) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst buffered = (ws as any).bufferedAmount;\n\t\treturn typeof buffered === 'number' ? buffered : null;\n\t}\n\n\tprivate logWsSend(event: string, ws: WebSocket, details: Record<string, any>): void {\n\t\tif (!this._wsSendDebug) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst payload = Object.assign({\n\t\t\tts: new Date().toISOString(),\n\t\t\tevent,\n\t\t\tid_ws: ws ? ws['id_socket'] : null,\n\t\t\tuser: ws ? ws['user'] : null\n\t\t}, details);\n\n\t\tconsole.log(JSON.stringify(payload));\n\t}\n\n\tpublic addWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.set(wsId, ws);\n\t}\n\n\tpublic removeWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.delete(wsId);\n\t\tthis.closeConnection(ws);\n\t}\n\n\tpublic getWebSocket(id_socket: string): WebSocket | undefined {\n\t\treturn this._webSockets.get(id_socket);\n\t}\n\n\tpublic send(ws: WebSocket, data: ServerResponseModel | string): void {\n\t\tconst wsId = ws['id_socket'];\n\n\t\tif (!this._messageBuffers.has(wsId)) {\n\t\t\tthis._messageBuffers.set(wsId, []);\n\t\t}\n\n\t\tif (typeof data === 'string') {\n\t\t\tif (ws && ws.readyState === WebSocket.OPEN) {\n\t\t\t\tws.send(data, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\t// Handle string messages like 'ping' or 'pong'\n\t\t\tconst chunkContext = this.prepareChunkContext(data);\n\t\t\tif (chunkContext) {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t\tthis.sendChunkSequence(ws, data, chunkContext);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._messageBuffers.get(wsId).push(data);\n\t\t}\n\n\t\tif (!this._batchingTimers.has(wsId)) {\n\t\t\t// Set a timer to send the batch after a short delay\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t}, this._messageDelay);\n\t\t\tthis._batchingTimers.set(wsId, timer);\n\t\t}\n\t}\n\n\tpublic sendPackedBuffer(ws: WebSocket, messageId: number, hasError: boolean, packedData: Uint8Array | Buffer, encoding: 'msgpack' | 'json' = 'msgpack'): void {\n\t\tif (!ws || ws.readyState !== WebSocket.OPEN || !packedData || !packedData.byteLength) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst shouldChunk = this._chunkingEnabled && packedData.byteLength > this._chunkThresholdBytes;\n\t\tif (!shouldChunk) {\n\t\t\tconst decoded = this.decodePackedPayload(packedData, encoding);\n\t\t\tif (decoded !== undefined) {\n\t\t\t\tthis.send(ws, { messageId, hasError, data: decoded });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!this._chunkingEnabled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst sendStartMs = Date.now();\n\t\tconst bufferedStart = this.getBufferedAmount(ws);\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.max(1, Math.ceil(packedData.byteLength / this._chunkSizeBytes));\n\t\tconst chunkSize = this._chunkSizeBytes;\n\n\t\tif (this.shouldLogSend(null, packedData.byteLength, bufferedStart)) {\n\t\t\tthis.logWsSend('wsSendStart', ws, {\n\t\t\t\tmessageId,\n\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\ttotalChunks,\n\t\t\t\tchunkSize,\n\t\t\t\tencoding,\n\t\t\t\tbufferedAmount: bufferedStart\n\t\t\t});\n\t\t}\n\n\t\t// Flush any buffered messages so the chunk stream starts immediately.\n\t\tthis.flushMessages(ws);\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: messageId,\n\t\t\thasError: hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\tchunkSize: chunkSize,\n\t\t\t\tencoding: encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage]);\n\n\t\tconst sendChunk = (index: number) => {\n\t\t\tif (!ws || ws.readyState !== WebSocket.OPEN) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= totalChunks) {\n\t\t\t\tconst endMessage: ServerResponseModel = {\n\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\thasError: hasError,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\t\tchunkStatus: 'end'\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.transmitBatch(ws, [endMessage]);\n\t\t\t\tconst durationMs = Date.now() - sendStartMs;\n\t\t\t\tconst bufferedEnd = this.getBufferedAmount(ws);\n\t\t\t\tif (this.shouldLogSend(durationMs, packedData.byteLength, bufferedEnd)) {\n\t\t\t\t\tthis.logWsSend('wsSendEnd', ws, {\n\t\t\t\t\t\tmessageId,\n\t\t\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\t\t\ttotalChunks,\n\t\t\t\t\t\tchunkSize,\n\t\t\t\t\t\tencoding,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\tbufferedAmount: bufferedEnd\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst start = index * chunkSize;\n\t\t\tconst end = Math.min(packedData.byteLength, start + chunkSize);\n\t\t\tconst slice = packedData.subarray(start, end);\n\t\t\tconst payload = encoding === 'msgpack' ? slice : this.toBase64(slice);\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: payload,\n\t\t\t\t\tencoding: encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage]);\n\n\t\t\tthis.scheduleNextChunk(ws, () => sendChunk(index + 1));\n\t\t};\n\n\t\tthis.scheduleNextChunk(ws, () => sendChunk(0));\n\t}\n\n\tprivate flushMessages(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tconst messages = this._messageBuffers.get(wsId);\n\n\t\tif (messages && messages.length > 0) {\n\t\t\t// Combine messages into one payload\n\t\t\tthis.transmitBatch(ws, messages);\n\n\t\t\tthis._messageBuffers.delete(wsId);\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n\t}\n\n\tprivate sendMessagesInChunksBinary(ws: WebSocket, messages: ServerResponseModel[]): void {\n\t\tlet chunk: ServerResponseModel[] = [];\n\t\tlet chunkSize = 0;\n\n\t\tfor (const message of messages) {\n\t\t\tconst packedMessage = Buffer.from(<any>pack([message]));\n\t\t\tconst messageSize = packedMessage.byteLength;\n\n\t\t\tif (chunkSize + messageSize > this._maxMessageSize) {\n\t\t\t\tconst packedChunk = Buffer.from(<any>pack(chunk));\n\t\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tchunk = [message];\n\t\t\t\tchunkSize = messageSize;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tchunk.push(message);\n\t\t\t\tchunkSize += messageSize;\n\t\t\t}\n\t\t}\n\n\t\tif (chunk.length > 0) {\n\t\t\tconst packedChunk = Buffer.from(<any>pack(chunk));\n\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleSendError(ws: WebSocket, error: Error): void {\n\t\tif (this._mainServer.getSubscriptionManager()) {\n\t\t\t// Handle send error, e.g., unsubscribe, close connection\n\t\t\tif (this._mainServer.getSubscriptionManager().getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Unsub WS', ws['user'], ws['id_socket'], error);\n\t\t\t}\n\t\t\tthis._mainServer.getSubscriptionManager().unsubscribeAll(ws);\n\t\t\tthis.removeWebSocket(ws);\n\t\t}\n\t}\n\n\tpublic closeConnection(ws: WebSocket): void {\n\t\tws.close();\n\t\tconst wsId = ws['id_socket'];\n\t\t// Clean up buffers and timers\n\t\tthis._messageBuffers.delete(wsId);\n\t\tif (this._batchingTimers.has(wsId)) {\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n\t\tthis._sendQueues.delete(wsId);\n\t\tif (this._sendQueueTimers.has(wsId)) {\n\t\t\tclearTimeout(this._sendQueueTimers.get(wsId));\n\t\t\tthis._sendQueueTimers.delete(wsId);\n\t\t}\n \n process.nextTick(() => {\n if ([WebSocket.OPEN, WebSocket.CLOSING].includes(<any>ws.readyState)) {\n // Socket still hangs, hard close\n ws.terminate();\n }\n });\n\t}\n\n\tprivate prepareChunkContext(message: ServerResponseModel): { buffer: Buffer, encoding: 'msgpack' | 'json' } | null {\n\t\tif (!this._chunkingEnabled) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (!message || message.hasError) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = message.data;\n\t\tif (data === undefined || data === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\tconst packed = Buffer.from(<any>pack(data));\n\t\t\tif (packed.byteLength > this._chunkThresholdBytes) {\n\t\t\t\treturn { buffer: packed, encoding: 'msgpack' };\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\tif (this._mainServer.getSubscriptionManager()?.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Chunking pack failed', err?.message || err);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate decodePackedPayload(packedData: Uint8Array | Buffer, encoding: 'msgpack' | 'json'): any | undefined {\n\t\ttry {\n\t\t\tconst source = packedData as Uint8Array;\n\t\t\tif (encoding === 'msgpack') {\n\t\t\t\treturn unpack(source);\n\t\t\t}\n\n\t\t\tconst text = this._textDecoder.decode(source);\n\t\t\treturn JSON.parse(text);\n\t\t}\n\t\tcatch (err) {\n\t\t\tif (this._mainServer.getSubscriptionManager()?.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Packed decode failed', err?.message || err);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate sendChunkSequence(ws: WebSocket, original: ServerResponseModel, chunkContext: { buffer: Buffer, encoding: 'msgpack' | 'json' }): void {\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.ceil(chunkContext.buffer.byteLength / this._chunkSizeBytes);\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: original.messageId,\n\t\t\thasError: original.hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: chunkContext.buffer.byteLength,\n\t\t\t\tchunkSize: this._chunkSizeBytes,\n\t\t\t\tencoding: chunkContext.encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage]);\n\n\t\tconst sendChunk = (index: number) => {\n\t\t\tif (!ws || ws.readyState !== WebSocket.OPEN) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= totalChunks) {\n\t\t\t\tconst endMessage: ServerResponseModel = {\n\t\t\t\t\tmessageId: original.messageId,\n\t\t\t\t\thasError: original.hasError,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\t\tchunkStatus: 'end'\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.transmitBatch(ws, [endMessage]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst start = index * this._chunkSizeBytes;\n\t\t\tconst end = Math.min(chunkContext.buffer.byteLength, start + this._chunkSizeBytes);\n\t\t\tconst slice = chunkContext.buffer.subarray(start, end);\n\t\t\tconst chunkPayload = slice;\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: original.messageId,\n\t\t\t\thasError: original.hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: chunkPayload,\n\t\t\t\t\tencoding: chunkContext.encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage]);\n\t\t\tthis.scheduleNextChunk(ws, () => sendChunk(index + 1));\n\t\t};\n\n\t\tthis.scheduleNextChunk(ws, () => sendChunk(0));\n\t}\n\n\tprivate transmitBatch(ws: WebSocket, batch: ServerResponseModel[]): void {\n\t\tif (!batch || !batch.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst wsId = ws['id_socket'];\n\t\tif (this.shouldQueueSend(ws) || this._sendQueues.has(wsId)) {\n\t\t\tthis.enqueueSend(ws, batch);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transmitBatchNow(ws, batch);\n\t}\n\n\tprivate transmitBatchNow(ws: WebSocket, batch: ServerResponseModel[]): void {\n\t\tif (!batch || !batch.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isChunkEnvelope = batch.length === 1 && batch[0]?.data && typeof batch[0].data === 'object' && batch[0].data[this._chunkMetaFlag];\n\n\t\tconst packedData = Buffer.from(<any>pack(batch));\n\t\tconst dataSize = packedData.byteLength;\n\t\tconst bufferedAmount = this.getBufferedAmount(ws);\n\n\t\tif (!isChunkEnvelope && dataSize > this._maxMessageSize) {\n\t\t\tthis.sendMessagesInChunksBinary(ws, batch);\n\t\t}\n\t\telse {\n\t\t\tws.send(packedData, (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (this.shouldLogSend(null, dataSize, bufferedAmount)) {\n\t\t\tthis.logWsSend('wsBatchSend', ws, {\n\t\t\t\tbatchSize: batch.length,\n\t\t\t\tdataSize,\n\t\t\t\tisChunkEnvelope,\n\t\t\t\tbufferedAmount\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate generateChunkId(): string {\n\t\treturn randomBytes(8).toString('hex');\n\t}\n\n\tprivate toBase64(data: Uint8Array | Buffer): string {\n\t\tif (Buffer.isBuffer(data)) {\n\t\t\treturn data.toString('base64');\n\t\t}\n\n\t\treturn Buffer.from(data).toString('base64');\n\t}\n}\n"]}
@@ -29,6 +29,8 @@ export declare class WorkerDispatcherManager {
29
29
  private _pendingTasks;
30
30
  private _debugNoWorkerTaskIds;
31
31
  private _taskTimings;
32
+ private _dispatchRetryTimer;
33
+ private _dispatchRetryDelayMs;
32
34
  private MAX_CONCURRENCY;
33
35
  private WORKER_TASK_LOG_THRESHOLD_MS;
34
36
  private WORKER_PUBLICATION_SLOW_MS;
@@ -80,6 +82,7 @@ export declare class WorkerDispatcherManager {
80
82
  * The main loop that assigns tasks from _taskQueue to any worker that has capacity.
81
83
  */
82
84
  private dispatchQueue;
85
+ private scheduleDispatchRetry;
83
86
  /**
84
87
  * Returns the worker with the fewest activeTasks that is under maxConcurrency and per-method limit.
85
88
  */
@@ -34,6 +34,8 @@ var WorkerDispatcherManager = /** @class */ (function () {
34
34
  this._pendingTasks = new Map();
35
35
  this._debugNoWorkerTaskIds = new Set();
36
36
  this._taskTimings = new Map();
37
+ this._dispatchRetryTimer = null;
38
+ this._dispatchRetryDelayMs = 25;
37
39
  this.MAX_CONCURRENCY = 10;
38
40
  this.WORKER_TASK_LOG_THRESHOLD_MS = 200;
39
41
  this.WORKER_PUBLICATION_SLOW_MS = 20000;
@@ -372,10 +374,12 @@ var WorkerDispatcherManager = /** @class */ (function () {
372
374
  * The main loop that assigns tasks from _taskQueue to any worker that has capacity.
373
375
  */
374
376
  WorkerDispatcherManager.prototype.dispatchQueue = function () {
375
- var _this = this;
376
377
  if (!this._taskQueue.length) {
377
378
  return;
378
379
  }
380
+ if (!this._workers.length) {
381
+ return;
382
+ }
379
383
  while (this._taskQueue.length > 0) {
380
384
  var assigned = false;
381
385
  var hasPublicationTask = this._taskQueue.some(function (task) { return task.method === 'runPublication'; });
@@ -408,9 +412,7 @@ var WorkerDispatcherManager = /** @class */ (function () {
408
412
  }
409
413
  if (!assigned) {
410
414
  this.logNoWorkerAvailability();
411
- setTimeout(function () {
412
- _this.dispatchQueue();
413
- }, 25);
415
+ this.scheduleDispatchRetry();
414
416
  if (this._methodManager.getEnableDebug()) {
415
417
  console.log(new Date(), 'No Worker Available', JSON.stringify(this._workers, null, 2));
416
418
  }
@@ -418,6 +420,17 @@ var WorkerDispatcherManager = /** @class */ (function () {
418
420
  }
419
421
  }
420
422
  };
423
+ WorkerDispatcherManager.prototype.scheduleDispatchRetry = function (delayMs) {
424
+ var _this = this;
425
+ if (delayMs === void 0) { delayMs = this._dispatchRetryDelayMs; }
426
+ if (this._dispatchRetryTimer) {
427
+ return;
428
+ }
429
+ this._dispatchRetryTimer = setTimeout(function () {
430
+ _this._dispatchRetryTimer = null;
431
+ _this.dispatchQueue();
432
+ }, delayMs);
433
+ };
421
434
  /**
422
435
  * Returns the worker with the fewest activeTasks that is under maxConcurrency and per-method limit.
423
436
  */