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