Пример #1
0
        /// <summary>
        /// Handles the reconnection attempts.
        /// If it succeeds, it marks the host as UP.
        /// If not, it marks the host as DOWN
        /// </summary>
        internal void AttemptReconnection()
        {
            _poolModificationSemaphore.Wait();
            var toRemove = _connections.Where(c => c.IsClosed).ToArray();

            foreach (var c in toRemove)
            {
                _connections.Remove(c);
            }
            if (_connections.Count > 0)
            {
                //there is already an open connection
                _poolModificationSemaphore.Release();
                return;
            }
            Logger.Info("Attempting reconnection to host {0}", _host.Address);
            CreateConnection().ContinueWith(t =>
            {
                if (t.Status == TaskStatus.RanToCompletion)
                {
                    _connections.Add(t.Result);
                    //Release as soon as possible
                    _poolModificationSemaphore.Release();
                    Logger.Info("Reconnection attempt to host {0} succeeded", _host.Address);
                    _host.BringUpIfDown();
                }
                else
                {
                    _poolModificationSemaphore.Release();
                    Logger.Info("Reconnection attempt to host {0} failed", _host.Address);
                    _host.SetDown();
                }
            }, TaskContinuationOptions.ExecuteSynchronously);
        }
 public void CopyOnWriteList_Should_Add_And_Remove()
 {
     var list = new CopyOnWriteList<string> {"one", "two", "three", "four", "five"};
     Assert.AreEqual(5, list.Count);
     list.Remove("three");
     CollectionAssert.AreEqual(new[] { "one", "two", "four", "five" }, list);
     list.Remove("one");
     CollectionAssert.AreEqual(new[] { "two", "four", "five" }, list);
     list.Remove("five");
     CollectionAssert.AreEqual(new[] { "two", "four" }, list);
     list.Remove("four");
     CollectionAssert.AreEqual(new[] { "two" }, list);
     CollectionAssert.AreEqual(new[] { "two" }, list.ToArray());
     list.Remove("two");
     CollectionAssert.AreEqual(new string[0], list);
 }
Пример #3
0
        public void RemoveListener(ContextPartitionStateListener listener)
        {
            if (listenersLazy == null) {
                return;
            }

            listenersLazy.Remove(listener);
        }
Пример #4
0
 public void CheckHealth(Connection c)
 {
     if (c.TimedOutOperations < _config.SocketOptions.DefunctReadTimeoutThreshold)
     {
         return;
     }
     //We are in the default thread-pool (non-io thread)
     //Defunct: close it and remove it from the pool
     _connections.Remove(c);
     c.Dispose();
 }
Пример #5
0
        public IDisposable Subscribe <T>(string path, Action <T> consumeAction)
        {
            Action <string, object> consumer = (pattern, message) =>
            {
                if (path == pattern && message is T)
                {
                    consumeAction((T)message);
                }
            };

            _list.Add(consumer);
            return(new AnonymousDisposer(() => _list.Remove(consumer)));
        }
Пример #6
0
        public IDisposable Subscribe(string topicPattern, Action <string, object> messageConsumer)
        {
            var topicExpression = new Regex(topicPattern);
            Action <string, object> conditionalConsume =
                (path, message) =>
            {
                if (topicExpression.IsMatch(path))
                {
                    messageConsumer(path, message);
                }
            };

            _subscribtions.Add(conditionalConsume);
            return(new AnonymousDisposer(() => _subscribtions.Remove(conditionalConsume)));
        }
 public void CopyOnWriteList_Should_Allow_Parallel_Calls_To_Remove()
 {
     var actions = new List<Action>();
     var list = new CopyOnWriteList<int>();
     for (var i = 0; i < 100; i++)
     {
         list.Add(i);
     }
     Assert.AreEqual(100, list.Count);
     for (var i = 0; i < 100; i++)
     {
         var item = i;
         actions.Add(() =>
         {
             list.Remove(item);
         });
     }
     TestHelper.ParallelInvoke(actions);
     Assert.AreEqual(0, list.Count);
 }
Пример #8
0
        /// <summary>
        /// Opens one connection.
        /// If a connection is being opened it yields the same task, preventing creation in parallel.
        /// </summary>
        /// <exception cref="SocketException">Throws a SocketException when the connection could not be established with the host</exception>
        /// <exception cref="AuthenticationException" />
        /// <exception cref="UnsupportedProtocolVersionException" />
        private async Task <Connection> CreateOpenConnection(bool foreground)
        {
            var concurrentOpenTcs = Volatile.Read(ref _connectionOpenTcs);

            // Try to exit early (cheap) as there could be another thread creating / finishing creating
            if (concurrentOpenTcs != null)
            {
                // There is another thread opening a new connection
                return(await concurrentOpenTcs.Task.ConfigureAwait(false));
            }
            var tcs = new TaskCompletionSource <Connection>();

            // Try to set the creation task source
            concurrentOpenTcs = Interlocked.CompareExchange(ref _connectionOpenTcs, tcs, null);
            if (concurrentOpenTcs != null)
            {
                // There is another thread opening a new connection
                return(await concurrentOpenTcs.Task.ConfigureAwait(false));
            }
            if (IsClosing)
            {
                return(await FinishOpen(tcs, false, GetNotConnectedException()).ConfigureAwait(false));
            }
            // Before creating, make sure that its still needed
            // This method is the only one that adds new connections
            // But we don't control the removal, use snapshot
            var connectionsSnapshot = _connections.GetSnapshot();

            if (connectionsSnapshot.Length >= _expectedConnectionLength)
            {
                if (connectionsSnapshot.Length == 0)
                {
                    // Avoid race condition while removing
                    return(await FinishOpen(tcs, false, GetNotConnectedException()).ConfigureAwait(false));
                }
                return(await FinishOpen(tcs, true, null, connectionsSnapshot[0]).ConfigureAwait(false));
            }
            if (foreground && !_canCreateForeground)
            {
                // Foreground creation only cares about one connection
                // If its already there, yield it
                connectionsSnapshot = _connections.GetSnapshot();
                if (connectionsSnapshot.Length == 0)
                {
                    // When creating in foreground, it failed
                    return(await FinishOpen(tcs, false, GetNotConnectedException()).ConfigureAwait(false));
                }
                return(await FinishOpen(tcs, false, null, connectionsSnapshot[0]).ConfigureAwait(false));
            }
            Logger.Info("Creating a new connection to {0}", _host.Address);
            Connection c          = null;
            Exception  creationEx = null;

            try
            {
                c = await DoCreateAndOpen().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Logger.Info("Connection to {0} could not be created: {1}", _host.Address, ex);
                // Can not be awaited on catch on C# 5...
                creationEx = ex;
            }
            if (creationEx != null)
            {
                return(await FinishOpen(tcs, true, creationEx).ConfigureAwait(false));
            }
            if (IsClosing)
            {
                Logger.Info("Connection to {0} opened successfully but pool #{1} was being closed",
                            _host.Address, GetHashCode());
                c.Dispose();
                return(await FinishOpen(tcs, false, GetNotConnectedException()).ConfigureAwait(false));
            }
            var newLength = _connections.AddNew(c);

            Logger.Info("Connection to {0} opened successfully, pool #{1} length: {2}",
                        _host.Address, GetHashCode(), newLength);
            if (IsClosing)
            {
                // We haven't use a CAS operation, so it's possible that the pool is being closed while adding a new
                // connection, we should remove it.
                Logger.Info("Connection to {0} opened successfully and added to the pool #{1} but it was being closed",
                            _host.Address, GetHashCode());
                _connections.Remove(c);
                c.Dispose();
                return(await FinishOpen(tcs, false, GetNotConnectedException()).ConfigureAwait(false));
            }
            return(await FinishOpen(tcs, true, null, c).ConfigureAwait(false));
        }
Пример #9
0
 public void RemoveListener(ContextPartitionStateListener listener)
 {
     listenersLazy?.Remove(listener);
 }
Пример #10
0
 public IDisposable Subscribe(Action <object> consumer)
 {
     _subscribers.Add(consumer);
     EnsureWatching();
     return(new AnonymousDisposer(() => _subscribers.Remove(consumer)));
 }