Implemented connection to cluster using gossip seeds

This commit is contained in:
Nicolas Dextraze
2016-10-15 15:41:25 -07:00
parent 4ea996781f
commit dd1302f641
10 changed files with 351 additions and 303 deletions

View File

@ -1,6 +1,8 @@
var EventStoreNodeConnection = require('./eventStoreNodeConnection');
var StaticEndpointDiscoverer = require('./core/staticEndpointDiscoverer');
var ClusterDnsEndPointDiscoverer = require('./core/clusterDnsEndPointDiscoverer');
var NoopLogger = require('./common/log/noopLogger');
var ensure = require('./common/utils/ensure');
var defaultConnectionSettings = {
log: new NoopLogger(),
@ -25,7 +27,13 @@ var defaultConnectionSettings = {
failOnNoServerResponse: false,
heartbeatInterval: 750,
heartbeatTimeout: 1500,
clientConnectionTimeout: 1000
clientConnectionTimeout: 1000,
// Cluster Settings
clusterDns: '',
maxDiscoverAttemps: 10,
externalGossipPort: 0,
gossipTimeout: 1000
};
@ -40,24 +48,63 @@ function merge(a,b) {
return c;
}
function createFromTcpEndpoint(settings, tcpEndpoint, connectionName) {
if (!tcpEndpoint.port || !tcpEndpoint.hostname) throw new TypeError('endPoint object must have hostname and port properties.');
var mergedSettings = merge(defaultConnectionSettings, settings || {});
var endpointDiscoverer = new StaticEndpointDiscoverer(tcpEndpoint, settings.useSslConnection);
return new EventStoreNodeConnection(mergedSettings, null, endpointDiscoverer, connectionName || null);
}
function createFromStringEndpoint(settings, endPoint, connectionName) {
var m = endPoint.match(/^(tcp|discover):\/\/([^:]):?(\d+)?$/);
if (!m) throw new Error('endPoint string must be tcp://hostname[:port] or discover://dns[:port]');
var scheme = m[1];
var hostname = m[2];
var port = m[3] ? parseInt(m[3]) : 1113;
if (scheme === 'tcp') {
var tcpEndpoint = {
hostname: hostname,
port: port
};
return createFromTcpEndpoint(settings, tcpEndpoint, connectionName);
}
if (scheme === 'discover') {
throw new Error('Not implemented.');
}
throw new Error('Invalid scheme for endPoint: ' + scheme);
}
function createFromGossipSeeds(connectionSettings, gossipSeeds, connectionName) {
ensure.notNull(connectionSettings, "connectionSettings");
ensure.notNull(gossipSeeds, "gossipSeeds");
var mergedSettings = merge(defaultConnectionSettings, connectionSettings || {});
var clusterSettings = {
clusterDns: '',
gossipSeeds: gossipSeeds,
externalGossipPort: 0,
maxDiscoverAttempts: mergedSettings.maxDiscoverAttempts,
gossipTimeout: mergedSettings.gossipTimeout
};
var endPointDiscoverer = new ClusterDnsEndPointDiscoverer(connectionSettings.log,
clusterSettings.clusterDns,
clusterSettings.maxDiscoverAttempts,
clusterSettings.externalGossipPort,
clusterSettings.gossipSeeds,
clusterSettings.gossipTimeout
);
return new EventStoreNodeConnection(mergedSettings, clusterSettings, endPointDiscoverer, connectionName);
}
/**
* Create an EventStore connection
* @param {object} settings
* @param {string|object} endPoint
* @param {string|object|array} endPointOrGossipSeeds
* @param {string} [connectionName]
* @returns {EventStoreNodeConnection}
*/
module.exports.create = function(settings, endPoint, connectionName) {
if (typeof endPoint === 'object') {
var mergedSettings = merge(defaultConnectionSettings, settings || {});
var endpointDiscoverer = new StaticEndpointDiscoverer(endPoint, settings.useSslConnection);
return new EventStoreNodeConnection(mergedSettings, endpointDiscoverer, connectionName || null);
}
if (typeof endPoint === 'string') {
//TODO: tcpEndpoint represented as tcp://hostname:port
//TODO: cluster discovery via dns represented as discover://dns:?port
throw new Error('Not implemented.');
}
//TODO: cluster discovery via gossip seeds in settings
throw new Error('Not implemented.');
module.exports.create = function(settings, endPointOrGossipSeeds, connectionName) {
if (Array.isArray(endPointOrGossipSeeds)) return createFromGossipSeeds(settings, endPointOrGossipSeeds, connectionName);
if (typeof endPointOrGossipSeeds === 'object') return createFromTcpEndpoint(settings, endPointOrGossipSeeds, connectionName);
if (typeof endPointOrGossipSeeds === 'string') return createFromStringEndpoint(settings, endPointOrGossipSeeds, connectionName);
throw new TypeError('endPointOrGossipSeeds must be an object, a string or an array.');
};