@celerispay/hazelcast-client 3.12.5-1 → 3.12.5-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.
|
@@ -36,6 +36,25 @@ export declare class ClientConnectionManager extends EventEmitter {
|
|
|
36
36
|
getActiveConnections(): {
|
|
37
37
|
[address: string]: ClientConnection;
|
|
38
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Checks if we already have a connection to the given address
|
|
41
|
+
* @param address The address to check
|
|
42
|
+
* @returns true if connection exists and is healthy, false otherwise
|
|
43
|
+
*/
|
|
44
|
+
hasConnection(address: Address): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Gets an existing connection to a specific address if it exists
|
|
47
|
+
* @param address The address to check for existing connection
|
|
48
|
+
* @returns The existing connection or undefined if none exists
|
|
49
|
+
*/
|
|
50
|
+
getConnection(address: Address): ClientConnection | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Gets all established connections
|
|
53
|
+
* @returns Object containing all established connections
|
|
54
|
+
*/
|
|
55
|
+
getEstablishedConnections(): {
|
|
56
|
+
[address: string]: ClientConnection;
|
|
57
|
+
};
|
|
39
58
|
/**
|
|
40
59
|
* Returns the {@link ClientConnection} with given {@link Address}. If there is no such connection established,
|
|
41
60
|
* it first connects to the address and then return the {@link ClientConnection}.
|
|
@@ -98,6 +98,17 @@ var ClientConnectionManager = /** @class */ (function (_super) {
|
|
|
98
98
|
_this.destroyConnection(connection.getAddress());
|
|
99
99
|
}
|
|
100
100
|
});
|
|
101
|
+
// Log current connection state
|
|
102
|
+
var activeConnections = Object.keys(this.establishedConnections).length;
|
|
103
|
+
var pendingConnections = Object.keys(this.pendingConnections).length;
|
|
104
|
+
var failedConnections = this.failedConnections.size;
|
|
105
|
+
this.logger.debug('ClientConnectionManager', "Connection State - Active: " + activeConnections + ", Pending: " + pendingConnections + ", Failed: " + failedConnections);
|
|
106
|
+
if (activeConnections > 0) {
|
|
107
|
+
Object.keys(this.establishedConnections).forEach(function (addressStr) {
|
|
108
|
+
var connection = _this.establishedConnections[addressStr];
|
|
109
|
+
_this.logger.debug('ClientConnectionManager', "Connection to " + addressStr + ": Alive=" + connection.isAlive() + ", Owner=" + connection.isAuthenticatedAsOwner());
|
|
110
|
+
});
|
|
111
|
+
}
|
|
101
112
|
};
|
|
102
113
|
ClientConnectionManager.prototype.checkConnectionHealth = function () {
|
|
103
114
|
// Use Object.keys() instead of Object.values() for compatibility
|
|
@@ -160,6 +171,32 @@ var ClientConnectionManager = /** @class */ (function (_super) {
|
|
|
160
171
|
ClientConnectionManager.prototype.getActiveConnections = function () {
|
|
161
172
|
return this.establishedConnections;
|
|
162
173
|
};
|
|
174
|
+
/**
|
|
175
|
+
* Checks if we already have a connection to the given address
|
|
176
|
+
* @param address The address to check
|
|
177
|
+
* @returns true if connection exists and is healthy, false otherwise
|
|
178
|
+
*/
|
|
179
|
+
ClientConnectionManager.prototype.hasConnection = function (address) {
|
|
180
|
+
var addressStr = address.toString();
|
|
181
|
+
var connection = this.establishedConnections[addressStr];
|
|
182
|
+
return connection && connection.isAlive();
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Gets an existing connection to a specific address if it exists
|
|
186
|
+
* @param address The address to check for existing connection
|
|
187
|
+
* @returns The existing connection or undefined if none exists
|
|
188
|
+
*/
|
|
189
|
+
ClientConnectionManager.prototype.getConnection = function (address) {
|
|
190
|
+
var addressStr = address.toString();
|
|
191
|
+
return this.establishedConnections[addressStr];
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Gets all established connections
|
|
195
|
+
* @returns Object containing all established connections
|
|
196
|
+
*/
|
|
197
|
+
ClientConnectionManager.prototype.getEstablishedConnections = function () {
|
|
198
|
+
return this.establishedConnections;
|
|
199
|
+
};
|
|
163
200
|
/**
|
|
164
201
|
* Returns the {@link ClientConnection} with given {@link Address}. If there is no such connection established,
|
|
165
202
|
* it first connects to the address and then return the {@link ClientConnection}.
|
|
@@ -98,7 +98,15 @@ export declare class ClusterService {
|
|
|
98
98
|
private handleMemberAttributeChange(uuid, key, operationType, value);
|
|
99
99
|
private memberAdded(member);
|
|
100
100
|
private memberRemoved(member);
|
|
101
|
+
/**
|
|
102
|
+
* Logs the current state for debugging purposes
|
|
103
|
+
*/
|
|
104
|
+
private logCurrentState();
|
|
101
105
|
private startReconnectionTask();
|
|
106
|
+
/**
|
|
107
|
+
* Starts a periodic task to log the current state for debugging
|
|
108
|
+
*/
|
|
109
|
+
private startStateLoggingTask();
|
|
102
110
|
private attemptReconnectionToFailedNodes();
|
|
103
111
|
/**
|
|
104
112
|
* Attempts to establish a connection to a specific address
|
|
@@ -57,6 +57,7 @@ var ClusterService = /** @class */ (function () {
|
|
|
57
57
|
this.logger = this.client.getLoggingService().getLogger();
|
|
58
58
|
this.members = [];
|
|
59
59
|
this.startReconnectionTask();
|
|
60
|
+
this.startStateLoggingTask();
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
62
63
|
* Starts cluster service.
|
|
@@ -227,15 +228,19 @@ var ClusterService = /** @class */ (function () {
|
|
|
227
228
|
this.failoverInProgress = true;
|
|
228
229
|
this.lastFailoverAttempt = now;
|
|
229
230
|
this.logger.info('ClusterService', 'Starting failover process...');
|
|
231
|
+
// Log state before failover
|
|
232
|
+
this.logCurrentState();
|
|
230
233
|
// Clear any stale partition information
|
|
231
234
|
this.client.getPartitionService().clearPartitionTable();
|
|
232
235
|
// Attempt to reconnect to cluster
|
|
233
236
|
this.connectToCluster()
|
|
234
237
|
.then(function () {
|
|
235
238
|
_this.logger.info('ClusterService', 'Failover completed successfully');
|
|
239
|
+
_this.logCurrentState(); // Log state after successful failover
|
|
236
240
|
})
|
|
237
241
|
.catch(function (error) {
|
|
238
242
|
_this.logger.error('ClusterService', 'Failover failed', error);
|
|
243
|
+
_this.logCurrentState(); // Log state after failed failover
|
|
239
244
|
// If failover fails, shutdown the client to prevent further issues
|
|
240
245
|
_this.client.shutdown();
|
|
241
246
|
})
|
|
@@ -349,6 +354,8 @@ var ClusterService = /** @class */ (function () {
|
|
|
349
354
|
this.members = members;
|
|
350
355
|
this.client.getPartitionService().refresh();
|
|
351
356
|
this.logger.info('ClusterService', 'Members received.', this.members);
|
|
357
|
+
// Log current state after member list update
|
|
358
|
+
this.logCurrentState();
|
|
352
359
|
var events = this.detectMembershipEvents(prevMembers);
|
|
353
360
|
for (var _i = 0, events_1 = events; _i < events_1.length; _i++) {
|
|
354
361
|
var event = events_1[_i];
|
|
@@ -416,10 +423,42 @@ var ClusterService = /** @class */ (function () {
|
|
|
416
423
|
var removedMemberList = this.members.splice(memberIndex, 1);
|
|
417
424
|
assert(removedMemberList.length === 1);
|
|
418
425
|
}
|
|
419
|
-
|
|
426
|
+
// Don't automatically destroy connections during failover
|
|
427
|
+
if (!this.failoverInProgress) {
|
|
428
|
+
this.logger.info('ClusterService', "Member removed: " + member.address.toString() + ", destroying connection");
|
|
429
|
+
this.client.getConnectionManager().destroyConnection(member.address);
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
this.logger.debug('ClusterService', "Member removed during failover: " + member.address.toString() + ", keeping connection for evaluation");
|
|
433
|
+
}
|
|
420
434
|
var membershipEvent = new MembershipEvent_1.MembershipEvent(member, MemberEvent.REMOVED, this.members);
|
|
421
435
|
this.fireMembershipEvent(membershipEvent);
|
|
422
436
|
};
|
|
437
|
+
/**
|
|
438
|
+
* Logs the current state for debugging purposes
|
|
439
|
+
*/
|
|
440
|
+
ClusterService.prototype.logCurrentState = function () {
|
|
441
|
+
var _this = this;
|
|
442
|
+
var activeConnections = Object.keys(this.client.getConnectionManager().getEstablishedConnections()).length;
|
|
443
|
+
var memberCount = this.members.length;
|
|
444
|
+
var downAddressesCount = this.downAddresses.size;
|
|
445
|
+
var hasOwner = !!this.ownerConnection;
|
|
446
|
+
this.logger.info('ClusterService', "Current State - Members: " + memberCount + ", Active Connections: " + activeConnections + ", Down Addresses: " + downAddressesCount + ", Has Owner: " + hasOwner);
|
|
447
|
+
if (this.ownerConnection) {
|
|
448
|
+
this.logger.info('ClusterService', "Owner Connection: " + this.ownerConnection.getAddress().toString() + ", Alive: " + this.ownerConnection.isAlive());
|
|
449
|
+
}
|
|
450
|
+
// Log all active connections
|
|
451
|
+
var connections = this.client.getConnectionManager().getEstablishedConnections();
|
|
452
|
+
Object.keys(connections).forEach(function (addressStr) {
|
|
453
|
+
var connection = connections[addressStr];
|
|
454
|
+
_this.logger.debug('ClusterService', "Connection to " + addressStr + ": Alive=" + connection.isAlive() + ", Owner=" + connection.isAuthenticatedAsOwner());
|
|
455
|
+
});
|
|
456
|
+
// Log down addresses
|
|
457
|
+
if (downAddressesCount > 0) {
|
|
458
|
+
var downAddresses = Array.from(this.downAddresses.keys());
|
|
459
|
+
this.logger.debug('ClusterService', "Down Addresses: " + downAddresses.join(', '));
|
|
460
|
+
}
|
|
461
|
+
};
|
|
423
462
|
ClusterService.prototype.startReconnectionTask = function () {
|
|
424
463
|
var _this = this;
|
|
425
464
|
// Periodically attempt to reconnect to previously failed addresses
|
|
@@ -427,15 +466,29 @@ var ClusterService = /** @class */ (function () {
|
|
|
427
466
|
_this.attemptReconnectionToFailedNodes();
|
|
428
467
|
}, this.reconnectionInterval);
|
|
429
468
|
};
|
|
469
|
+
/**
|
|
470
|
+
* Starts a periodic task to log the current state for debugging
|
|
471
|
+
*/
|
|
472
|
+
ClusterService.prototype.startStateLoggingTask = function () {
|
|
473
|
+
var _this = this;
|
|
474
|
+
// Log state every 30 seconds for debugging
|
|
475
|
+
setInterval(function () {
|
|
476
|
+
if (_this.client.getLifecycleService().isRunning()) {
|
|
477
|
+
_this.logCurrentState();
|
|
478
|
+
}
|
|
479
|
+
}, 30000);
|
|
480
|
+
};
|
|
430
481
|
ClusterService.prototype.attemptReconnectionToFailedNodes = function () {
|
|
431
482
|
var _this = this;
|
|
432
|
-
|
|
483
|
+
// Allow reconnection even during failover, but be more careful
|
|
484
|
+
if (this.failoverInProgress) {
|
|
485
|
+
this.logger.debug('ClusterService', 'Skipping reconnection attempt during failover');
|
|
433
486
|
return;
|
|
434
487
|
}
|
|
435
488
|
var now = Date.now();
|
|
436
489
|
var addressesToReconnect = [];
|
|
437
490
|
var totalDownAddresses = this.downAddresses.size;
|
|
438
|
-
// If we have no down addresses, we can
|
|
491
|
+
// If we have no down addresses, we can skip
|
|
439
492
|
if (totalDownAddresses === 0) {
|
|
440
493
|
return;
|
|
441
494
|
}
|
|
@@ -449,6 +502,12 @@ var ClusterService = /** @class */ (function () {
|
|
|
449
502
|
var port = parseInt(portStr, 10);
|
|
450
503
|
if (host && !isNaN(port)) {
|
|
451
504
|
var address = new Address(host, port);
|
|
505
|
+
// Check if we already have a connection to this address
|
|
506
|
+
if (_this.client.getConnectionManager().hasConnection(address)) {
|
|
507
|
+
_this.logger.debug('ClusterService', "Already have active connection to " + addressStr + ", removing from down addresses");
|
|
508
|
+
_this.downAddresses.delete(addressStr);
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
452
511
|
addressesToReconnect.push(address);
|
|
453
512
|
}
|
|
454
513
|
}
|
|
@@ -474,6 +533,8 @@ var ClusterService = /** @class */ (function () {
|
|
|
474
533
|
});
|
|
475
534
|
this.logger.debug('ClusterService', "Still waiting for " + totalDownAddresses + " addresses to unblock: " + remainingBlocked.join(', '));
|
|
476
535
|
}
|
|
536
|
+
// Log current state after reconnection attempts
|
|
537
|
+
this.logCurrentState();
|
|
477
538
|
};
|
|
478
539
|
/**
|
|
479
540
|
* Attempts to establish a connection to a specific address
|
|
@@ -482,6 +543,12 @@ var ClusterService = /** @class */ (function () {
|
|
|
482
543
|
ClusterService.prototype.attemptReconnectionToAddress = function (address) {
|
|
483
544
|
var _this = this;
|
|
484
545
|
var addressStr = address.toString();
|
|
546
|
+
// Check if we already have a connection to this address
|
|
547
|
+
if (this.client.getConnectionManager().hasConnection(address)) {
|
|
548
|
+
this.logger.debug('ClusterService', "Already have active connection to " + addressStr + ", skipping reconnection");
|
|
549
|
+
this.downAddresses.delete(addressStr);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
485
552
|
// Remove from down addresses to allow connection attempt
|
|
486
553
|
this.downAddresses.delete(addressStr);
|
|
487
554
|
this.logger.debug('ClusterService', "Attempting reconnection to " + addressStr);
|
|
@@ -489,8 +556,14 @@ var ClusterService = /** @class */ (function () {
|
|
|
489
556
|
this.client.getConnectionManager().getOrConnect(address, false)
|
|
490
557
|
.then(function (connection) {
|
|
491
558
|
_this.logger.info('ClusterService', "Successfully reconnected to " + addressStr);
|
|
492
|
-
//
|
|
493
|
-
_this.
|
|
559
|
+
// Only evaluate ownership change if we don't have an owner or current owner is unhealthy
|
|
560
|
+
if (!_this.ownerConnection || !_this.ownerConnection.isAlive()) {
|
|
561
|
+
_this.logger.info('ClusterService', "Evaluating ownership change for " + addressStr);
|
|
562
|
+
_this.evaluateOwnershipChange(address, connection);
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
_this.logger.debug('ClusterService', "Keeping " + addressStr + " as member connection, current owner is healthy");
|
|
566
|
+
}
|
|
494
567
|
// Trigger partition service refresh to update routing information
|
|
495
568
|
_this.client.getPartitionService().refresh();
|
|
496
569
|
}).catch(function (error) {
|
|
@@ -518,12 +591,8 @@ var ClusterService = /** @class */ (function () {
|
|
|
518
591
|
this.promoteToOwner(connection, address);
|
|
519
592
|
return;
|
|
520
593
|
}
|
|
521
|
-
//
|
|
522
|
-
|
|
523
|
-
if (wasPreviousOwner) {
|
|
524
|
-
this.logger.debug('ClusterService', "Reconnected node " + address.toString() + " was previously known, monitoring for ownership opportunity");
|
|
525
|
-
// Don't switch ownership immediately, but keep the connection for potential future use
|
|
526
|
-
}
|
|
594
|
+
// Don't switch ownership if current owner is healthy
|
|
595
|
+
this.logger.debug('ClusterService', "Current owner is healthy, keeping " + address.toString() + " as member connection");
|
|
527
596
|
};
|
|
528
597
|
/**
|
|
529
598
|
* Promotes a connection to owner status
|
package/package.json
CHANGED