/// <summary>
        /// Get storage connection
        /// </summary>
        public IConnection GetStorageConnection(ConnectionAddress connectionAddress)
        {
            if (!_storageConnectionPools.TryGetValue(connectionAddress, out IConnectionPool connectionPool))
            {
                lock (_storageSyncObject)
                {
                    if (!_storageConnectionPools.TryGetValue(connectionAddress, out connectionPool))
                    {
                        var connectionPoolOption = new ConnectionPoolOption()
                        {
                            ConnectionAddress          = connectionAddress,
                            ConnectionLifeTime         = _configuration.ConnectionLifeTime,
                            ConnectionConcurrentThread = _configuration.ConnectionConcurrentThread,
                            MaxConnection = _configuration.StorageMaxConnection,
                            ScanTimeoutConnectionInterval = _configuration.ScanTimeoutConnectionInterval
                        };

                        connectionPool = _connectionPoolFactory.CreateConnectionPool(connectionPoolOption);
                        if (!_storageConnectionPools.TryAdd(connectionAddress, connectionPool))
                        {
                            _logger.LogWarning("Fail to add connection pool to storage connection pools! ConnectionAddress:{0}", connectionAddress);
                        }
                    }
                }
            }

            if (connectionPool == null)
            {
                throw new ArgumentException($"Can't find any connection pools for {connectionAddress}");
            }
            return(connectionPool.GetConnection());
        }
        public void GetConnection_Return_Test()
        {
            var connectionPoolOption = new ConnectionPoolOption()
            {
                ConnectionAddress          = new ConnectionAddress("192.168.0.6", 22122),
                ConnectionConcurrentThread = 1,
                ConnectionLifeTime         = 3600,
                MaxConnection = 1,
                ScanTimeoutConnectionInterval = 500
            };

            var mockConnectionBuilder = new Mock <IConnectionBuilder>();
            var mockConnection        = new Mock <IConnection>();

            mockConnection.Setup(x => x.Id)
            .Returns("1234567890");
            mockConnection.Setup(x => x.ConnectionAddress)
            .Returns(connectionPoolOption.ConnectionAddress);

            mockConnectionBuilder.Setup(x => x.CreateConnection(connectionPoolOption.ConnectionAddress))
            .Returns(mockConnection.Object);


            IConnectionPool connectionPool = new DefaultConnectionPool(_mockLogger.Object, connectionPoolOption, mockConnectionBuilder.Object);

            var connection = connectionPool.GetConnection();

            Assert.NotEmpty(connectionPool.Name);
            Assert.Equal("192.168.0.6", connection.ConnectionAddress.IPAddress);
            Assert.Equal(22122, connection.ConnectionAddress.Port);
            Assert.Equal("1234567890", connection.Id);
            mockConnectionBuilder.Verify(x => x.CreateConnection(connectionPoolOption.ConnectionAddress), Times.Once);

            Task.Run(() =>
            {
                Task.Delay(200);
                connectionPool.Return(connection);
            });
            var connection2 = connectionPool.GetConnection();

            mockConnectionBuilder.Verify(x => x.CreateConnection(connectionPoolOption.ConnectionAddress), Times.Once);

            Assert.Equal(connection.ConnectionAddress, connection2.ConnectionAddress);
            Assert.Equal(connection.Id, connection2.Id);
        }
        /// <summary>
        /// Get tracker connection
        /// </summary>
        public IConnection GetTrackerConnection()
        {
            var rd                = new Random();
            var index             = rd.Next(_configuration.Trackers.Count);
            var tracker           = _configuration.Trackers[index];
            var connectionAddress = new ConnectionAddress(tracker.IPAddress, tracker.Port);

            if (!_trackerConnectionPools.TryGetValue(connectionAddress, out IConnectionPool connectionPool))
            {
                lock (_trackerSyncObject)
                {
                    if (!_trackerConnectionPools.TryGetValue(connectionAddress, out connectionPool))
                    {
                        var connectionPoolOption = new ConnectionPoolOption()
                        {
                            ConnectionAddress          = connectionAddress,
                            ConnectionLifeTime         = _configuration.ConnectionLifeTime,
                            ConnectionConcurrentThread = _configuration.ConnectionConcurrentThread,
                            MaxConnection = _configuration.TrackerMaxConnection,
                            ScanTimeoutConnectionInterval = _configuration.ScanTimeoutConnectionInterval
                        };

                        connectionPool = _connectionPoolFactory.CreateConnectionPool(connectionPoolOption);
                        if (!_trackerConnectionPools.TryAdd(connectionAddress, connectionPool))
                        {
                            _logger.LogWarning("Fail to add connection pool to tracker connection pools! ConnectionAddress:{0}", connectionAddress);
                        }
                        else
                        {
                            connectionPool.Start();
                        }
                    }
                }
            }

            return(connectionPool.GetConnection());
        }