示例#1
0
        /// <summary>
        /// execute heal connection tasks if the actual number of connections in pool is less than expected
        /// </summary>
        /// <param name="pool"> connection pool </param>
        /// <param name="url"> target url </param>
        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        //ORIGINAL LINE: private void healIfNeed(ConnectionPool pool, Url url) throws exception.RemotingException, ThreadInterruptedException
        private void healIfNeed(ConnectionPool pool, Url url)
        {
            string poolKey = url.UniqueKey;

            // only when async creating connections done
            // and the actual size of connections less than expected, the healing task can be run.
            if (pool.AsyncCreationDone && pool.size() < url.ConnNum)
            {
                this.healTasks.TryGetValue(poolKey, out var task);
                if (null == task)
                {
                    FutureTask newTask = new FutureTask(new HealConnectionCall(this, url, pool));

                    if (!healTasks.ContainsKey(poolKey))
                    {
                        healTasks.AddOrUpdate(poolKey, newTask, (_, __) => newTask);
                        task = newTask;
                    }
                    else
                    {
                        healTasks.TryGetValue(poolKey, out task);
                    }
                    task.run();
                }
                try
                {
                    int numAfterHeal = (int)task.@get();
                    if (logger.IsEnabled(LogLevel.Debug))
                    {
                        logger.LogDebug("[NOTIFYME] - conn num after heal {}, expected {}, warmup {}", numAfterHeal, url.ConnNum, url.ConnWarmup);
                    }
                }
                catch (ThreadInterruptedException)
                {
                    healTasks.TryRemove(poolKey, out _);
                    throw;
                }
                catch (ExecutionException e)
                {
                    healTasks.TryRemove(poolKey, out _);
                    System.Exception cause = e.InnerException;
                    if (cause is RemotingException)
                    {
                        throw (RemotingException)cause;
                    }
                    else
                    {
                        FutureTaskUtil.launderThrowable(cause);
                    }
                }
                // heal task is one-off, remove from cache directly after run
                healTasks.TryRemove(poolKey, out _);
            }
        }
示例#2
0
 /// <summary>
 /// remove task and remove all connections
 /// </summary>
 /// <param name="poolKey"> target pool key </param>
 protected internal virtual void removeTask(string poolKey)
 {
     connTasks.TryRemove(poolKey, out var task);
     if (null != task)
     {
         ConnectionPool pool = (ConnectionPool)FutureTaskUtil.getFutureTaskResult(task, logger);
         if (null != pool)
         {
             pool.removeAllAndTryClose();
         }
     }
 }
        public virtual void monitor(ConcurrentDictionary <string, RunStateRecordedFutureTask> connPools)
        {
            try
            {
                if (connPools == null || connPools.Count == 0)
                {
                    return;
                }

                foreach (var entry in connPools)
                {
                    string         poolKey = entry.Key;
                    ConnectionPool pool    = (ConnectionPool)FutureTaskUtil.getFutureTaskResult(entry.Value, logger);

                    var serviceOnConnections  = new List <Connection>();
                    var serviceOffConnections = new List <Connection>();


                    foreach (var connection in pool.All)
                    {
                        if (isConnectionOn(connection))
                        {
                            serviceOnConnections.Add(connection);
                        }
                        else
                        {
                            serviceOffConnections.Add(connection);
                        }
                    }

                    if (serviceOnConnections.Count > connectionThreshold)
                    {
                        Connection freshSelectConnect = (Connection)serviceOnConnections[random.nextInt(serviceOnConnections.Count)];
                        freshSelectConnect.setAttribute(Configs.CONN_SERVICE_STATUS, Configs.CONN_SERVICE_STATUS_OFF);
                        serviceOffConnections.Add(freshSelectConnect);
                    }
                    else
                    {
                        if (logger.IsEnabled(LogLevel.Information))
                        {
                            logger.LogInformation("serviceOnConnections({}) size[{}], CONNECTION_THRESHOLD[{}].", poolKey, serviceOnConnections.Count, connectionThreshold);
                        }
                    }

                    foreach (var offConn in serviceOffConnections)
                    {
                        if (offConn.InvokeFutureMapFinish)
                        {
                            if (offConn.Fine)
                            {
                                offConn.close();
                            }
                        }
                        else
                        {
                            if (logger.IsEnabled(LogLevel.Information))
                            {
                                logger.LogInformation("Address={} won't close at this schedule turn", offConn.Channel.RemoteAddress.ToString());
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                logger.LogError("ScheduledDisconnectStrategy monitor error", e);
            }
        }
示例#4
0
        /// <summary>
        /// Get the mapping instance of <seealso cref="ConnectionPool"/> with the specified poolKey,
        /// or create one if there is none mapping in connTasks.
        /// </summary>
        /// <param name="poolKey">  mapping key of <seealso cref="ConnectionPool"/> </param>
        /// <param name="callable"> the callable task </param>
        /// <returns> a non-nullable instance of <seealso cref="ConnectionPool"/> </returns>
        /// <exception cref="RemotingException"> if there is no way to get an available <seealso cref="ConnectionPool"/> </exception>
        /// <exception cref="ThreadInterruptedException"> </exception>
        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        //ORIGINAL LINE: private ConnectionPool getConnectionPoolAndCreateIfAbsent(String poolKey, java.util.concurrent.Callable<ConnectionPool> callable) throws exception.RemotingException, ThreadInterruptedException
        private ConnectionPool getConnectionPoolAndCreateIfAbsent(string poolKey, Callable callable)
        {
            RunStateRecordedFutureTask initialTask;
            ConnectionPool             pool = null;

            int retry = Constants.DEFAULT_RETRY_TIMES;

            int timesOfResultNull = 0;
            int timesOfInterrupt  = 0;

            for (int i = 0; (i < retry) && (pool == null); ++i)
            {
                connTasks.TryGetValue(poolKey, out initialTask);
                if (null == initialTask)
                {
                    RunStateRecordedFutureTask newTask = new RunStateRecordedFutureTask(callable);

                    if (!connTasks.ContainsKey(poolKey))
                    {
                        connTasks.AddOrUpdate(poolKey, newTask, (_, __) => newTask);
                        initialTask = newTask;
                    }
                    else
                    {
                        connTasks.TryGetValue(poolKey, out initialTask);
                    }

                    initialTask.run();
                }

                try
                {
                    pool = (ConnectionPool)initialTask.get();
                    if (null == pool)
                    {
                        if (i + 1 < retry)
                        {
                            timesOfResultNull++;
                            continue;
                        }
                        connTasks.TryRemove(poolKey, out _);
                        string errMsg = "Get future task result null for poolKey [" + poolKey + "] after [" + (timesOfResultNull + 1) + "] times try.";
                        throw new RemotingException(errMsg);
                    }
                }
                catch (ThreadInterruptedException e)
                {
                    if (i + 1 < retry)
                    {
                        timesOfInterrupt++;
                        continue; // retry if interrupted
                    }
                    connTasks.TryRemove(poolKey, out _);
                    logger.LogWarning("Future task of poolKey {} interrupted {} times. ThreadInterruptedException thrown and stop retry.", poolKey, timesOfInterrupt + 1, e);
                    throw;
                }
                catch (ExecutionException e)
                {
                    // DO NOT retry if ExecutionException occurred
                    connTasks.TryRemove(poolKey, out _);

                    System.Exception cause = e.InnerException;
                    if (cause is RemotingException)
                    {
                        throw (RemotingException)cause;
                    }
                    else
                    {
                        FutureTaskUtil.launderThrowable(cause);
                    }
                }
            }
            return(pool);
        }
示例#5
0
 /// <summary>
 /// get connection pool from future task
 /// </summary>
 /// <param name="task"> future task </param>
 /// <returns> connection pool </returns>
 private ConnectionPool getConnectionPool(RunStateRecordedFutureTask task)
 {
     return((ConnectionPool)FutureTaskUtil.getFutureTaskResult(task, logger));
 }