@celerispay/hazelcast-client 3.12.5-4 → 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.
- package/lib/invocation/ClientConnectionManager.d.ts +6 -1
- package/lib/invocation/ClientConnectionManager.js +32 -1
- package/lib/invocation/ClusterService.d.ts +8 -5
- package/lib/invocation/ClusterService.js +70 -13
- package/lib/proxy/ProxyManager.d.ts +4 -0
- package/lib/proxy/ProxyManager.js +77 -21
- package/package.json +1 -1
|
@@ -82,9 +82,14 @@ export declare class ClientConnectionManager extends EventEmitter {
|
|
|
82
82
|
destroyConnection(address: Address): void;
|
|
83
83
|
/**
|
|
84
84
|
* Cleans up all connections to a specific address during failover
|
|
85
|
-
* @param address
|
|
85
|
+
* @param address The address to cleanup
|
|
86
86
|
*/
|
|
87
87
|
cleanupConnectionsForFailover(address: Address): void;
|
|
88
|
+
/**
|
|
89
|
+
* Handles authentication errors by clearing failed connections and allowing retry
|
|
90
|
+
* @param address The address that had authentication issues
|
|
91
|
+
*/
|
|
92
|
+
handleAuthenticationError(address: Address): void;
|
|
88
93
|
shutdown(): void;
|
|
89
94
|
private triggerConnect(address, asOwner);
|
|
90
95
|
private connectTLSSocket(address, configOpts);
|
|
@@ -133,6 +133,16 @@ var ClientConnectionManager = /** @class */ (function (_super) {
|
|
|
133
133
|
_this.failedConnections.delete(address.toString());
|
|
134
134
|
return connection;
|
|
135
135
|
}).catch(function (error) {
|
|
136
|
+
// Check if it's an authentication error
|
|
137
|
+
var isAuthError = error.message && (error.message.includes('Invalid Credentials') ||
|
|
138
|
+
error.message.includes('authentication') ||
|
|
139
|
+
error.message.includes('credentials'));
|
|
140
|
+
if (isAuthError) {
|
|
141
|
+
_this.logger.error('ClientConnectionManager', "Authentication failed for " + address.toString() + ", not retrying: " + error.message);
|
|
142
|
+
// Handle authentication errors specially
|
|
143
|
+
_this.handleAuthenticationError(address);
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
136
146
|
if (retryCount < _this.maxConnectionRetries) {
|
|
137
147
|
_this.logger.warn('ClientConnectionManager', "Connection attempt " + (retryCount + 1) + " failed for " + address.toString() + ", retrying in " + _this.connectionRetryDelay + "ms");
|
|
138
148
|
return new Promise(function (resolve, reject) {
|
|
@@ -328,7 +338,7 @@ var ClientConnectionManager = /** @class */ (function (_super) {
|
|
|
328
338
|
};
|
|
329
339
|
/**
|
|
330
340
|
* Cleans up all connections to a specific address during failover
|
|
331
|
-
* @param address
|
|
341
|
+
* @param address The address to cleanup
|
|
332
342
|
*/
|
|
333
343
|
ClientConnectionManager.prototype.cleanupConnectionsForFailover = function (address) {
|
|
334
344
|
var addressStr = address.toString();
|
|
@@ -338,6 +348,27 @@ var ClientConnectionManager = /** @class */ (function (_super) {
|
|
|
338
348
|
// Remove from failed connections to allow reconnection after failover
|
|
339
349
|
this.failedConnections.delete(addressStr);
|
|
340
350
|
};
|
|
351
|
+
/**
|
|
352
|
+
* Handles authentication errors by clearing failed connections and allowing retry
|
|
353
|
+
* @param address The address that had authentication issues
|
|
354
|
+
*/
|
|
355
|
+
ClientConnectionManager.prototype.handleAuthenticationError = function (address) {
|
|
356
|
+
var addressStr = address.toString();
|
|
357
|
+
this.logger.warn('ClientConnectionManager', "Handling authentication error for " + addressStr);
|
|
358
|
+
// Clear from failed connections to allow retry with fresh credentials
|
|
359
|
+
this.failedConnections.delete(addressStr);
|
|
360
|
+
// Also clear any established connections to this address
|
|
361
|
+
if (this.establishedConnections.hasOwnProperty(addressStr)) {
|
|
362
|
+
this.logger.info('ClientConnectionManager', "Clearing established connection to " + addressStr + " due to auth error");
|
|
363
|
+
this.destroyConnection(address);
|
|
364
|
+
}
|
|
365
|
+
// Clear any pending connections
|
|
366
|
+
if (this.pendingConnections.hasOwnProperty(addressStr)) {
|
|
367
|
+
this.logger.info('ClientConnectionManager', "Clearing pending connection to " + addressStr + " due to auth error");
|
|
368
|
+
this.pendingConnections[addressStr].reject(new Error('Authentication error, connection cleared'));
|
|
369
|
+
delete this.pendingConnections[addressStr];
|
|
370
|
+
}
|
|
371
|
+
};
|
|
341
372
|
ClientConnectionManager.prototype.shutdown = function () {
|
|
342
373
|
if (this.connectionHealthCheckInterval) {
|
|
343
374
|
clearInterval(this.connectionHealthCheckInterval);
|
|
@@ -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.
|
|
@@ -87,6 +86,10 @@ export declare class ClusterService {
|
|
|
87
86
|
private onConnectionClosed(connection);
|
|
88
87
|
private onHeartbeatStopped(connection);
|
|
89
88
|
private triggerFailover();
|
|
89
|
+
/**
|
|
90
|
+
* Attempts emergency recovery when failover fails
|
|
91
|
+
*/
|
|
92
|
+
private attemptEmergencyRecovery();
|
|
90
93
|
private isAddressKnownDown(address);
|
|
91
94
|
private markAddressAsDown(address);
|
|
92
95
|
private getDownAddressesInfo();
|
|
@@ -50,7 +50,7 @@ var ClusterService = /** @class */ (function () {
|
|
|
50
50
|
this.lastFailoverAttempt = 0;
|
|
51
51
|
this.failoverCooldown = 5000; // 5 seconds cooldown between failover attempts
|
|
52
52
|
this.downAddresses = new Map(); // address -> timestamp when marked down
|
|
53
|
-
this.addressBlockDuration =
|
|
53
|
+
this.addressBlockDuration = 15000; // Reduced from 30000ms to 15000ms
|
|
54
54
|
this.reconnectionTask = null;
|
|
55
55
|
this.reconnectionInterval = 10000; // 10 seconds between reconnection attempts
|
|
56
56
|
this.client = client;
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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);
|
|
@@ -242,14 +251,50 @@ var ClusterService = /** @class */ (function () {
|
|
|
242
251
|
})
|
|
243
252
|
.catch(function (error) {
|
|
244
253
|
_this.logger.error('ClusterService', 'Failover failed', error);
|
|
254
|
+
// If failover fails, try to unblock at least one address to allow recovery
|
|
255
|
+
_this.attemptEmergencyRecovery();
|
|
245
256
|
_this.logCurrentState(); // Log state after failed failover
|
|
246
|
-
//
|
|
247
|
-
_this.client.shutdown();
|
|
257
|
+
// Don't shutdown immediately, give recovery a chance
|
|
248
258
|
})
|
|
249
259
|
.finally(function () {
|
|
250
260
|
_this.failoverInProgress = false;
|
|
251
261
|
});
|
|
252
262
|
};
|
|
263
|
+
/**
|
|
264
|
+
* Attempts emergency recovery when failover fails
|
|
265
|
+
*/
|
|
266
|
+
ClusterService.prototype.attemptEmergencyRecovery = function () {
|
|
267
|
+
var _this = this;
|
|
268
|
+
this.logger.warn('ClusterService', 'Attempting emergency recovery...');
|
|
269
|
+
// Unblock at least one address to allow recovery
|
|
270
|
+
if (this.downAddresses.size > 0) {
|
|
271
|
+
var firstBlockedAddress_1 = Array.from(this.downAddresses.keys())[0];
|
|
272
|
+
this.logger.info('ClusterService', "Emergency unblocking address " + firstBlockedAddress_1);
|
|
273
|
+
this.downAddresses.delete(firstBlockedAddress_1);
|
|
274
|
+
// Try to connect to the unblocked address
|
|
275
|
+
try {
|
|
276
|
+
var _a = firstBlockedAddress_1.split(':'), host = _a[0], portStr = _a[1];
|
|
277
|
+
var port = parseInt(portStr, 10);
|
|
278
|
+
if (host && !isNaN(port)) {
|
|
279
|
+
var address_1 = new Address(host, port);
|
|
280
|
+
this.logger.info('ClusterService', "Attempting emergency connection to " + firstBlockedAddress_1);
|
|
281
|
+
// Try to connect without blocking
|
|
282
|
+
this.client.getConnectionManager().getOrConnect(address_1, false)
|
|
283
|
+
.then(function (connection) {
|
|
284
|
+
_this.logger.info('ClusterService', "Emergency connection successful to " + firstBlockedAddress_1);
|
|
285
|
+
_this.evaluateOwnershipChange(address_1, connection);
|
|
286
|
+
_this.client.getPartitionService().refresh();
|
|
287
|
+
})
|
|
288
|
+
.catch(function (error) {
|
|
289
|
+
_this.logger.warn('ClusterService', "Emergency connection failed to " + firstBlockedAddress_1 + ":", error);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
this.logger.error('ClusterService', 'Error during emergency recovery:', error);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
253
298
|
ClusterService.prototype.isAddressKnownDown = function (address) {
|
|
254
299
|
var addressStr = address.toString();
|
|
255
300
|
var downTime = this.downAddresses.get(addressStr);
|
|
@@ -567,7 +612,7 @@ var ClusterService = /** @class */ (function () {
|
|
|
567
612
|
// Check if we're already trying to connect to this address
|
|
568
613
|
var connectionManager = this.client.getConnectionManager();
|
|
569
614
|
var establishedConnections = connectionManager.getEstablishedConnections();
|
|
570
|
-
var pendingConnections = Object.keys(connectionManager.getPendingConnections
|
|
615
|
+
var pendingConnections = Object.keys(connectionManager.getPendingConnections()).length;
|
|
571
616
|
if (pendingConnections > 0) {
|
|
572
617
|
this.logger.debug('ClusterService', "Already have pending connections, skipping reconnection to " + addressStr);
|
|
573
618
|
return;
|
|
@@ -651,6 +696,18 @@ var ClusterService = /** @class */ (function () {
|
|
|
651
696
|
var _this = this;
|
|
652
697
|
var addressStr = address.toString();
|
|
653
698
|
var now = Date.now();
|
|
699
|
+
// Don't block if we already have a healthy connection to this address
|
|
700
|
+
if (this.client.getConnectionManager().hasConnection(address)) {
|
|
701
|
+
this.logger.debug('ClusterService', "Not blocking " + addressStr + " as we have a healthy connection");
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
// Don't block if this would leave us with no available nodes
|
|
705
|
+
var totalDownAddresses = this.downAddresses.size;
|
|
706
|
+
var totalMembers = this.members.length;
|
|
707
|
+
if (totalDownAddresses >= totalMembers - 1) {
|
|
708
|
+
this.logger.warn('ClusterService', "Not blocking " + addressStr + " as it would leave us with no available nodes");
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
654
711
|
this.downAddresses.set(addressStr, now);
|
|
655
712
|
this.logger.warn('ClusterService', "Marked address " + addressStr + " as down, will be blocked for " + blockDuration + "ms");
|
|
656
713
|
// Schedule cleanup of this address after block duration
|
|
@@ -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
|
-
|
|
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
|
|
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()
|
|
153
|
-
var
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
171
|
-
|
|
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