public void TestConcurrentAccess()
        {
            int count = 20;

            // Initialize using a specific count.
            var pool = new SocketAwaitablePool(count);

            Assert.AreEqual(pool.Count, count);

            // Deplete the pool.
            Parallel.For(0, count, i => Assert.IsNotNull(pool.Take()));
            Assert.AreEqual(pool.Count, 0);

            // Force pool to initialize new awaitables.
            var newAwaitables = new SocketAwaitable[count];

            Parallel.For(0, count, i => Assert.IsNotNull(newAwaitables[i] = pool.Take()));

            // Add new awaitables [back] to the pool.
            Parallel.For(0, count, i => pool.Add(newAwaitables[i]));
            Assert.AreEqual(pool.Count, count);

            // Add to, take from and iterate the pool in parallel.
            var addTask = Task.Run(
                () => Parallel.For(0, 1000000, i => pool.Add(new SocketAwaitable())));

            var takeTask = Task.Run(
                () => Parallel.For(0, 1000000 + count, i => Assert.IsNotNull(pool.Take())));

            var iterateTask = Task.Run(
                () => Parallel.ForEach(pool, e => Assert.IsNotNull(e)));

            Task.WaitAll(addTask, takeTask, iterateTask);
        }
        public void TestConcurrentAccess()
        {
            int count = 20;

            // Initialize using a specific count.
            var pool = new SocketAwaitablePool(count);
            Assert.AreEqual(pool.Count, count);

            // Deplete the pool.
            Parallel.For(0, count, i => Assert.IsNotNull(pool.Take()));
            Assert.AreEqual(pool.Count, 0);

            // Force pool to initialize new awaitables.
            var newAwaitables = new SocketAwaitable[count];
            Parallel.For(0, count, i => Assert.IsNotNull(newAwaitables[i] = pool.Take()));

            // Add new awaitables [back] to the pool.
            Parallel.For(0, count, i => pool.Add(newAwaitables[i]));
            Assert.AreEqual(pool.Count, count);

            // Add to, take from and iterate the pool in parallel.
            var addTask = Task.Run(
                () => Parallel.For(0, 1000000, i => pool.Add(new SocketAwaitable())));

            var takeTask = Task.Run(
                () => Parallel.For(0, 1000000 + count, i => Assert.IsNotNull(pool.Take())));

            var iterateTask = Task.Run(
                () => Parallel.ForEach(pool, e => Assert.IsNotNull(e)));

            Task.WaitAll(addTask, takeTask, iterateTask);
        }
        private async Task ConnectAsync(EndPoint endPoint)
        {
            var result = SocketError.Fault;

            for (var i = 0; i < _socketConnectAttempts; i++)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                {
                    UseOnlyOverlappedIO = true,
                    NoDelay             = true,
                    ReceiveTimeout      = _receiveTimeout,
                    SendTimeout         = _sendTimeout,
                    ReceiveBufferSize   = _receiveBufferSize,
                    SendBufferSize      = _sendBufferSize
                };

                var awaitable = _socketAwaitablePool.Take();
                try
                {
                    awaitable.RemoteEndPoint = endPoint;

                    var socketAwaitable = _socket.ConnectAsync(awaitable);
                    _lastActivity = DateTime.UtcNow;

                    result = await socketAwaitable;

                    if (result == SocketError.Success)
                    {
                        break;
                    }
                }
                finally
                {
                    awaitable.Clear();
                    _socketAwaitablePool.Add(awaitable);
                }
            }

            if (result != SocketError.Success)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
                throw new RiakException("Unable to connect to remote server: {0}:{1} error code {2}".Fmt(_endPoint.Host, _endPoint.Port, result));
            }
        }
Example #4
0
        public async Task SendAsyncImmediatelly(byte[] packetBytes)
        {
            int totalBytesSent = 0;

            var socketAwaitable = socketAwaitablePool.Take();

            var sendBuffer        = bufferManager.GetBuffer();
            var sendBufferMaxSize = sendBuffer.Count;

            try
            {
                while (totalBytesSent < packetBytes.Length)
                {
                    socketAwaitable.Clear();
                    var writeCount = Math.Min(packetBytes.Length - totalBytesSent, sendBufferMaxSize);
                    Buffer.BlockCopy(packetBytes, totalBytesSent, sendBuffer.Array, sendBuffer.Offset, writeCount);

                    socketAwaitable.Buffer = new ArraySegment <byte>(sendBuffer.Array, sendBuffer.Offset, writeCount);

                    var result = await Socket.SendAsync(socketAwaitable);

                    if (result != SocketError.Success || socketAwaitable.Transferred.Count == 0)
                    {
                        if (Logger.IsDebugEnabled && result != SocketError.Success)
                        {
                            Logger.Debug("Socket did not succeed when sending a packet socketError[{0}] IP[{1}]", result, RemoteIP);
                        }

                        return;
                    }

                    totalBytesSent += socketAwaitable.Transferred.Count;
                }
            }
            // Ignore cases where we accidentally send to the socket after its been disposed
            catch (ObjectDisposedException) { }
            catch (Exception e)
            {
                Logger.Warn(e, "Unexpected exception in send IP[{0}]", RemoteIP);
            }
            finally
            {
                socketAwaitable.Clear();
                socketAwaitablePool.Add(socketAwaitable);

                bufferManager.ReleaseBuffer(sendBuffer);
            }
        }
        public void TestAddingAfterDispose()
        {
            var count = 20;
            var pool  = new SocketAwaitablePool(count);

            Assert.AreEqual(pool.Count, count);

            pool.Dispose();
            Assert.AreEqual(pool.Count, 0);

            var awaitable = new SocketAwaitable();

            Assert.IsFalse(awaitable.IsDisposed);

            pool.Add(awaitable);
            Assert.IsTrue(awaitable.IsDisposed);
        }
        public void TestAddingAfterDispose()
        {
            var count = 20;
            var pool = new SocketAwaitablePool(count);
            Assert.AreEqual(pool.Count, count);

            pool.Dispose();
            Assert.AreEqual(pool.Count, 0);

            var awaitable = new SocketAwaitable();
            Assert.IsFalse(awaitable.IsDisposed);

            pool.Add(awaitable);
            Assert.IsTrue(awaitable.IsDisposed);
        }