/// <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 _); } }
/// <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); } }
/// <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); }
/// <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)); }