Ejemplo n.º 1
0
        /// <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;
        }
Ejemplo n.º 2
0
        /// <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;
        }
Ejemplo n.º 3
0
        /// <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);
        }