/// <summary>
        /// Executes an operation for a given key.
        /// </summary>
        /// <typeparam name="T">The Type T of the value being stored or retrieved.</typeparam>
        /// <param name="operation">The <see cref="IOperation{T}" /> being executed.</param>
        /// <returns>
        /// An <see cref="IOperationResult{T}" /> representing the result of operation.
        /// </returns>
        public IOperationResult <T> Execute <T>(IOperation <T> operation)
        {
            //Get the buffer and a connection
            var request    = operation.Write();
            var connection = _connectionPool.Acquire();

            byte[] response;
            try
            {
                //A new connection will have to be authenticated
                if (!connection.IsAuthenticated)
                {
                    Authenticate(connection);
                }

                //Send the request buffer and release the connection
                response = connection.Send(request);
            }
            finally
            {
                _connectionPool.Release(connection);
            }

            //Read the response and return the completed operation
            if (response != null)
            {
                operation.Read(response, 0, response.Length);
            }
            return(operation.GetResult());
        }
예제 #2
0
        /// <summary>
        /// Executes an operation for a given key.
        /// </summary>
        /// <param name="operation">The <see cref="IOperation" /> being executed.</param>
        /// <returns>
        /// An <see cref="IOperationResult" /> representing the result of operation.
        /// </returns>
        public IOperationResult Execute(IOperation operation)
        {
            //Get the buffer and a connection
            var request    = operation.Write();
            var connection = _connectionPool.Acquire();

            Log.Trace("Using conn {0} on {1}", connection.Identity, connection.EndPoint);
            byte[] response = null;
            try
            {
                //A new connection will have to check for server features
                if (_enableServerFeatures)
                {
                    lock (_syncObj)
                    {
                        EnableServerFeatures(connection);
                        _enableServerFeatures = false;
                    }
                }

                //Send the request buffer and release the connection
                response = connection.Send(request);
            }
            catch (SocketException e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.TransportFailure);
            }
            catch (AuthenticationException e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.AuthenticationError);
            }
            catch (RemoteHostTimeoutException e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.TransportFailure);

                //this almost always will be a server offline or service down
                _connectionPool.Owner.MarkDead();
            }
            catch (Exception e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.ClientFailure);
            }
            finally
            {
                _connectionPool.Release(connection);
            }

            operation.Read(response, _errorMap);
            return(operation.GetResult());
        }
        public IOperationResult <T> Execute <T>(IOperation <T> operation)
        {
            var request = operation.Write();

            byte[] response = null;

            try
            {
                //A new connection will have to be authenticated
                if (!_connection.IsAuthenticated)
                {
                    //if two (or more) threads compete for auth, the first will succeed
                    //and subsequent threads will fail. This keeps that from happening.
                    lock (_syncObj)
                    {
                        Authenticate(_connection);
                        EnableEnhancedDurability(_connection);
                    }
                }

                response = _connection.Send(request);
            }
            catch (SocketException e)
            {
                Log.DebugFormat("Endpoint: {0} - {1} {2}", EndPoint, _identity, e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.TransportFailure);
            }
            catch (AuthenticationException e)
            {
                Log.DebugFormat("Endpoint: {0} - {1} {2}", EndPoint, _identity, e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.AuthenticationError);
            }
            catch (Exception e)
            {
                Log.DebugFormat("Endpoint: {0} - {1} {2}", EndPoint, _identity, e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.ClientFailure);
            }
            finally
            {
                //need better error handling
                if (_connection.IsDead)
                {
                    _connectionPool.Release(_connection);
                    _connection = _connectionPool.Acquire();
                }
            }

            //Read the response and return the completed operation
            if (response != null && response.Length > 0)
            {
                operation.Read(response, 0, response.Length);
            }
            return(operation.GetResultWithValue());
        }
        /// <summary>
        /// Executes an operation for a given key.
        /// </summary>
        /// <param name="operation">The <see cref="IOperation" /> being executed.</param>
        /// <returns>
        /// An <see cref="IOperationResult" /> representing the result of operation.
        /// </returns>
        public IOperationResult Execute(IOperation operation)
        {
            //Get the buffer and a connection
            var request    = operation.Write();
            var connection = _connectionPool.Acquire();

            byte[] response = null;
            try
            {
                //A new connection will have to be authenticated
                if (!connection.IsAuthenticated)
                {
                    lock (_syncObj)
                    {
                        Authenticate(connection);
                        EnableEnhancedDurability(connection);
                    }
                }

                //Send the request buffer and release the connection
                response = connection.Send(request);
            }
            catch (SocketException e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.TransportFailure);
            }
            catch (RemoteHostTimeoutException e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.TransportFailure);

                //this almost always will be a server offline or service down
                _connectionPool.Owner.MarkDead();
            }
            catch (Exception e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.ClientFailure);
            }
            finally
            {
                _connectionPool.Release(connection);
            }

            //Read the response and return the completed operation
            if (response != null && response.Length > 0)
            {
                operation.Read(response, 0, response.Length);
            }
            return(operation.GetResult());
        }
예제 #5
0
        void CheckConnection()
        {
            lock (_syncObj)
            {
                Log.Info("Checking connection {0} is dead {1}", _connection.Identity, _connection.IsDead);
                IConnection connection = null;
                try
                {
                    if (_connection == null || _connection.IsDead)
                    {
                        Log.Info("Trying to acquire a new connection for {0}", _connection.Identity, _connection.IsDead);
                        _connectionPool.Release(_connection);

                        connection = _connectionPool.Acquire();
                        Log.Info("Exchanging {0} for {1}", _connection.Identity, connection.Identity);
                        Interlocked.Exchange(ref _connection, connection);

                        Authenticate(connection);
                        EnableServerFeatures(connection);
                    }
                }
                catch (Exception e)
                {
                    if (connection != null)
                    {
                        connection.IsDead = true;
                        _connectionPool.Release(connection);
                        Log.Info("Connection {0} {1}", _connection.Identity, e);
                    }
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PooledIOService"/> class.
        /// </summary>
        /// <param name="connectionPool">The connection pool.</param>
        public PooledIOService(IConnectionPool connectionPool)
        {
            Log.Debug("Creating PooledIOService {0}", Identity);
            ConnectionPool = connectionPool;

            var connection = connectionPool.Connections.FirstOrDefault() ?? connectionPool.Acquire();

            CheckEnabledServerFeatures(connection);
        }
        public MultiplexingIOService(IConnectionPool connectionPool)
        {
            Log.Info("Creating IOService {0}", _identity);
            _connectionPool = connectionPool;
            _connection     = _connectionPool.Acquire();

            //enable the server features
            EnableServerFeatures(_connection);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PooledIOService"/> class.
        /// </summary>
        /// <param name="connectionPool">The connection pool.</param>
        /// <param name="saslMechanism">The sasl mechanism.</param>
        public PooledIOService(IConnectionPool connectionPool, ISaslMechanism saslMechanism)
        {
            Log.Debug("Creating PooledIOService {0}", Identity);
            ConnectionPool = connectionPool;
            SaslMechanism  = saslMechanism;

            var conn = connectionPool.Acquire();

            CheckEnabledServerFeatures(conn);
        }
        public MultiplexingIOService(IConnectionPool connectionPool)
        {
            Log.Info("Creating IOService {0}", Identity);
            ConnectionPool = connectionPool;
            _connection    = connectionPool.Connections.FirstOrDefault() ?? connectionPool.Acquire();

            //enable the server features
            CheckEnabledServerFeatures(_connection);
            EnableServerFeatures(_connection);
        }
예제 #10
0
        /// <summary>
        /// Executes an operation for a given key.
        /// </summary>
        /// <param name="operation">The <see cref="IOperation" /> being executed.</param>
        /// <returns>
        /// An <see cref="IOperationResult" /> representing the result of operation.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public IOperationResult Execute(IOperation operation)
        {
            //Get the buffer and a connection
            var request    = operation.Write();
            var connection = _connectionPool.Acquire();

            byte[] response = null;
            try
            {
                //A new connection will have to be authenticated
                if (!connection.IsAuthenticated)
                {
                    Authenticate(connection);
                }

                //Send the request buffer and release the connection
                response = connection.Send(request);
            }
            catch (SocketException e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.TransportFailure);
            }
            catch (Exception e)
            {
                Log.Debug(e);
                operation.Exception = e;
                operation.HandleClientError(e.Message, ResponseStatus.ClientFailure);
            }
            finally
            {
                _connectionPool.Release(connection);
            }

            //Read the response and return the completed operation
            if (response != null && response.Length > 0)
            {
                operation.Read(response, 0, response.Length);
            }
            return(operation.GetResult());
        }
        public MultiplexingIOService(IConnectionPool connectionPool)
        {
            Log.Debug(m => m("Creating IOService {0}", _identity));
            _connectionPool = connectionPool;
            _connection     = _connectionPool.Acquire();

            //authenticate the connection
            if (!_connection.IsAuthenticated)
            {
                Authenticate(_connection);
            }
        }
예제 #12
0
        public void Test_Acquire_2ndRequest_Gets_Connection_From_Pool_While_1stRequest_Waits_For_Opening()
        {
            //Arrange
            var ipEndpoint       = UriExtensions.GetEndPoint(_address);
            var factoryWithDelay = new Func <IConnectionPool <Connection>, IByteConverter, BufferAllocator, Connection>(
                (a, b, c) =>
            {
                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //remove sleep and use Moq for threads synchronization
                Thread.Sleep(500);
                return(new Connection(a, socket, b, c));
            });

            _configuration  = new PoolConfiguration(MaxSize, 1, WaitTimeout, RecieveTimeout, ShutdownTimeout, SendTimeout, ConnectTimeout, MaxConnectionAcquireCount, BucketName);
            _connectionPool = new ConnectionPool <Connection>(_configuration, ipEndpoint, factoryWithDelay, new DefaultConverter());
            _connectionPool.Initialize();

            //Act
            var connectionFromPool = _connectionPool.Acquire();
            var task1 = new Task <IConnection>(() => _connectionPool.Acquire());
            var task2 = new Task <IConnection>(() => _connectionPool.Acquire());

            task1.Start();
            Thread.Sleep(100);
            task2.Start();
            //enqueue connection to pool
            //at this point task2 should get released connection
            _connectionPool.Release(connectionFromPool);

            Task.WaitAll(task1, task2);

            var connectionFromFactory      = task1.Result;
            var connectionFromPoolReleased = task2.Result;


            //Assert
            Assert.IsNotNull(connectionFromFactory);
            Assert.AreNotEqual(connectionFromPool, connectionFromFactory);
            Assert.AreEqual(connectionFromPool, connectionFromPoolReleased);
        }
        public void Test_Acquire_2ndRequest_Gets_Connection_From_Pool_While_1stRequest_Waits_For_Opening()
        {
            //Arrange
            var ipEndpoint = UriExtensions.GetEndPoint(_address);
            var factoryWithDelay = new Func<ConnectionPool<Connection>, IByteConverter, BufferAllocator, Connection>(
                (a, b, c) =>
                {
                    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //remove sleep and use Moq for threads synchronization
                    Thread.Sleep(500);
                    return new Connection(a, socket, b, c);
                });

            _configuration = new PoolConfiguration(MaxSize, 1, WaitTimeout, RecieveTimeout, ShutdownTimeout, SendTimeout, ConnectTimeout, MaxConnectionAcquireCount);
            _connectionPool = new ConnectionPool<Connection>(_configuration, ipEndpoint, factoryWithDelay, new DefaultConverter());
            _connectionPool.Initialize();

            //Act
            var connectionFromPool = _connectionPool.Acquire();
            var task1 = new Task<IConnection>(() => _connectionPool.Acquire());
            var task2 = new Task<IConnection>(() => _connectionPool.Acquire());

            task1.Start();
            Thread.Sleep(100);
            task2.Start();
            //enqueue connection to pool
            //at this point task2 should get released connection
            _connectionPool.Release(connectionFromPool);

            Task.WaitAll(task1, task2);

            var connectionFromFactory = task1.Result;
            var connectionFromPoolReleased = task2.Result;


            //Assert
            Assert.IsNotNull(connectionFromFactory);
            Assert.AreNotEqual(connectionFromPool, connectionFromFactory);
            Assert.AreEqual(connectionFromPool, connectionFromPoolReleased);
        }
예제 #14
0
        public MultiplexingIOService(IConnectionPool connectionPool)
        {
            Log.Info("Creating IOService {0}", _identity);
            _connectionPool = connectionPool;
            _connection     = _connectionPool.Acquire();

            //authenticate the connection
            if (!_connection.IsAuthenticated)
            {
                Authenticate(_connection);
                EnableServerFeatures(_connection);
            }
        }
        public IOperationResult <T> Execute <T>(IOperation <T> operation)
        {
            var connection = _connectionPool.Acquire();

            if (!connection.IsAuthenticated)
            {
                Authenticate(connection);
            }
            var result = Execute(operation, connection);

            _connectionPool.Release(connection);
            return(result);
        }
        void CheckConnection()
        {
            var lockTaken = false;

            try
            {
                Monitor.TryEnter(_syncObj, ref lockTaken);
                if (!lockTaken)
                {
                    return;
                }
                IConnection connection = null;
                try
                {
                    Log.Info("Checking connection {0} is dead {1}", _connection.Identity, _connection.IsDead);
                    if (_connection == null || _connection.IsDead)
                    {
                        Log.Info("Trying to acquire a new connection for {0}", _connection.Identity,
                                 _connection.IsDead);
                        _connectionPool.Release(_connection);

                        connection = _connectionPool.Acquire();
                        Log.Info("Exchanging {0} for {1}", _connection.Identity, connection.Identity);
                        Interlocked.Exchange(ref _connection, connection);

                        EnableServerFeatures(connection);
                        Authenticate(connection);
                    }
                }
                catch (Exception e)
                {
                    if (connection != null)
                    {
                        connection.IsDead = true;
                        _connectionPool.Release(connection);
                        Log.Info("Connection {0} {1}", _connection.Identity, e);
                    }
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(_syncObj);
                }
            }
        }
        public void Test_Acquire()
        {
            var connection = _connectionPool.Acquire();

            Assert.IsNotNull(connection);
        }
 public ISession Session()
 {
     return(new Session(_connectionPool.Acquire(), _logger));
 }
예제 #19
0
        public void When_Connection_Acquired_Handle_Is_Not_Null()
        {
            var connection = _connectionPool.Acquire();

            Assert.IsNotNull(connection.Socket);
        }