public void should_build_connections_per_service()
        {
            var serviceName = "products";

            var availableServices = new List <Service>
            {
                new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
                new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
            };

            _services        = availableServices;
            _leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);

            var response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);

            response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);

            response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);

            response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
        }
        public void should_handle_service_returning_to_available()
        {
            var serviceName = "products";

            var availableServices = new List <Service>
            {
                new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
                new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
            };

            _leastConnection = new LeastConnection(() => Task.FromResult(availableServices), serviceName);

            var hostAndPortOne = _leastConnection.Lease(_context).Result;

            hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
            var hostAndPortTwo = _leastConnection.Lease(_context).Result;

            hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2");
            _leastConnection.Release(hostAndPortOne.Data);
            _leastConnection.Release(hostAndPortTwo.Data);

            availableServices = new List <Service>
            {
                new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
            };

            hostAndPortOne = _leastConnection.Lease(_context).Result;
            hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
            hostAndPortTwo = _leastConnection.Lease(_context).Result;
            hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.1");
            _leastConnection.Release(hostAndPortOne.Data);
            _leastConnection.Release(hostAndPortTwo.Data);

            availableServices = new List <Service>
            {
                new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
                new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
            };

            hostAndPortOne = _leastConnection.Lease(_context).Result;
            hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
            hostAndPortTwo = _leastConnection.Lease(_context).Result;
            hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2");
            _leastConnection.Release(hostAndPortOne.Data);
            _leastConnection.Release(hostAndPortTwo.Data);
        }
        public void should_be_able_to_lease_and_release_concurrently()
        {
            var serviceName = "products";

            var availableServices = new List <Service>
            {
                new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
                new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
            };

            _services        = availableServices;
            _leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);

            var tasks = new Task[100];

            for (var i = 0; i < tasks.Length; i++)
            {
                tasks[i] = LeaseDelayAndRelease();
            }

            Task.WaitAll(tasks);
        }
        public void should_release_connection()
        {
            var serviceName = "products";

            var availableServices = new List <Service>
            {
                new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
                new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
            };

            _services        = availableServices;
            _leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);

            var response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);

            response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);

            response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);

            response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);

            //release this so 2 should have 1 connection and we should get 2 back as our next host and port
            _leastConnection.Release(availableServices[1].HostAndPort);

            response = _leastConnection.Lease(_context).Result;

            response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
        }
 private void GivenTheLoadBalancerStarts(List <Service> services, string serviceName)
 {
     _services        = services;
     _leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
 }