Skip to content

Commit c2b7638

Browse files
authored
[HTTP] Scavange fix (#61530)
* Guard pool scavenging callback from parallel execution when it takes longer than the timer interval gets triggered * Dispose connection from the pool in a serate task to not to block the caller (scavenge timer callback) * feedback
1 parent f1edeed commit c2b7638

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1979,7 +1979,12 @@ public bool CleanCacheAndDisposeIfUnused()
19791979
}
19801980

19811981
// Dispose the stale connections outside the pool lock, to avoid holding the lock too long.
1982-
toDispose?.ForEach(c => c.Dispose());
1982+
// Dispose them asynchronously to not to block the caller on closing the SslStream or NetworkStream.
1983+
if (toDispose is not null)
1984+
{
1985+
Task.Factory.StartNew(static s => ((List<HttpConnectionBase>)s!).ForEach(c => c.Dispose()), toDispose,
1986+
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
1987+
}
19831988

19841989
// Pool is active. Should not be removed.
19851990
return false;

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ private void SetCleaningTimer(TimeSpan timeout)
462462
{
463463
try
464464
{
465-
_cleaningTimer!.Change(timeout, timeout);
465+
_cleaningTimer!.Change(timeout, Timeout.InfiniteTimeSpan);
466466
_timerIsRunning = timeout != Timeout.InfiniteTimeSpan;
467467
}
468468
catch (ObjectDisposedException)
@@ -492,13 +492,10 @@ private void RemoveStalePools()
492492
}
493493
}
494494

495-
// Stop running the timer if we don't have any pools to clean up.
495+
// Restart the timer if we have any pools to clean up.
496496
lock (SyncObj)
497497
{
498-
if (_pools.IsEmpty)
499-
{
500-
SetCleaningTimer(Timeout.InfiniteTimeSpan);
501-
}
498+
SetCleaningTimer(!_pools.IsEmpty ? _cleanPoolTimeout : Timeout.InfiniteTimeSpan);
502499
}
503500

504501
// NOTE: There is a possible race condition with regards to a pool getting cleaned up at the same

0 commit comments

Comments
 (0)