/// <summary>
 /// CTOR for testing/dependency injection.
 /// </summary>
 /// <param name="configuration">The <see cref="PoolConfiguration"/> to use.</param>
 /// <param name="endPoint">The <see cref="IPEndPoint"/> of the Couchbase Server.</param>
 /// <param name="factory">A functory for creating <see cref="IConnection"/> objects./></param>
 internal ConnectionPool(PoolConfiguration configuration, IPEndPoint endPoint, Func <ConnectionPool <T>, IByteConverter, BufferAllocator, T> factory, IByteConverter converter)
 {
     _configuration   = configuration;
     _factory         = factory;
     _converter       = converter;
     _bufferAllocator = Configuration.BufferAllocator(Configuration);
     EndPoint         = endPoint;
 }
 public ConnectionBase(Socket socket, OperationAsyncState asyncState, IByteConverter converter, BufferAllocator bufferAllocator)
 {
     _socket         = socket;
     _state          = asyncState;
     Converter       = converter;
     BufferAllocator = bufferAllocator;
     EndPoint        = socket.RemoteEndPoint;
 }
Exemple #3
0
 /// <summary>
 /// CTOR for testing/dependency injection.
 /// </summary>
 /// <param name="configuration">The <see cref="PoolConfiguration"/> to use.</param>
 /// <param name="endPoint">The <see cref="IPEndPoint"/> of the Couchbase Server.</param>
 /// <param name="factory">A functory for creating <see cref="IConnection"/> objects./></param>
 /// <param name="converter">The <see cref="IByteConverter"/>that this instance is using.</param>
 internal ConnectionPoolBase(PoolConfiguration configuration, IPEndPoint endPoint, Func <IConnectionPool <T>, IByteConverter, BufferAllocator, T> factory, IByteConverter converter)
 {
     Configuration   = configuration;
     Factory         = factory;
     Converter       = converter;
     BufferAllocator = Configuration.BufferAllocator(Configuration);
     EndPoint        = endPoint;
 }
Exemple #4
0
 public ConnectionBase(Socket socket, OperationAsyncState asyncState, IByteConverter converter, BufferAllocator bufferAllocator)
 {
     _socket                  = socket;
     _state                   = asyncState;
     Converter                = converter;
     BufferAllocator          = bufferAllocator;
     EndPoint                 = socket.RemoteEndPoint;
     LocalEndPoint            = socket.LocalEndPoint;
     MustEnableServerFeatures = true;
 }
        private async Task <byte[]> SendAsync(byte[] buffer, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque);
            var state  = new SocketAsyncState
            {
                Data          = MemoryStreamFactory.GetMemoryStream(),
                Opaque        = opaque,
                CorrelationId = CreateCorrelationId(opaque)
            };

            await _sslStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ContinueOnAnyContext();

            try
            {
                state.SetIOBuffer(BufferAllocator.GetBuffer());

                while (state.BytesReceived < state.BodyLength + 24)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var bytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength, cancellationToken).ContinueOnAnyContext();

                    state.BytesReceived += bytesReceived;

                    if (state.BytesReceived == 0)
                    {
                        // No more bytes were received, go ahead and exit the loop
                        break;
                    }
                    if (state.BodyLength == 0)
                    {
                        // Reading header, so get the BodyLength
                        state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.Body);
                    }

                    state.Data.Write(state.Buffer, state.BufferOffset, bytesReceived);
                }
            }
            finally
            {
                if (state.IOBuffer != null)
                {
                    BufferAllocator.ReleaseBuffer(state.IOBuffer);
                }
            }

            return(state.Data.ToArray());
        }
        /// <summary>
        /// Disposes the underlying socket and other objects used by this instance.
        /// </summary>
        public override void Dispose()
        {
            Log.DebugFormat("Disposing {0}", _identity);
            if (Disposed || InUse && !IsDead)
            {
                return;
            }
            Disposed = true;
            IsDead   = true;

            try
            {
                if (Socket != null)
                {
                    if (Socket.Connected)
                    {
                        Socket.Shutdown(SocketShutdown.Both);
                        Socket.Close(ConnectionPool.Configuration.ShutdownTimeout);
                    }
                    else
                    {
                        Socket.Close();
                        Socket.Dispose();
                    }
                }
                //call the bases dispose to cleanup the timer
                base.Dispose();

                _eventArgs.Dispose();
                _requestCompleted.Dispose();
            }
            catch (Exception e)
            {
                Log.Info(e);
            }

            try
            {
                // Release the buffer in a separate try..catch block, because we want to ensure this happens
                // even if other steps fail.  Otherwise we will run out of buffers when the ConnectionPool reaches
                // its maximum size.

                BufferAllocator.ReleaseBuffer(_eventArgs);
            }
            catch (Exception e)
            {
                Log.Info(e);
            }
        }
        internal Connection(IConnectionPool connectionPool, Socket socket, SocketAsyncEventArgs eventArgs, IByteConverter converter)
            : base(socket, converter)
        {
            //set the configuration info
            ConnectionPool = connectionPool;
            Configuration  = ConnectionPool.Configuration;

            //Since the config can be changed on the fly create allocator late in the cycle
            _allocator = Configuration.BufferAllocator(Configuration);

            //create a seae with an accept socket and completed event
            _eventArgs = eventArgs;
            _eventArgs.AcceptSocket = socket;
            _eventArgs.Completed   += OnCompleted;

            //set the buffer to use with this saea instance
            _allocator.SetBuffer(_eventArgs);
        }
Exemple #8
0
        internal Connection(IConnectionPool connectionPool, Socket socket, IByteConverter converter, BufferAllocator allocator)
            : base(socket, converter)
        {
            ConnectionPool = connectionPool;
            Configuration  = ConnectionPool.Configuration;

            //set the max close attempts so that a connection in use is not disposed
            MaxCloseAttempts = Configuration.MaxCloseAttempts;

            _allocator = allocator;

            //create a seae with an accept socket and completed event
            _eventArgs = new SocketAsyncEventArgs();
            _eventArgs.AcceptSocket = socket;
            _eventArgs.Completed   += OnCompleted;

            //set the buffer to use with this saea instance
            _allocator.SetBuffer(_eventArgs);
            Offset = _eventArgs.Offset;
        }
        public Connection(IConnectionPool connectionPool, Socket socket, IByteConverter converter, BufferAllocator allocator)
            : base(socket, converter)
        {
            ConnectionPool = connectionPool;
            Configuration = ConnectionPool.Configuration;

            //set the max close attempts so that a connection in use is not disposed
            MaxCloseAttempts = Configuration.MaxCloseAttempts;

            _allocator = allocator;

            //create a seae with an accept socket and completed event
            _eventArgs = new SocketAsyncEventArgs();
            _eventArgs.AcceptSocket = socket;
            _eventArgs.Completed += OnCompleted;

            //set the buffer to use with this saea instance
            _allocator.SetBuffer(_eventArgs);
            Offset = _eventArgs.Offset;
        }
        public MultiplexingConnection(IConnectionPool connectionPool, Socket socket, IByteConverter converter,
            BufferAllocator allocator)
            : base(socket, converter, allocator)
        {
            ConnectionPool = connectionPool;
            Configuration = ConnectionPool.Configuration;

            //set the max close attempts so that a connection in use is not disposed
            MaxCloseAttempts = Configuration.MaxCloseAttempts;

            _statesInFlight = new ConcurrentDictionary<uint, IState>();
            _statePool = new Queue<SyncState>();

            //allocate a buffer
            _receiveBuffer = new byte[Configuration.BufferSize];
            _receiveBufferLength = 0;

            //Start a dedicated background thread for receiving server responses.
            _receiveThread = new Thread(ReceiveThreadBody);
            _receiveThread.IsBackground = true;
            _receiveThread.Start();
        }
        public Connection(IConnectionPool connectionPool, Socket socket, IByteConverter converter, BufferAllocator allocator)
            : base(socket, converter, allocator)
        {
            ConnectionPool = connectionPool;
            Configuration = ConnectionPool.Configuration;

            //set the max close attempts so that a connection in use is not disposed
            MaxCloseAttempts = Configuration.MaxCloseAttempts;

            //create a seae with an accept socket and completed event
            _eventArgs = new SocketAsyncEventArgs();
            _eventArgs.AcceptSocket = socket;
            _eventArgs.Completed += OnCompleted;

            //set the buffer to use with this saea instance
            if (!BufferAllocator.SetBuffer(_eventArgs))
            {
                // failed to acquire a buffer because the allocator was exhausted

                throw new BufferUnavailableException("Unable to allocate a buffer for this connection because the BufferAllocator is exhausted.");
            }
        }
Exemple #12
0
        public Connection(IConnectionPool connectionPool, Socket socket, IByteConverter converter, BufferAllocator allocator)
            : base(socket, converter, allocator)
        {
            ConnectionPool = connectionPool;
            Configuration  = ConnectionPool.Configuration;

            //set the max close attempts so that a connection in use is not disposed
            MaxCloseAttempts = Configuration.MaxCloseAttempts;

            //create a seae with an accept socket and completed event
            _eventArgs = new SocketAsyncEventArgs();
            _eventArgs.AcceptSocket = socket;
            _eventArgs.Completed   += OnCompleted;

            //set the buffer to use with this saea instance
            if (!BufferAllocator.SetBuffer(_eventArgs))
            {
                // failed to acquire a buffer because the allocator was exhausted

                throw new BufferUnavailableException("Unable to allocate a buffer for this connection because the BufferAllocator is exhausted.");
            }
        }
Exemple #13
0
        public MultiplexingConnection(IConnectionPool connectionPool, Socket socket, IByteConverter converter,
                                      BufferAllocator allocator)
            : base(socket, converter, allocator)
        {
            ConnectionPool = connectionPool;
            Configuration  = ConnectionPool.Configuration;

            //set the max close attempts so that a connection in use is not disposed
            MaxCloseAttempts = Configuration.MaxCloseAttempts;

            _statesInFlight = new ConcurrentDictionary <uint, IState>();
            _statePool      = new ConcurrentQueue <SyncState>();

            //allocate a buffer
            _receiveBuffer       = new byte[Configuration.BufferSize];
            _receiveBufferLength = 0;

            //Start a dedicated background thread for receiving server responses.
            _receiveThread = new Thread(ReceiveThreadBody);
            _receiveThread.IsBackground = true;
            _receiveThread.Start();
        }
Exemple #14
0
 public SslConnection(IConnectionPool connectionPool, Socket socket, IByteConverter converter, BufferAllocator allocator)
     : this(connectionPool,
            socket,
            new SslStream(new NetworkStream(socket), true, GetCertificateCallback(connectionPool.Configuration.ClientConfiguration)),
            converter,
            allocator)
 {
 }
Exemple #15
0
 public SslConnection(IConnectionPool connectionPool, Socket socket, SslStream sslStream, IByteConverter converter, BufferAllocator allocator)
     : base(socket, converter, allocator)
 {
     ConnectionPool = connectionPool;
     _sslStream     = sslStream;
     Configuration  = ConnectionPool.Configuration;
     _buffer        = new IOBuffer(new byte[Configuration.BufferSize], 0, Configuration.BufferSize);
 }
        public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback)
        {
            ExceptionDispatchInfo capturedException = null;
            SocketAsyncState      state             = null;

            try
            {
                state = new SocketAsyncState
                {
                    Data      = new MemoryStream(),
                    Opaque    = Converter.ToUInt32(request, HeaderIndexFor.Opaque),
                    Buffer    = request,
                    Completed = callback
                };

                await _sslStream.WriteAsync(request, 0, request.Length).ConfigureAwait(false);

                state.SetIOBuffer(BufferAllocator.GetBuffer());
                state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength).ConfigureAwait(false);

                //write the received buffer to the state obj
                await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived).ConfigureAwait(false);

                state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.BodyLength);
                while (state.BytesReceived < state.BodyLength + 24)
                {
                    var bufferLength = state.BufferLength - state.BytesSent < state.BufferLength
                        ? state.BufferLength - state.BytesSent
                        : state.BufferLength;

                    state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, bufferLength).ConfigureAwait(false);

                    await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived - (int)state.Data.Length).ConfigureAwait(false);
                }
                await callback(state).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                IsDead            = true;
                capturedException = ExceptionDispatchInfo.Capture(e);
            }
            finally
            {
                ConnectionPool.Release(this);
                if (state.IOBuffer != null)
                {
                    BufferAllocator.ReleaseBuffer(state.IOBuffer);
                }
            }

            if (capturedException != null)
            {
                var sourceException = capturedException.SourceException;
                if (state == null)
                {
                    await callback(new SocketAsyncState
                    {
                        Exception = capturedException.SourceException,
                        Status    = (sourceException is SocketException)
                            ? ResponseStatus.TransportFailure
                            : ResponseStatus.ClientFailure
                    }).ConfigureAwait(false);
                }
                else
                {
                    state.Exception = sourceException;
                    await state.Completed(state).ConfigureAwait(false);

                    Log.Debug(sourceException);
                }
            }
        }
 public SslConnection(IConnectionPool connectionPool, Socket socket, SslStream sslStream, IByteConverter converter, BufferAllocator allocator)
     : base(socket, converter, allocator)
 {
     ConnectionPool = connectionPool;
     _sslStream     = sslStream;
     Configuration  = ConnectionPool.Configuration;
     _timingEnabled = Configuration.EnableOperationTiming;
 }
 public SslConnection(IConnectionPool connectionPool, Socket socket, IByteConverter converter, BufferAllocator allocator)
     : this(connectionPool, socket, new SslStream(new NetworkStream(socket), true, ServerCertificateValidationCallback), converter, allocator)
 {
 }
Exemple #19
0
 public ConnectionBase(Socket socket, IByteConverter converter, BufferAllocator bufferAllocator)
     : this(socket, new OperationAsyncState(), converter, bufferAllocator)
 {
 }