@celerispay/hazelcast-client 3.12.7-4 → 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
- var isAuthError = error.message && (error.message.includes('Invalid Credentials') ||
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
@@ -281,26 +281,31 @@ var ClusterService = /** @class */ (function () {
281
281
  // Clear partition information
282
282
  this.client.getPartitionService().clearPartitionTable();
283
283
  // IMPORTANT: Unblock all down addresses before attempting reconnection.
284
- // The address was just marked as down by onConnectionClosed/onHeartbeatStopped,
285
- // but connectToCluster() skips blocked addresses so without clearing the block
286
- // it will immediately fail with "Unable to connect to any address".
287
- // clearAllCredentials() already clears failedConnections inside ConnectionManager.
288
- this.logger.info('ClusterService', '🔓 SINGLE-NODE RESET: Unblocking all addresses for fresh reconnection...');
289
- this.downAddresses.clear();
290
- // Direct reconnection without waiting for member events
291
- this.logger.info('ClusterService', '🔄 SINGLE-NODE RESET: Attempting direct reconnection...');
292
- this.connectToCluster()
293
- .then(function () {
294
- _this.logger.info('ClusterService', '✅ Single-node cluster reset completed successfully');
295
- _this.logCurrentState();
296
- })
297
- .catch(function (error) {
298
- _this.logger.error('ClusterService', 'Single-node cluster reset failed', error);
299
- _this.logCurrentState();
300
- })
301
- .finally(function () {
302
- _this.failoverInProgress = false;
303
- });
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);
304
309
  };
305
310
  /**
306
311
  * Handles multi-node failover - preserves existing logic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celerispay/hazelcast-client",
3
- "version": "3.12.7-4",
3
+ "version": "3.12.7-5",
4
4
  "description": "Hazelcast - open source In-Memory Data Grid - client for NodeJS with critical connection failover fixes",
5
5
  "main": "./lib/index.js",
6
6
  "scripts": {