@celerispay/hazelcast-client 3.12.7-3 → 3.12.7-5
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.
|
@@ -139,6 +139,13 @@ export declare class ClientConnectionManager extends EventEmitter {
|
|
|
139
139
|
* Clears all stored credentials - used for single-node cluster reset
|
|
140
140
|
*/
|
|
141
141
|
clearAllCredentials(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Clears the failed connections blocklist so previously failed addresses
|
|
144
|
+
* can be retried immediately. Called after a cluster reset to ensure
|
|
145
|
+
* async destroyConnection() calls don't re-block addresses that were
|
|
146
|
+
* just unblocked for reconnection.
|
|
147
|
+
*/
|
|
148
|
+
clearFailedConnections(): void;
|
|
142
149
|
/**
|
|
143
150
|
* Handles authentication errors by clearing failed connections and allowing retry
|
|
144
151
|
* @param address The address that had authentication issues
|
|
@@ -137,8 +137,10 @@ var ClientConnectionManager = /** @class */ (function (_super) {
|
|
|
137
137
|
_this.failedConnections.delete(address.toString());
|
|
138
138
|
return connection;
|
|
139
139
|
}).catch(function (error) {
|
|
140
|
-
// Check if it's an authentication error
|
|
141
|
-
|
|
140
|
+
// Check if it's an authentication error.
|
|
141
|
+
// error.message may be null when the server sends a null-message protocol error
|
|
142
|
+
// (e.g. ReferenceError: null from ErrorFactory), so we check for null explicitly.
|
|
143
|
+
var isAuthError = (error.message == null) || (error.message.includes('Invalid Credentials') ||
|
|
142
144
|
error.message.includes('authentication') ||
|
|
143
145
|
error.message.includes('credentials'));
|
|
144
146
|
if (isAuthError) {
|
|
@@ -486,6 +488,17 @@ var ClientConnectionManager = /** @class */ (function (_super) {
|
|
|
486
488
|
this.failedConnections.clear();
|
|
487
489
|
this.logger.info('ClientConnectionManager', '✅ All credentials cleared, ready for fresh authentication');
|
|
488
490
|
};
|
|
491
|
+
/**
|
|
492
|
+
* Clears the failed connections blocklist so previously failed addresses
|
|
493
|
+
* can be retried immediately. Called after a cluster reset to ensure
|
|
494
|
+
* async destroyConnection() calls don't re-block addresses that were
|
|
495
|
+
* just unblocked for reconnection.
|
|
496
|
+
*/
|
|
497
|
+
ClientConnectionManager.prototype.clearFailedConnections = function () {
|
|
498
|
+
var count = this.failedConnections.size;
|
|
499
|
+
this.failedConnections.clear();
|
|
500
|
+
this.logger.info('ClientConnectionManager', "\uD83D\uDD13 Cleared " + count + " failed connection entries, all addresses unblocked");
|
|
501
|
+
};
|
|
489
502
|
/**
|
|
490
503
|
* Handles authentication errors by clearing failed connections and allowing retry
|
|
491
504
|
* @param address The address that had authentication issues
|
|
@@ -280,20 +280,32 @@ var ClusterService = /** @class */ (function () {
|
|
|
280
280
|
this.client.getConnectionManager().forceCleanupDeadConnections();
|
|
281
281
|
// Clear partition information
|
|
282
282
|
this.client.getPartitionService().clearPartitionTable();
|
|
283
|
-
//
|
|
284
|
-
|
|
285
|
-
this.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
.
|
|
295
|
-
_this.
|
|
296
|
-
|
|
283
|
+
// IMPORTANT: Unblock all down addresses before attempting reconnection.
|
|
284
|
+
// We must clear BOTH blocklists:
|
|
285
|
+
// 1. this.downAddresses — ClusterService-level block (checked by tryConnectingToAddresses)
|
|
286
|
+
// 2. failedConnections — ClientConnectionManager-level block (checked by getOrConnect)
|
|
287
|
+
// We delay by 200ms to let any in-flight async destroyConnection() calls finish,
|
|
288
|
+
// because destroyConnection() re-adds the address to failedConnections after we clear it.
|
|
289
|
+
// Clearing both right before connectToCluster() ensures neither blocklist interferes.
|
|
290
|
+
this.logger.info('ClusterService', '🔓 SINGLE-NODE RESET: Scheduling reconnection after brief stabilization delay...');
|
|
291
|
+
setTimeout(function () {
|
|
292
|
+
// Clear both blocklists right before attempting reconnection
|
|
293
|
+
_this.downAddresses.clear();
|
|
294
|
+
_this.client.getConnectionManager().clearFailedConnections();
|
|
295
|
+
_this.logger.info('ClusterService', '🔄 SINGLE-NODE RESET: Attempting direct reconnection...');
|
|
296
|
+
_this.connectToCluster()
|
|
297
|
+
.then(function () {
|
|
298
|
+
_this.logger.info('ClusterService', '✅ Single-node cluster reset completed successfully');
|
|
299
|
+
_this.logCurrentState();
|
|
300
|
+
})
|
|
301
|
+
.catch(function (error) {
|
|
302
|
+
_this.logger.error('ClusterService', 'Single-node cluster reset failed', error);
|
|
303
|
+
_this.logCurrentState();
|
|
304
|
+
})
|
|
305
|
+
.finally(function () {
|
|
306
|
+
_this.failoverInProgress = false;
|
|
307
|
+
});
|
|
308
|
+
}, 200);
|
|
297
309
|
};
|
|
298
310
|
/**
|
|
299
311
|
* Handles multi-node failover - preserves existing logic
|
|
@@ -806,21 +818,35 @@ var ClusterService = /** @class */ (function () {
|
|
|
806
818
|
}
|
|
807
819
|
// Remove from down addresses to allow connection attempt
|
|
808
820
|
this.downAddresses.delete(addressStr);
|
|
809
|
-
|
|
810
|
-
//
|
|
811
|
-
|
|
821
|
+
// Determine whether to connect as owner.
|
|
822
|
+
// If we have no owner connection (e.g. after a single-node restart), we must
|
|
823
|
+
// authenticate as owner so the server assigns fresh UUIDs. Connecting as a
|
|
824
|
+
// non-owner with null UUIDs will always be rejected by the server.
|
|
825
|
+
var needsOwner = !this.ownerConnection || !this.ownerConnection.isHealthy();
|
|
826
|
+
var connectAsOwner = needsOwner;
|
|
827
|
+
this.logger.info('ClusterService', "Attempting reconnection to " + addressStr + " (asOwner=" + connectAsOwner + ", needsOwner=" + needsOwner + ")");
|
|
828
|
+
this.client.getConnectionManager().getOrConnect(address, connectAsOwner)
|
|
812
829
|
.then(function (connection) {
|
|
813
830
|
_this.logger.info('ClusterService', "Successfully reconnected to " + addressStr);
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
_this.
|
|
831
|
+
if (connectAsOwner) {
|
|
832
|
+
// We authenticated as owner — make it official and re-register membership listener
|
|
833
|
+
connection.setAuthenticatedAsOwner(true);
|
|
834
|
+
_this.ownerConnection = connection;
|
|
835
|
+
_this.logger.info('ClusterService', "Promoted " + addressStr + " to owner after reconnection");
|
|
836
|
+
// Re-register membership listener so member events resume
|
|
837
|
+
return _this.initMembershipListener().then(function () {
|
|
838
|
+
_this.logger.info('ClusterService', "Membership listener re-registered after reconnection to " + addressStr);
|
|
839
|
+
_this.client.getPartitionService().refresh();
|
|
840
|
+
}).catch(function (err) {
|
|
841
|
+
_this.logger.warn('ClusterService', "Failed to re-register membership listener after reconnection: " + err.message);
|
|
842
|
+
_this.client.getPartitionService().refresh();
|
|
843
|
+
});
|
|
818
844
|
}
|
|
819
845
|
else {
|
|
846
|
+
// Non-owner: evaluate if ownership should change (multi-node case)
|
|
820
847
|
_this.logger.debug('ClusterService', "Keeping " + addressStr + " as member connection, current owner is healthy");
|
|
848
|
+
_this.client.getPartitionService().refresh();
|
|
821
849
|
}
|
|
822
|
-
// Trigger partition service refresh to update routing information
|
|
823
|
-
_this.client.getPartitionService().refresh();
|
|
824
850
|
}).catch(function (error) {
|
|
825
851
|
_this.logger.warn('ClusterService', "Reconnection attempt to " + addressStr + " failed:", error);
|
|
826
852
|
// Mark the address as down again, but with a shorter block duration for reconnection attempts
|
package/package.json
CHANGED