/// <summary> /// Initializes a new instance of the <see cref="Connection" /> class. /// </summary> /// <param name="address">The address.</param> /// <param name="cluster">The cluster.</param> /// <param name="nr">The connection nr.</param> public Connection(IPAddress address, Cluster cluster, int nr) { _address = address; _cluster = cluster; _nr = nr; //setup support for multiple queries _availableQueryIds = new Queue<sbyte>(); for (sbyte i = 0; i < sbyte.MaxValue; i++) _availableQueryIds.Enqueue(i); _openRequests = new Dictionary<sbyte, TaskCompletionSource<Frame>>(); //setup locks _writeLock = new SemaphoreSlim(1); _frameSubmitLock = new SemaphoreSlim(sbyte.MaxValue); //setup state _activeRequests = 0; _load = 0; _connectionState = 0; _lastActivity = DateTime.Now.Ticks; Logger.Current.LogVerbose("{0} created", this); }
/// <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; }
public async Task BalancedStrategyLowTreshold() { using(ShimsContext.Create()) { //create cluster var config = new CqlConnectionStringBuilder {NewConnectionTreshold = 5}; var cluster = new Cluster(config); //create nodes var n = new Node(IPAddress.Parse("127.0.0.1"), cluster); var n2 = new Node(IPAddress.Parse("127.0.0.2"), cluster); var n3 = new Node(IPAddress.Parse("127.0.0.3"), cluster); var n4 = new Node(IPAddress.Parse("127.0.0.4"), cluster); var nodes = new Ring(); nodes.Update(new List<Node> {n, n2, n3, n4}, "RandomPartitioner", new Logger(new NullLogger(), LogLevel.None)); ShimAllConnections(); var logger = cluster.LoggerManager.GetLogger("BalancedStrategyLowTresholdTest"); IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config); const int nr = 8; for(int i = 0; i < nr; i++) { Connection connection; using(logger.ThreadBinding()) { connection = strategy.GetOrCreateConnection(ConnectionScope.Command, PartitionKey.None); } await connection.SendRequestAsync(new QueryFrame("", CqlConsistency.Any, null), logger, 10, CancellationToken.None); } Assert.AreEqual(nodes.Sum(nd => nd.ConnectionCount), nr); Assert.IsTrue(nodes.All(nd => nd.ConnectionCount == nr/4)); } }
public async Task BalancedStrategyManyRequestLowMaxConnections() { using (ShimsContext.Create()) { //create cluster var config = new ClusterConfig { NewConnectionTreshold = 5, MaxConnections = 6 }; var cluster = new Cluster(config); //create nodes var n1 = new Node(IPAddress.Parse("127.0.0.1"), cluster); var n2 = new Node(IPAddress.Parse("127.0.0.2"), cluster); var n3 = new Node(IPAddress.Parse("127.0.0.3"), cluster); var n4 = new Node(IPAddress.Parse("127.0.0.4"), cluster); var nodes = new Ring(new List<Node> { n1, n2, n3, n4 }, "RandomPartitioner"); ShimAllConnections(); var logger = cluster.LoggerManager.GetLogger("BalancedStrategyManyRequestLowMaxConnectionsTest"); IConnectionStrategy strategy = new BalancedConnectionStrategy(nodes, config); const int nr = 80; for (int i = 0; i < nr; i++) { Connection connection; using (logger.ThreadBinding()) connection = strategy.GetOrCreateConnection(PartitionKey.None); await connection.SendRequestAsync(new QueryFrame("", CqlConsistency.Any), logger, 10); } Assert.AreEqual(6, nodes.Sum(nd => nd.ConnectionCount)); Assert.IsTrue(nodes.All(n => n.Load == 80 * 10 / 4)); } }
/// <summary> /// Initializes a new instance of the <see cref="CqlConnection" /> class. /// </summary> /// <param name="cluster"> The cluster. </param> internal CqlConnection(Cluster cluster) { _cluster = cluster; }
/// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="disposing"> <c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources. </param> protected void Dispose(bool disposing) { if (disposing && (Interlocked.Exchange(ref _state, 2) == 1)) { if (_connection != null) { _cluster.ReturnConnection(_connection); _connection = null; } _cluster = null; } }
/// <summary> /// Releases the unmanaged resources used by the <see cref="T:System.ComponentModel.Component" /> and optionally releases /// the managed resources. /// </summary> /// <param name="disposing"> /// true to release both managed and unmanaged resources; false to release only unmanaged /// resources. /// </param> protected override void Dispose(bool disposing) { if(!_disposed && disposing) { if(State == ConnectionState.Connecting) { try { //wait until open is finished (may return immediatly) _openTask.Wait(); } // ReSharper disable EmptyGeneralCatchClause catch { //ignore here } // ReSharper restore EmptyGeneralCatchClause } if(State == ConnectionState.Open) { //return connection if any if(_connection != null) { Cluster.ConnectionStrategy.ReturnConnection(_connection, ConnectionScope.Connection); _connection = null; } } //clear cluster _cluster = null; //clear database _database = string.Empty; //dispose any remaining cancel tokens if(_userCancelTokenSource != null) { _userCancelTokenSource.Dispose(); _userCancelTokenSource = null; } if(_openCancellationTokenSource != null) { _openCancellationTokenSource.Dispose(); _openCancellationTokenSource = null; } _disposed = true; } base.Dispose(disposing); }
/// <summary> /// Closes the connection to the database. This is the preferred method of closing any open connection. /// </summary> public override void Close() { if(State != ConnectionState.Closed) { var logger = LoggerManager.GetLogger("CqlSharp.CqlConnection.Close"); try { //wait until open is finished (may return immediatly) _openTask.Wait(); } catch(Exception ex) { logger.LogVerbose("Closing connection that was not opened correctly: ", ex); } //return connection if any if(_connection != null) { Cluster.ConnectionStrategy.ReturnConnection(_connection, ConnectionScope.Connection); _connection = null; } //clear cluster _cluster = null; //clear database _database = string.Empty; //clear open task, such that open can be run again _openTask = null; } }