Bug 11833 - HttpWebRequest times out when called in fastcgi-mono-server4, thread issue
Summary: HttpWebRequest times out when called in fastcgi-mono-server4, thread issue
Status: RESOLVED NOT_REPRODUCIBLE
Alias: None
Product: Class Libraries
Classification: Mono
Component: System ()
Version: master
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-04-17 16:00 UTC by Timotheus Pokorra
Modified: 2016-01-31 07:07 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
showing how to call HttpWebRequest from within a web service (855 bytes, text/x-csharp)
2013-04-17 16:00 UTC, Timotheus Pokorra
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NOT_REPRODUCIBLE

Description Timotheus Pokorra 2013-04-17 16:00:17 UTC
I have a server running with fastcgi-mono-server, and need to access another web service from within my own web service.

I have noticed people having issues already a year ago:
 http://lists.ximian.com/pipermail/mono-aspnet-list/2012-February/001530.html

I then noticed a commit to trunk 2 months ago, which did solve the problem for me:
 https://github.com/mono/mono/commit/8c2167d52cb9acf9582647ebb5f99c92d9127fbd
 https://github.com/mono/mono/pull/550: [HttpWebRequest] Avoid using the threadpool for synchronous requests
But then it was reverted:
 https://github.com/mono/mono/commit/14f0405443693ec2586e73e4b3746134046210d5

Comment from Miguel was:
The reason is:
"The HttpWebRequests tests are not enough"
"A quick review of the code shows that the code is taking a lock, while
calling a function that retries connections (which in turn takes another
important lock --for the socket--) which might casue a stack overflow
if someone calls SetWriteStream"
"This also will make the opereation sync when calling Begin/End"
"Finally, this is a patch that improves the use of the threadpool, but
the threadpool still will end up exhausted"
Probably best to just increase the number of threads?


My question is, if there is a cleaner way, that will still accomplish being able to read web services from within your own web service?

Thanks,
  Timotheus
Comment 1 Timotheus Pokorra 2013-04-17 16:00:57 UTC
Created attachment 3826 [details]
showing how to call HttpWebRequest from within a web service
Comment 2 Andres G. Aragoneses 2013-04-19 06:03:20 UTC
Hi Timotheus, thanks for filing this bug.

I wrote the patch that later was reverted.

I haven't had time much time to try to understand the reasons of why it was reverted. But maybe you can help me with it so we can come with a better patch? If you're interested, this is how far I got:

- My guess is that I broke the scenario of WebException timeouts being fired when the request takes longer than its timeout, because with my fix, a synchronous request doesn't get blocked anymore in this line (939) of HttpWebRequest.cs:

  if (!result.WaitUntilComplete (timeout, false)) {

- Sadly this means that timeouts are not covered by unit tests in Mono. So we should implement one so next time we propose a patch to fix this bug, we're sure that we don't break timeouts. To come up with a unit test, I've looked at how were timeouts implemented in mono in the past. I used the blame-feature of github in this file (https://github.com/mono/mono/blame/8c2167d52cb9acf9582647ebb5f99c92d9127fbd/mcs/class/System/System.Net/WebConnection.cs) so I could locate the exact commit, which I believe is the following:

https://github.com/mono/mono/commit/e1bb8604984ef15ec9e8e36bf22e46585bde53ea

That commit refers to this bug ( https://bugzilla.novell.com/show_bug.cgi?id=MONO74177 ) which contains a testcase. I guess we can convert that testcase to a unit test.

- And when we have done this, we will think about fixing this bug again.
Comment 3 Andres G. Aragoneses 2013-04-20 13:46:04 UTC
(In reply to comment #2)
> That commit refers to this bug (
> https://bugzilla.novell.com/show_bug.cgi?id=MONO74177 ) which contains a
> testcase. I guess we can convert that testcase to a unit test.

I finished this today, and this is the result: https://github.com/mono/mono/pull/617

Hopefully it will be merged/reviewed soon, and then:


> - And when we have done this, we will think about fixing this bug again.

The first approach I'm thinking is, in the synchronous case, stop using a ManualResetEvent in WebAsyncResult.cs, but a System.Threading.Timer. This would mean that the way to control the timeout would not mean 2 threads per synchronous web request, but one thread in the beginning, and a 2nd thread (from the threadpool) *only* if the timeout is reached.
Comment 4 Timotheus Pokorra 2013-04-23 08:51:25 UTC
Thank you Andres for looking into this!
I see that your test has been merged into trunk already, which is good!
https://github.com/mono/mono/commit/0e5dd1f51a0dc59f1ada718ccba4622666beb434

I like what you are doing.
Not so sure how I can help. This is quite some levels above what I am used to.

Somehow there is a locking situation, with threads being used, so it would be good to avoid using a thread if possible.
Comment 5 Timotheus Pokorra 2015-02-09 11:48:14 UTC
I think this problem has been resolved meanwhile.

I don't need the workaround from https://github.com/mono/mono/pull/550 anymore.

With Mono 3.12.0 it just works, I cannot reproduce this issue anymore.
Comment 6 cnhx27 2016-01-31 07:07:17 UTC
I think this problem has not been resolve
I reproduce it with Mono 4.2.1 with this code: 
    WebProxy webProxy = new WebProxy(proxyUri, true);
    webProxy.Credentials = new NetworkCredential(proxyUserName, proxyPassword);
    WebRequest request = WebRequest.Create(targetUri);
    request.Proxy = webProxy;
    request.Method = "CONNECT";
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();  
    Stream responseStream = response.GetResponseStream();

It failed immediately with an Unhandled Exception:
System.Net.WebException: The remote server returned an error: (504) Gateway Time-out.
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) <0xb464dc48 + 0x0018c> in <filename unknown>:0
  at System.Net.HttpWebRequest.GetResponse () <0xb4646470 + 0x0006b> in <filename unknown>:0