/// <summary>
        /// Checks connection for timeout
        /// </summary>
        public void CheckForTimeout(TimeSpan keepAlive)
        {
            lock (this)
            {
                CachedConnection prev = null;
                CachedConnection current = _connections;

                while (current != null)
                {
                    // see if it's lifetime has expired
                    if (current.InactiveTime > keepAlive)
                    {
                        // close the connection
                        current.Connection.Close();

                        // remove connection from the list
                        current = current.Next;
                        if (prev == null)
                        {
                            _connections = current;
                        }
                        else
                        {
                            prev.Next = current;
                        }
                    }
                    else
                    {
                        // move to the next
                        prev = current;
                        current = current.Next;
                    }
                }
            }
        }
        /// <summary>
        /// Checks connection for timeout
        /// </summary>
        public void CheckForTimeout(TimeSpan keepAlive)
        {
            lock (this)
            {
                CachedConnection prev    = null;
                CachedConnection current = _connections;

                while (current != null)
                {
                    // see if it's lifetime has expired
                    if (current.InactiveTime > keepAlive)
                    {
                        // close the connection
                        current.Connection.Close();

                        // remove connection from the list
                        current = current.Next;
                        if (prev == null)
                        {
                            _connections = current;
                        }
                        else
                        {
                            prev.Next = current;
                        }
                    }
                    else
                    {
                        // move to the next
                        prev    = current;
                        current = current.Next;
                    }
                }
            }
        }
 /// <summary>
 /// Returns connection back to the cache
 /// </summary>
 public void StoreConnection(IConnection connection)
 {
     lock (this)
     {
         _connections = new CachedConnection(connection, _connections);
     }
 }
Example #4
0
        //------------------------------------------------------
        //--Plugin Services
        //------------------------------------------------------

        public IDatabase GetDatabase(string connectionName, int?database = null)
        {
            CachedConnection cachedConn = GetConnection(connectionName);
            int?databaseId = database ?? cachedConn.Configuration.DefaultDatabase;

            return(databaseId == null
                ? cachedConn.Connection.GetDatabase()
                : cachedConn.Connection.GetDatabase(databaseId.Value));
        }
Example #5
0
        public ValueTask <HttpConnection> GetConnectionAsync <TState>(Func <TState, ValueTask <HttpConnection> > createConnection, TState state)
        {
            List <CachedConnection> list = _idleConnections;

            lock (SyncObj)
            {
                // Try to return a cached connection.  We need to loop in case the connection
                // we get from the list is unusable.
                while (list.Count > 0)
                {
                    CachedConnection cachedConnection = list[list.Count - 1];
                    list.RemoveAt(list.Count - 1);
                    if (cachedConnection.IsUsable())
                    {
                        // We found a valid collection.  Return it.
                        return(new ValueTask <HttpConnection>(cachedConnection._connection));
                    }

                    // We got a connection, but it was already closed by the server or the
                    // server sent unexpected data or the connection is too old.  In any case,
                    // we can't use the connection, so get rid of it and try again.
                    cachedConnection._connection.Dispose();
                }

                // No valid cached connections, so we need to create a new one.  If
                // there's no limit on the number of connections associated with this
                // pool, or if we haven't reached such a limit, simply create a new
                // connection.
                if (_waiters == null || _associatedConnectionCount < _maxConnections)
                {
                    IncrementConnectionCountNoLock();
                    return(WaitForCreatedConnectionAsync(createConnection(state)));
                }
                else
                {
                    // There is a limit, and we've reached it, which means we need to
                    // wait for a connection to be returned to the pool or for a connection
                    // associated with the pool to be dropped before we can create a
                    // new one.  Create a waiter object and register it with the pool; it'll
                    // be signaled with the created connection when one is returned or
                    // space is available and the provided creation func has successfully
                    // created the connection to be used.
                    var waiter = new ConnectionWaiter <TState>(this, createConnection, state);
                    _waiters.Enqueue(waiter);
                    return(new ValueTask <HttpConnection>(waiter.Task));
                }

                // Note that we don't check for _disposed.  We may end up disposing the
                // created connection when it's returned, but we don't want to block use
                // of the pool if it's already been disposed, as there's a race condition
                // between getting a pool and someone disposing of it, and we don't want
                // to complicate the logic about trying to get a different pool when the
                // retrieved one has been disposed of.  In the future we could alternatively
                // try returning such connections to whatever pool is currently considered
                // current for that endpoint, if there is one.
            }
        }
Example #6
0
        public Task Listen(string channelId)
        {
            _logger.LogDebug($"listen {channelId} {Context.User?.Identity.Name} {Context.ConnectionId}");
            Groups.AddToGroupAsync(Context.ConnectionId, channelId);
            var cc = new CachedConnection
            {
                Id          = Context.ConnectionId,
                ProfileId   = Context.User?.FindFirstValue(JwtRegisteredClaimNames.Sub),
                ProfileName = Context.User?.FindFirstValue("name"),
                Room        = channelId
            };

            _cache.Connections.TryAdd(cc.Id, cc);
            return(Clients.OthersInGroup(channelId).PresenceEvent(new BroadcastEvent(Context.User, "PRESENCE.ARRIVED")));
        }
 /// <summary>
 /// Returns cached connection
 /// </summary>
 public IConnection GetConnection()
 {
     lock (this)
     {
         if (_connections == null)
         {
             // cache is empty so create new connection
             return(_cache.CreateConnection(_channelUri));
         }
         else
         {
             IConnection connection = _connections.Connection;
             _connections = _connections.Next;
             return(connection);
         }
     }
 }
        public ValueTask <HttpConnection> GetConnectionAsync <TState>(
            Func <TState, CancellationToken, ValueTask <HttpConnection> > createConnection, TState state, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(new ValueTask <HttpConnection>(Task.FromCanceled <HttpConnection>(cancellationToken)));
            }

            List <CachedConnection> list = _idleConnections;

            lock (SyncObj)
            {
                // Try to return a cached connection.  We need to loop in case the connection
                // we get from the list is unusable.
                while (list.Count > 0)
                {
                    CachedConnection cachedConnection = list[list.Count - 1];
                    HttpConnection   conn             = cachedConnection._connection;

                    list.RemoveAt(list.Count - 1);
                    if (cachedConnection.IsUsable())
                    {
                        // We found a valid collection.  Return it.
                        if (NetEventSource.IsEnabled)
                        {
                            conn.Trace("Found usable connection in pool.");
                        }
                        return(new ValueTask <HttpConnection>(conn));
                    }

                    // We got a connection, but it was already closed by the server or the
                    // server sent unexpected data or the connection is too old.  In any case,
                    // we can't use the connection, so get rid of it and try again.
                    if (NetEventSource.IsEnabled)
                    {
                        conn.Trace("Found invalid connection in pool.");
                    }
                    conn.Dispose();
                }

                // No valid cached connections, so we need to create a new one.  If
                // there's no limit on the number of connections associated with this
                // pool, or if we haven't reached such a limit, simply create a new
                // connection.
                if (_associatedConnectionCount < _maxConnections)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        Trace("Creating new connection for pool.");
                    }
                    IncrementConnectionCountNoLock();
                    return(WaitForCreatedConnectionAsync(createConnection(state, cancellationToken)));
                }
                else
                {
                    // There is a limit, and we've reached it, which means we need to
                    // wait for a connection to be returned to the pool or for a connection
                    // associated with the pool to be dropped before we can create a
                    // new one.  Create a waiter object and register it with the pool; it'll
                    // be signaled with the created connection when one is returned or
                    // space is available and the provided creation func has successfully
                    // created the connection to be used.
                    if (NetEventSource.IsEnabled)
                    {
                        Trace("Limit reached.  Waiting to create new connection.");
                    }
                    var waiter = new ConnectionWaiter <TState>(this, createConnection, state, cancellationToken);
                    EnqueueWaiter(waiter);
                    if (cancellationToken.CanBeCanceled)
                    {
                        // If cancellation could be requested, register a callback for it that'll cancel
                        // the waiter and remove the waiter from the queue.  Note that this registration needs
                        // to happen under the reentrant lock and after enqueueing the waiter.
                        waiter._cancellationTokenRegistration = cancellationToken.Register(s =>
                        {
                            var innerWaiter = (ConnectionWaiter)s;
                            lock (innerWaiter._pool.SyncObj)
                            {
                                // If it's in the list, remove it and cancel it.
                                if (innerWaiter._pool.RemoveWaiterForCancellation(innerWaiter))
                                {
                                    bool canceled = innerWaiter.TrySetCanceled(innerWaiter._cancellationToken);
                                    Debug.Assert(canceled);
                                }
                            }
                        }, waiter);
                    }
                    return(new ValueTask <HttpConnection>(waiter.Task));
                }

                // Note that we don't check for _disposed.  We may end up disposing the
                // created connection when it's returned, but we don't want to block use
                // of the pool if it's already been disposed, as there's a race condition
                // between getting a pool and someone disposing of it, and we don't want
                // to complicate the logic about trying to get a different pool when the
                // retrieved one has been disposed of.  In the future we could alternatively
                // try returning such connections to whatever pool is currently considered
                // current for that endpoint, if there is one.
            }
        }
Example #9
0
        public ISubscriber GetSubscriber(string connectionName)
        {
            CachedConnection cachedConn = GetConnection(connectionName);

            return(cachedConn.Connection.GetSubscriber());
        }
Example #10
0
 /// <summary>
 /// Returns connection back to the cache
 /// </summary>
 public void StoreConnection(IConnection connection)
 {
     lock (this)
     {
         _connections = new CachedConnection(connection, _connections);
     }
 }
Example #11
0
        /// <summary>
        /// Returns cached connection
        /// </summary>
        public IConnection GetConnection()
        {
            lock (this)
            {
                if (_connections == null)
                {
                    // cache is empty so create new connection
                    return _cache.CreateConnection(_channelUri);
                }

                IConnection connection = _connections.Connection;
                _connections = _connections.Next;
                return connection;
            }
        }
Example #12
0
 public CachedConnection(IConnection connection, CachedConnection next)
 {
     _connection = connection;
     _lastUsed = DateTime.Now;
     Next = next;
 }
 public CachedConnection(IConnection connection, CachedConnection next)
 {
     _connection = connection;
     _lastUsed   = DateTime.Now;
     _next       = next;
 }