jsgar 3.7.2 → 3.7.8
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/dist/gar.umd.js +62 -25
- package/package.json +1 -1
package/dist/gar.umd.js
CHANGED
|
@@ -47,7 +47,11 @@
|
|
|
47
47
|
this.reconnectDelay = 5000; // Milliseconds
|
|
48
48
|
this.user = user;
|
|
49
49
|
this.working_namespace = working_namespace;
|
|
50
|
-
this.
|
|
50
|
+
this.timeoutScale = (typeof process !== 'undefined' && process.env && process.env.TRS_TIMEOUT_SCALE) ? parseFloat(process.env.TRS_TIMEOUT_SCALE) : 1.0;
|
|
51
|
+
this.scaledHeartbeatTimeoutInterval = heartbeatTimeoutInterval;
|
|
52
|
+
if (this.timeoutScale !== 1.0) {
|
|
53
|
+
this.scaledHeartbeatTimeoutInterval *= this.timeoutScale;
|
|
54
|
+
}
|
|
51
55
|
this.version = 650707;
|
|
52
56
|
|
|
53
57
|
if (typeof window !== 'undefined' && window.location) {
|
|
@@ -70,7 +74,6 @@
|
|
|
70
74
|
this.heartbeatIntervalId = null;
|
|
71
75
|
this.messageHandlers = new Map();
|
|
72
76
|
this.lastHeartbeatTime = Date.now() / 1000;
|
|
73
|
-
this.heartbeatTimeout = 3; // Seconds
|
|
74
77
|
|
|
75
78
|
this.heartbeatTimeoutCallback = null;
|
|
76
79
|
this.stoppedCallback = null;
|
|
@@ -145,42 +148,72 @@
|
|
|
145
148
|
|
|
146
149
|
/**
|
|
147
150
|
* Establish WebSocket connection with reconnection logic.
|
|
151
|
+
* @param {number} [openTimeout=20] - Connection timeout in seconds
|
|
148
152
|
*/
|
|
149
|
-
|
|
150
|
-
* Establish WebSocket connection with reconnection logic.
|
|
151
|
-
*/
|
|
152
|
-
async connect() {
|
|
153
|
+
async connect(openTimeout = 20) {
|
|
153
154
|
// Before attempting a new connection, clear any previous state
|
|
154
155
|
this.clearConnectionState();
|
|
155
156
|
|
|
157
|
+
let scaledOpenTimeout = openTimeout * this.timeoutScale;
|
|
158
|
+
|
|
156
159
|
while (this.running && !this.connected) {
|
|
157
160
|
try {
|
|
158
161
|
const WS = await this._ensureWebSocketCtor();
|
|
159
162
|
const isNode = typeof process !== 'undefined' && process.versions && process.versions.node;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
163
|
+
|
|
164
|
+
this.log('INFO', `Connecting to WebSocket server at ${this.wsEndpoint}`);
|
|
165
|
+
|
|
166
|
+
const connectionPromise = new Promise((resolve, reject) => {
|
|
167
|
+
let websocket;
|
|
168
|
+
if (this.allowSelfSignedCertificate && isNode) {
|
|
169
|
+
// Node.js 'ws' supports options for TLS; browsers do not.
|
|
170
|
+
websocket = new WS(this.wsEndpoint, ['gar-protocol'], { rejectUnauthorized: false });
|
|
171
|
+
} else {
|
|
172
|
+
websocket = new WS(this.wsEndpoint, ['gar-protocol']);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const timeoutId = setTimeout(() => {
|
|
176
|
+
websocket.onopen = null;
|
|
177
|
+
websocket.onclose = null;
|
|
178
|
+
websocket.onerror = null;
|
|
179
|
+
if (websocket.terminate) websocket.terminate();
|
|
180
|
+
else if (websocket.close) websocket.close();
|
|
181
|
+
reject(new Error(`Connection timed out after ${scaledOpenTimeout}s`));
|
|
182
|
+
}, scaledOpenTimeout * 1000);
|
|
183
|
+
|
|
184
|
+
websocket.onopen = () => {
|
|
185
|
+
clearTimeout(timeoutId);
|
|
186
|
+
resolve(websocket);
|
|
187
|
+
};
|
|
188
|
+
websocket.onerror = (error) => {
|
|
189
|
+
clearTimeout(timeoutId);
|
|
190
|
+
reject(new Error(error.message || 'Unknown WebSocket error'));
|
|
191
|
+
};
|
|
192
|
+
websocket.onclose = () => {
|
|
193
|
+
clearTimeout(timeoutId);
|
|
194
|
+
reject(new Error('WebSocket closed during connection attempt'));
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
this.websocket = await connectionPromise;
|
|
199
|
+
this.connected = true;
|
|
200
|
+
this.log('INFO', `Connected to WebSocket server at ${this.wsEndpoint} using gar-protocol`);
|
|
201
|
+
|
|
172
202
|
this.websocket.onclose = () => {
|
|
173
203
|
this.log('WARNING', 'WebSocket connection closed.');
|
|
174
204
|
this.connected = false;
|
|
175
205
|
this.websocket = null;
|
|
206
|
+
this._reconnect();
|
|
176
207
|
};
|
|
177
208
|
this.websocket.onerror = (error) => {
|
|
178
209
|
this.log('ERROR', `WebSocket error: ${error.message || 'Unknown error'}`);
|
|
179
210
|
this.connected = false;
|
|
180
211
|
this.websocket = null;
|
|
181
212
|
};
|
|
182
|
-
|
|
183
|
-
|
|
213
|
+
|
|
214
|
+
this._sendMessages();
|
|
215
|
+
this._receiveMessages();
|
|
216
|
+
|
|
184
217
|
} catch (e) {
|
|
185
218
|
this.log('ERROR', `WebSocket connection failed: ${e.message}. Reconnecting in ${this.reconnectDelay / 1000} seconds...`);
|
|
186
219
|
this.connected = false;
|
|
@@ -457,13 +490,13 @@
|
|
|
457
490
|
message_type: 'Introduction',
|
|
458
491
|
value: {
|
|
459
492
|
version: this.version,
|
|
460
|
-
heartbeat_timeout_interval: this.
|
|
493
|
+
heartbeat_timeout_interval: Math.floor(this.scaledHeartbeatTimeoutInterval),
|
|
461
494
|
user: this.user,
|
|
462
495
|
working_namespace: this.working_namespace
|
|
463
496
|
}
|
|
464
497
|
};
|
|
465
498
|
this.sendMessage(introMsg);
|
|
466
|
-
this.heartbeatIntervalId = setInterval(() => this._heartbeatLoop(), this.
|
|
499
|
+
this.heartbeatIntervalId = setInterval(() => this._heartbeatLoop(), this.scaledHeartbeatTimeoutInterval / 2);
|
|
467
500
|
this.connect();
|
|
468
501
|
}
|
|
469
502
|
|
|
@@ -590,7 +623,7 @@
|
|
|
590
623
|
*/
|
|
591
624
|
checkHeartbeat() {
|
|
592
625
|
const now = Date.now() / 1000;
|
|
593
|
-
const cutoff = this._initialGracePeriod ? this._initialGraceDeadline : this.lastHeartbeatTime + this.
|
|
626
|
+
const cutoff = this._initialGracePeriod ? this._initialGraceDeadline : this.lastHeartbeatTime + (this.scaledHeartbeatTimeoutInterval / 1000.0);
|
|
594
627
|
if (now > cutoff) {
|
|
595
628
|
this.log('WARNING', `Heartbeat failed; previous heartbeat: ${this.lastHeartbeatTime.toFixed(3)}s`);
|
|
596
629
|
this.exitCode = 1;
|
|
@@ -678,10 +711,14 @@
|
|
|
678
711
|
this.serverKeyIdToName.clear();
|
|
679
712
|
this.serverKeyNameToId.clear();
|
|
680
713
|
this.recordMap.clear();
|
|
681
|
-
|
|
714
|
+
let newInterval = value.heartbeat_timeout_interval;
|
|
715
|
+
if (this.timeoutScale !== 1.0) {
|
|
716
|
+
newInterval *= this.timeoutScale;
|
|
717
|
+
}
|
|
718
|
+
this.scaledHeartbeatTimeoutInterval = Math.max(this.scaledHeartbeatTimeoutInterval, newInterval);
|
|
682
719
|
this.lastHeartbeatTime = Date.now() / 1000;
|
|
683
720
|
this._initialGracePeriod = true;
|
|
684
|
-
this._initialGraceDeadline = this.lastHeartbeatTime + this.
|
|
721
|
+
this._initialGraceDeadline = this.lastHeartbeatTime + (this.scaledHeartbeatTimeoutInterval / 1000.0) * 10;
|
|
685
722
|
// New Introduction: do not reset the first-heartbeat promise to avoid racing
|
|
686
723
|
// with consumers already awaiting it. The existing promise will resolve on
|
|
687
724
|
// the first Heartbeat observed during the grace period above.
|