UNPKG

hazelcast-client

Version:

Hazelcast - open source In-Memory Data Grid - client for NodeJS

249 lines 10.5 kB
"use strict"; /* * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var Promise = require("bluebird"); var ClientAddMembershipListenerCodec_1 = require("../codec/ClientAddMembershipListenerCodec"); var LoggingService_1 = require("../logging/LoggingService"); var events_1 = require("events"); var ClientInfo_1 = require("../ClientInfo"); var Address = require("../Address"); var HazelcastError_1 = require("../HazelcastError"); var assert = require("assert"); var MEMBER_ADDED = 1; var MEMBER_REMOVED = 2; var EMIT_MEMBER_ADDED = 'memberAdded'; var EMIT_MEMBER_REMOVED = 'memberRemoved'; var EMIT_ATTRIBUTE_CHANGE = 'memberAttributeChange'; var ATTRIBUTE_CHANGE = { 1: 'put', 2: 'remove' }; /** * Manages the relationship of this client with the cluster. */ var ClusterService = /** @class */ (function (_super) { __extends(ClusterService, _super); function ClusterService(client) { var _this = _super.call(this) || this; /** * The unique identifier of the owner server node. This node is responsible for resource cleanup */ _this.ownerUuid = null; /** * The unique identifier of this client instance. Assigned by owner node on authentication */ _this.uuid = null; _this.knownAddresses = []; _this.members = []; _this.logger = LoggingService_1.LoggingService.getLoggingService(); _this.client = client; _this.members = []; return _this; } /** * Starts cluster service. * @returns */ ClusterService.prototype.start = function () { this.initHeartbeatListener(); this.initConnectionListener(); return this.connectToCluster(); }; /** * Connects to cluster. It uses the addresses provided in the configuration. * @returns */ ClusterService.prototype.connectToCluster = function () { var _this = this; if (this.members.length > 0) { this.knownAddresses = new Array(); this.members.forEach(function (member) { _this.knownAddresses.push(member.address); }); } else { this.knownAddresses = this.client.getConfig().networkConfig.addresses; } if (this.knownAddresses.length === 0) { this.knownAddresses.push(new Address('127.0.0.1', 5701)); } var attemptLimit = this.client.getConfig().networkConfig.connectionAttemptLimit; var attemptPeriod = this.client.getConfig().networkConfig.connectionAttemptPeriod; return this.tryAddresses(0, attemptLimit, attemptPeriod); }; /** * Returns the list of members in the cluster. * @returns */ ClusterService.prototype.getMembers = function (selector) { if (selector === undefined) { return this.members; } else { var members_1 = []; this.members.forEach(function (member) { if (selector.select(member)) { members_1.push(member); } }); return members_1; } }; /** * Returns the number of nodes in cluster. * @returns {number} */ ClusterService.prototype.getSize = function () { return this.members.length; }; /** * Returns information about this client. * @returns {ClientInfo} */ ClusterService.prototype.getClientInfo = function () { var info = new ClientInfo_1.ClientInfo(); info.uuid = this.uuid; info.localAddress = this.getOwnerConnection().getLocalAddress(); return info; }; ClusterService.prototype.initHeartbeatListener = function () { this.client.getHeartbeat().addListener({ onHeartbeatStopped: this.onHeartbeatStopped.bind(this) }); }; ClusterService.prototype.initConnectionListener = function () { this.client.getConnectionManager().on('connectionClosed', this.onConnectionClosed.bind(this)); }; ClusterService.prototype.onConnectionClosed = function (connection) { this.logger.warn('ClusterService', 'Connection closed to ' + connection.toString()); if (connection.isAuthenticatedAsOwner()) { this.ownerConnection = null; this.connectToCluster().catch(this.client.shutdown.bind(this.client)); } }; ClusterService.prototype.onHeartbeatStopped = function (connection) { this.logger.warn('ClusterService', connection.toString() + ' stopped heartbeating.'); if (connection.isAuthenticatedAsOwner()) { this.client.getConnectionManager().destroyConnection(connection.getAddress()); } }; ClusterService.prototype.tryAddresses = function (index, attemptLimit, attemptPeriod) { var _this = this; if (this.knownAddresses.length <= index) { attemptLimit = attemptLimit - 1; if (attemptLimit === 0) { var error = new HazelcastError_1.IllegalStateError('Unable to connect to any of the following addresses: ' + this.knownAddresses.map(function (element) { return element.toString(); }).join(', ')); return Promise.reject(error); } else { var deferred_1 = Promise.defer(); setTimeout(function () { _this.tryAddresses(0, attemptLimit, attemptPeriod).then(function () { deferred_1.resolve(); }).catch(function (e) { deferred_1.reject(e); }); }, attemptPeriod); return deferred_1.promise; } } else { var currentAddress = this.knownAddresses[index]; return this.client.getConnectionManager().getOrConnect(currentAddress, true).then(function (connection) { if (connection == null) { throw new Error('Could not connect to ' + currentAddress.toString()); } connection.setAuthneticatedAsOwner(true); _this.ownerConnection = connection; return _this.initMemberShipListener(); }).catch(function (e) { _this.logger.warn('ClusterService', e); return _this.tryAddresses(index + 1, attemptLimit, attemptPeriod); }); } }; /** * Returns the connection associated with owner node of this client. * @returns {ClientConnection} */ ClusterService.prototype.getOwnerConnection = function () { return this.ownerConnection; }; ClusterService.prototype.initMemberShipListener = function () { var _this = this; var request = ClientAddMembershipListenerCodec_1.ClientAddMembershipListenerCodec.encodeRequest(false); var handler = function (m) { var handleMember = _this.handleMember.bind(_this); var handleMemberList = _this.handleMemberList.bind(_this); var handleAttributeChange = _this.handleMemberAttributeChange.bind(_this); ClientAddMembershipListenerCodec_1.ClientAddMembershipListenerCodec.handle(m, handleMember, handleMemberList, handleAttributeChange, null); }; return this.client.getInvocationService().invokeOnConnection(this.getOwnerConnection(), request, handler) .then(function (resp) { _this.logger.trace('ClusterService', 'Registered listener with id ' + ClientAddMembershipListenerCodec_1.ClientAddMembershipListenerCodec.decodeResponse(resp).response); }); }; ClusterService.prototype.handleMember = function (member, eventType) { if (eventType === MEMBER_ADDED) { this.logger.info('ClusterService', member.toString() + ' added to cluster'); this.memberAdded(member); } else if (eventType === MEMBER_REMOVED) { this.logger.info('ClusterService', member.toString() + ' removed from cluster'); this.memberRemoved(member); } this.client.getPartitionService().refresh(); }; ClusterService.prototype.handleMemberList = function (members) { this.members = members; this.client.getPartitionService().refresh(); this.logger.info('ClusterService', 'Members received.', this.members); }; ClusterService.prototype.handleMemberAttributeChange = function (uuid, key, operationType, value) { this.emit(EMIT_ATTRIBUTE_CHANGE, uuid, key, ATTRIBUTE_CHANGE[operationType], value); }; ClusterService.prototype.memberAdded = function (member) { this.members.push(member); this.emit(EMIT_MEMBER_ADDED, member); }; ClusterService.prototype.memberRemoved = function (member) { var memberIndex = this.members.findIndex(member.equals, member); if (memberIndex !== -1) { var removedMemberList = this.members.splice(memberIndex, 1); assert(removedMemberList.length === 1); } this.client.getConnectionManager().destroyConnection(member.address); this.emit(EMIT_MEMBER_REMOVED, member); }; return ClusterService; }(events_1.EventEmitter)); exports.ClusterService = ClusterService; //# sourceMappingURL=ClusterService.js.map