/// <summary> /// Initializes a new instance of the <see cref="CqlConnection" /> class. /// </summary> /// <param name="config"> The config. </param> public CqlConnection(ClusterConfig config) { //add the config to the list, or get an existing instance with the same parameters ClusterConfig c = Configs.GetOrAdd(config.ToString(), config); //get the cluster based on the instance Cluster cluster = Clusters.GetOrAdd(c, conf => new Cluster(conf)); //set the connection provider to the found cluster _cluster = cluster; }
/// <summary> /// Initializes a new instance of the <see cref="CqlConnection" /> class. /// </summary> /// <param name="connectionString"> The connection string. </param> public CqlConnection(string connectionString) { //get the cluster config, or add one if none exists ClusterConfig config = Configs.GetOrAdd(connectionString, connString => { //create new config var cc = new ClusterConfig(connString); //get if a similar already exists, or add it otherwise return(Configs.GetOrAdd(cc.ToString(), cc)); }); //fetch the cluster, or create one Cluster cluster = Clusters.GetOrAdd(config, conf => new Cluster(conf)); //set the connection provider to the cluster _cluster = cluster; }
/// <summary> /// Opens the cluster for queries. Contains actual implementation and will be called only once per cluster /// </summary> /// <returns></returns> /// <exception cref="CqlException">Cannot construct ring from provided seeds!</exception> private async Task OpenAsyncInternal(Logger logger) { logger.LogInfo("Opening Cluster with parameters: {0}", _config.ToString()); //try to connect to the seeds in turn foreach (IPAddress seedAddress in _config.NodeAddresses) { try { var seed = new Node(seedAddress, this); _nodes = await DiscoverNodesAsync(seed, logger).ConfigureAwait(false); } catch (Exception ex) { //seed not reachable, try next logger.LogWarning("Could not discover nodes via seed {0}: {1}", seedAddress, ex); } } if (_nodes == null) { var ex = new CqlException("Cannot construct ring from provided seeds!"); logger.LogCritical("Unable to setup Cluster based on given configuration: {0}", ex); throw ex; } logger.LogInfo("Nodes detected: " + string.Join(", ", _nodes.Select(n => n.Address))); //setup cluster connection strategy switch (_config.ConnectionStrategy) { case ConnectionStrategy.Balanced: _connectionSelector = new BalancedConnectionStrategy(_nodes, _config); break; case ConnectionStrategy.Random: _connectionSelector = new RandomConnectionStrategy(_nodes, _config); break; case ConnectionStrategy.Exclusive: _connectionSelector = new ExclusiveConnectionStrategy(_nodes, _config); break; case ConnectionStrategy.PartitionAware: _connectionSelector = new PartitionAwareConnectionStrategy(_nodes, _config); if (_config.DiscoveryScope != DiscoveryScope.Cluster || _config.DiscoveryScope != DiscoveryScope.DataCenter) { logger.LogWarning("PartitionAware connection strategy performs best if DiscoveryScope is set to cluster or datacenter"); } break; } //setup throttle int concurrent = _config.MaxConcurrentQueries <= 0 ? _nodes.Count * _config.MaxConnectionsPerNode * 256 : _config.MaxConcurrentQueries; logger.LogInfo("Cluster is configured to allow {0} parallel queries", concurrent); _throttle = new SemaphoreSlim(concurrent, concurrent); //setup prepared query cache _prepareResultCache = new ConcurrentDictionary <string, ConcurrentDictionary <IPAddress, ResultFrame> >(); //setup maintenance connection SetupMaintenanceConnection(logger); }