ServicePoint safety checks to prevent blocking on new HttpWebRequests
-
04-03-2021 - |
Question
I'm using a 3rd party library that makes a number of http calls. By decompiling the code, I've determined that it is creating and using raw HttpWebRequest
's, all going to a single URL. The issue is that some of the requests don't get closed properly. After some time, all new HttpWebRequest
's block forever when the library calls GetRequestStream()* on them. I've determined this blocking is due to the ConnectionLimit on the ServicePoint for that particular host, which has the default value of 2. In other words, the library has opened 2 requests, and then tries to open a 3rd, which blocks.
I want to protect against this blocking. The library is fairly resilient and will reconnect itself, so it's okay if I kill the existing connections it has made. The problem is that I don't have access to any of the HttpWebRequest
or HttpWebResponse
s this library makes. However I do know the URL it accesses and therefore I can access the ServicePoint
for it.
var sp = ServicePointManager.FindServicePoint(new Uri("http://UrlThatIKnowAbout.com"));
(Note: KeepAlive is enabled on these HttpWebRequests)
Solution
This worked, though I'm not sure it's the best way to solve the problem.
- Get the service point object for the url
var sp = ServicePointManager.FindServicePoint(new Uri("http://UrlThatIKnowAbout.com"));
- Increase the
ConnectionLimit
toint.MaxValue
- Create a background thread that periodically checks the
ConnectionCount
on the service point. If it goes above 5, callCloseConnectionGroup()
- Set
MaxIdleTime
to 1 hour (instead of default)
Setting the ConnectionLimit
should prevent the blocking. The monitor thread will ensure that too many connections are never active at the same time. Setting MaxIdleTime
should serve as a fall back.