-
Notifications
You must be signed in to change notification settings - Fork 523
Server deadlock #103
Comments
I don't get what you are talking about. What doesn't work with |
|
I'm noticing the same issue cross-platform. I'm having trouble creating a reliable trivial test. Relevant stack trace appears to be:
This will eventually leave my server running with no errors, accepting new requests but not responding, with the last request before the hang partly sent (probably at a TextWriter buffer boundary, judging by the stack trace) and open. Update: Kestrel entry from
|
When the mentioned Write hangs, the |
Unfortunately, no. This is all I have:
y matched the route with name '' and template ''.
Interestingly, if I leave out writing the blog entry body |
Just writing to confirm I am noticing the exact same thing on an Ubuntu LTS machine, latest DNX runtime, as well as locally on Windows 8.1. I'm not sure what triggered the issue - whether it was the new libuv release (1.4), or the new kestrel runtime. Up until I saw this issue, I assumed it was a problem with my own code deadlocking or something to do with the asp.net layer, but it seems the issue isn't present in IIS. I usually can't even get a single response to complete successfully on Kestrel - the response is written to the browser in full but the connection never closes (the little loading spinner in firefox never disappears). After that first request, the server accepts no further connections (so embedded images don't load, and often bootstrap libraries/other things that aren't in the main html don't load). I have noticed that if I put a breakpoint in somewhere and pause during the request (can be in the controller or a view) and slow the entire request down, it completes successfully. This is definitely indicative of some sort of race condition, getting stuck on that Write() seems to fit the bill. No exceptions in logging, log reads: info : [Microsoft.Framework.DependencyInjection.DataProtectionServices] User profile is available. Using 'C:\Users\USER\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. And that's all I get before it hangs indefinitely. |
I'm seeing the same thing with our MVC-using apps. I was able to work around the issue by introducing a middleware that wraps the request stream with a custom one, like so: public class StupidMiddleware
{
readonly RequestDelegate next;
public StupidMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext ctx)
{
var resp = ctx.Response;
// Replace the body stream with a fake one
var realBodyStream = resp.Body;
var fakeBody = new MemoryStream();
resp.Body = fakeBody;
await next(ctx);
// The fake body stream is closed, so make a new one
fakeBody = new MemoryStream(fakeBody.ToArray());
// Swap the real body stream back in
resp.Body = realBodyStream;
await fakeBody.CopyToAsync(resp.Body);
}
} I reproduced the deadlock again and attached to the Kestrel process. The stack trace for the hung thread is in https://gist.github.com/bojanrajkovic/45f31c6713608ee96c70, and shows Kestrel's
The wrapping middleware above seems to take care of the problem by making all of the elements that MVC deals with async-safe, thus preventing the deadlock. |
Thanks for the workaround, @bojanrajkovic! I've boiled it down (https://gist.github.com/mdekrey/59b93ab52cd130c4a2a8) if you're already using MVC. It should be noted that this needs to go first in your |
Nice, didn't know about |
Can confirm that I am able to replicate this problem on OS X Yosemite: after a number of requests, Kestrel would stop responding to any more. Kill process, restart, repeat. Very odd problem. So far, thanks to @mdekrey's variant of @bojanrajkovic's workaround, it's been up and running and now I can actually test ASP .NET applications for more than a few minutes. |
This makes Kestrel behave much better for me too (OSX/Yosemite/DNX latest). However it does seem to make Kestrel refuse to quit when you Ctrl+C After I ctrl+c it just sits there... then if I got to my browser and refresh the MVC page the browser shows an error then Kestrel quits. Usually with one of the following 2 errors:
Or
|
That particular issue is tracked here: #9 |
Agreed with @Tragetaschen - the Ctrl+C behavior was malfunctioning long before adding the workaround provided by @bojanrajkovic. |
Appears to be working for me as of |
If that's the problem, #60 solved this by filling the async gap from the FrameResponseStream into the Write method. All the callbacks are ultimately only used to transport a possible error to the higher layers which a TaskCompletionSource does very well. |
Doesn't look like it is resolved on OSX, dnvm version 1.0.0-beta6-12032, with |
@mdekrey I think I resolved this deadlock issue. I noticed a similar deadlock when running https://github.com/aspnet/MusicStore on Linux and fixed it with this commit. This is the same commit @davidfowl linked to earlier in the thread, but you'll need Kestrel 1.0.0-beta6-11852 or later to try it out. |
I'm getting deadlocks when making simultaneous requests with If I switch to any host besides kestrel on Windows, the issue disappears. |
Closing as we think this is fixed. If anyone repros with beta8 then create a new issue and link to this one. |
Right now, Kestrel invokes
Task.Wait()
in several places (one of them:KestrelHttpServer/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseStream.cs
Line 63 in 063fb64
In combination with MVC, this has quite fatal consequences: MVC asynchronously renders the page. It then disposes the output writer which in turn flushes the output stream. Because
IDisposable
is incompatible withasync
/await
, all of this is done synchronously, leading to the synchronousWrite
call. As a result, multiple requests (2 were already enough in all of my tests) lead to more and more server threads getting hung up inTask.Wait
, until they finally deadlock the entire server as the tasks they are waiting for never run.The text was updated successfully, but these errors were encountered: