This implementation attempts to balance the connections over the cluster based on load. First it will try to reuse an existing connection. If no connections exist, or if all connection loads are larger than the newConnectionTreshold, a new connection is created at a node with an as low as possible load. If that fails (e.g. because the max amount of connections per node is reached), an attempt is made to select the least used connection from the least used node.
Inheritance: IConnectionStrategy
        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));
            }
        }