@celerispay/hazelcast-client 3.12.5-5 → 3.12.5-6

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.
@@ -47,6 +47,10 @@ export declare class ClusterService {
47
47
  */
48
48
  connectToCluster(): Promise<void>;
49
49
  getPossibleMemberAddresses(): Promise<string[]>;
50
+ /**
51
+ * Returns the owner connection if available
52
+ */
53
+ getOwnerConnection(): ClientConnection | null;
50
54
  /**
51
55
  * Returns the list of members in the cluster.
52
56
  * @returns
@@ -63,11 +67,6 @@ export declare class ClusterService {
63
67
  * @returns {ClientInfo}
64
68
  */
65
69
  getClientInfo(): ClientInfo;
66
- /**
67
- * Returns the connection associated with owner node of this client.
68
- * @returns {ClientConnection}
69
- */
70
- getOwnerConnection(): ClientConnection;
71
70
  /**
72
71
  * Adds MembershipListener to listen for membership updates. There is no check for duplicate registrations,
73
72
  * so if you register the listener twice, it will get events twice.
@@ -103,6 +103,12 @@ var ClusterService = /** @class */ (function () {
103
103
  return Array.from(new Set(Array.from(addresses).concat(Array.from(providerAddresses))));
104
104
  });
105
105
  };
106
+ /**
107
+ * Returns the owner connection if available
108
+ */
109
+ ClusterService.prototype.getOwnerConnection = function () {
110
+ return this.ownerConnection;
111
+ };
106
112
  /**
107
113
  * Returns the list of members in the cluster.
108
114
  * @returns
@@ -144,16 +150,15 @@ var ClusterService = /** @class */ (function () {
144
150
  ClusterService.prototype.getClientInfo = function () {
145
151
  var info = new ClientInfo_1.ClientInfo();
146
152
  info.uuid = this.uuid;
147
- info.localAddress = this.getOwnerConnection().getLocalAddress();
153
+ var ownerConnection = this.getOwnerConnection();
154
+ if (ownerConnection) {
155
+ info.localAddress = ownerConnection.getLocalAddress();
156
+ }
157
+ else {
158
+ info.localAddress = null;
159
+ }
148
160
  return info;
149
161
  };
150
- /**
151
- * Returns the connection associated with owner node of this client.
152
- * @returns {ClientConnection}
153
- */
154
- ClusterService.prototype.getOwnerConnection = function () {
155
- return this.ownerConnection;
156
- };
157
162
  /**
158
163
  * Adds MembershipListener to listen for membership updates. There is no check for duplicate registrations,
159
164
  * so if you register the listener twice, it will get events twice.
@@ -185,7 +190,11 @@ var ClusterService = /** @class */ (function () {
185
190
  var handleAttributeChange = _this.handleMemberAttributeChange.bind(_this);
186
191
  ClientAddMembershipListenerCodec_1.ClientAddMembershipListenerCodec.handle(m, handleMember, handleMemberList, handleAttributeChange, null);
187
192
  };
188
- return this.client.getInvocationService().invokeOnConnection(this.getOwnerConnection(), request, handler)
193
+ var ownerConnection = this.getOwnerConnection();
194
+ if (!ownerConnection) {
195
+ return Promise.reject(new Error('Cannot initialize membership listener: no owner connection available'));
196
+ }
197
+ return this.client.getInvocationService().invokeOnConnection(ownerConnection, request, handler)
189
198
  .then(function (resp) {
190
199
  _this.logger.trace('ClusterService', 'Registered listener with id '
191
200
  + ClientAddMembershipListenerCodec_1.ClientAddMembershipListenerCodec.decodeResponse(resp).response);
@@ -603,7 +612,7 @@ var ClusterService = /** @class */ (function () {
603
612
  // Check if we're already trying to connect to this address
604
613
  var connectionManager = this.client.getConnectionManager();
605
614
  var establishedConnections = connectionManager.getEstablishedConnections();
606
- var pendingConnections = Object.keys(connectionManager.getPendingConnections || {}).length;
615
+ var pendingConnections = Object.keys(connectionManager.getPendingConnections()).length;
607
616
  if (pendingConnections > 0) {
608
617
  this.logger.debug('ClusterService', "Already have pending connections, skipping reconnection to " + addressStr);
609
618
  return;
@@ -37,4 +37,8 @@ export declare class ProxyManager {
37
37
  private findNextAddress();
38
38
  private initializeProxy(proxyObject, promise, deadline);
39
39
  private createDistributedObjectListener();
40
+ /**
41
+ * Checks if the cluster is healthy enough to create proxies
42
+ */
43
+ private isClusterHealthy();
40
44
  }
@@ -15,6 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ var Promise = require("bluebird");
18
19
  var ClientAddDistributedObjectListenerCodec_1 = require("../codec/ClientAddDistributedObjectListenerCodec");
19
20
  var ClientCreateProxyCodec_1 = require("../codec/ClientCreateProxyCodec");
20
21
  var ClientDestroyProxyCodec_1 = require("../codec/ClientDestroyProxyCodec");
@@ -68,6 +69,12 @@ var ProxyManager = /** @class */ (function () {
68
69
  if (this.proxies[fullName]) {
69
70
  return this.proxies[fullName];
70
71
  }
72
+ // Check if cluster is healthy before creating proxy
73
+ if (!this.isClusterHealthy()) {
74
+ var error = new Error('Cluster is not healthy, cannot create proxy for ' + name);
75
+ this.logger.error('ProxyManager', error.message);
76
+ return Promise.reject(error);
77
+ }
71
78
  var deferred = Util_1.DeferredPromise();
72
79
  var newProxy;
73
80
  if (serviceName === ProxyManager.MAP_SERVICE && this.client.getConfig().getNearCacheConfig(name)) {
@@ -91,6 +98,9 @@ var ProxyManager = /** @class */ (function () {
91
98
  if (createAtServer) {
92
99
  this.createProxy(newProxy).then(function () {
93
100
  deferred.resolve(newProxy);
101
+ }).catch(function (error) {
102
+ _this.logger.error('ProxyManager', 'Failed to create proxy for ' + name + ': ' + error);
103
+ deferred.reject(error);
94
104
  });
95
105
  }
96
106
  this.proxies[fullName] = deferred.promise;
@@ -130,46 +140,68 @@ var ProxyManager = /** @class */ (function () {
130
140
  };
131
141
  ProxyManager.prototype.findNextAddress = function () {
132
142
  var members = this.client.getClusterService().getMembers();
143
+ // If no members available, return null but log the issue
144
+ if (!members || members.length === 0) {
145
+ this.logger.warn('ProxyManager', 'No cluster members available for proxy creation');
146
+ return null;
147
+ }
133
148
  var liteMember = null;
149
+ var dataMember = null;
134
150
  for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
135
151
  var member = members_1[_i];
136
152
  if (member != null && member.isLiteMember === false) {
137
- return member.address;
153
+ dataMember = member;
154
+ break; // Prefer data members
138
155
  }
139
156
  else if (member != null && member.isLiteMember) {
140
157
  liteMember = member;
141
158
  }
142
159
  }
143
- if (liteMember != null) {
160
+ // Return data member if available, otherwise lite member, otherwise null
161
+ if (dataMember != null) {
162
+ return dataMember.address;
163
+ }
164
+ else if (liteMember != null) {
144
165
  return liteMember.address;
145
166
  }
146
167
  else {
168
+ this.logger.warn('ProxyManager', 'No valid members found for proxy creation');
147
169
  return null;
148
170
  }
149
171
  };
150
172
  ProxyManager.prototype.initializeProxy = function (proxyObject, promise, deadline) {
151
173
  var _this = this;
152
- if (Date.now() <= deadline) {
153
- var address = this.findNextAddress();
154
- var request = ClientCreateProxyCodec_1.ClientCreateProxyCodec.encodeRequest(proxyObject.getName(), proxyObject.getServiceName(), address);
155
- var invocation = new InvocationService_1.Invocation(this.client, request);
156
- invocation.address = address;
157
- this.client.getInvocationService().invoke(invocation).then(function (response) {
158
- promise.resolve(response);
159
- }).catch(function (error) {
160
- if (_this.isRetryable(error)) {
161
- _this.logger.warn('ProxyManager', 'Create proxy request for ' + proxyObject.getName() +
162
- ' failed. Retrying in ' + _this.invocationRetryPauseMillis + 'ms. ' + error);
163
- setTimeout(_this.initializeProxy.bind(_this, proxyObject, promise, deadline), _this.invocationRetryPauseMillis);
164
- }
165
- else {
166
- _this.logger.warn('ProxyManager', 'Create proxy request for ' + proxyObject.getName() + ' failed ' + error);
167
- }
168
- });
174
+ if (Date.now() > deadline) {
175
+ var error = new Error('Create proxy request timed-out for ' + proxyObject.getName());
176
+ this.logger.error('ProxyManager', error.message);
177
+ promise.reject(error);
178
+ return;
169
179
  }
170
- else {
171
- promise.reject('Create proxy request timed-out for ' + proxyObject.getName());
180
+ var address = this.findNextAddress();
181
+ if (!address) {
182
+ var error = new Error('No cluster members available for proxy creation: ' + proxyObject.getName());
183
+ this.logger.error('ProxyManager', error.message);
184
+ promise.reject(error);
185
+ return;
172
186
  }
187
+ var request = ClientCreateProxyCodec_1.ClientCreateProxyCodec.encodeRequest(proxyObject.getName(), proxyObject.getServiceName(), address);
188
+ var invocation = new InvocationService_1.Invocation(this.client, request);
189
+ invocation.address = address;
190
+ this.client.getInvocationService().invoke(invocation).then(function (response) {
191
+ promise.resolve(response);
192
+ }).catch(function (error) {
193
+ if (_this.isRetryable(error)) {
194
+ _this.logger.warn('ProxyManager', 'Create proxy request for ' + proxyObject.getName() +
195
+ ' failed. Retrying in ' + _this.invocationRetryPauseMillis + 'ms. ' + error);
196
+ setTimeout(function () {
197
+ _this.initializeProxy(proxyObject, promise, deadline);
198
+ }, _this.invocationRetryPauseMillis);
199
+ }
200
+ else {
201
+ _this.logger.error('ProxyManager', 'Create proxy request for ' + proxyObject.getName() + ' failed ' + error);
202
+ promise.reject(error);
203
+ }
204
+ });
173
205
  };
174
206
  ProxyManager.prototype.createDistributedObjectListener = function () {
175
207
  return {
@@ -184,6 +216,30 @@ var ProxyManager = /** @class */ (function () {
184
216
  },
185
217
  };
186
218
  };
219
+ /**
220
+ * Checks if the cluster is healthy enough to create proxies
221
+ */
222
+ ProxyManager.prototype.isClusterHealthy = function () {
223
+ var members = this.client.getClusterService().getMembers();
224
+ var hasMembers = members && members.length > 0;
225
+ if (!hasMembers) {
226
+ this.logger.warn('ProxyManager', 'No cluster members available');
227
+ return false;
228
+ }
229
+ // Check if we have at least one data member
230
+ var hasDataMember = members.some(function (member) { return member && !member.isLiteMember; });
231
+ if (!hasDataMember) {
232
+ this.logger.warn('ProxyManager', 'No data members available in cluster');
233
+ return false;
234
+ }
235
+ // Check if we have an owner connection
236
+ var ownerConnection = this.client.getClusterService().getOwnerConnection();
237
+ if (!ownerConnection || !ownerConnection.isHealthy()) {
238
+ this.logger.warn('ProxyManager', 'No healthy owner connection available');
239
+ return false;
240
+ }
241
+ return true;
242
+ };
187
243
  ProxyManager.MAP_SERVICE = 'hz:impl:mapService';
188
244
  ProxyManager.SET_SERVICE = 'hz:impl:setService';
189
245
  ProxyManager.LOCK_SERVICE = 'hz:impl:lockService';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celerispay/hazelcast-client",
3
- "version": "3.12.5-5",
3
+ "version": "3.12.5-6",
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": {