Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileModule or StaticFolderModule get stuck returning medium files #574

Open
lucapivato opened this issue Dec 12, 2022 · 4 comments
Open
Labels
area:http Issue with HttpListener and related types bug v3.x

Comments

@lucapivato
Copy link

Describe the bug

Using server.WithStaticFolder() or server.WithModule(new FileModule()) seems to get stuck when returning files more than a few kb.

It takes over 25 seconds to return about 1MB, it hangs the browser with an open connection. After that even reading favicon.ico takes 18 seconds and hangs Chrome.

To Reproduce

var server = new WebServer(o => o.WithUrlPrefix("http://localhost:5000"));
server.WithStaticFolder("/", contentRoot, true);
server.RunAsync();
Console.ReadLine();

Expected behavior

Enter http://localhost:5000/test.js (or any other file) and receive the file.

Screenshots

image

@rdeago rdeago added bug v3.x area:http Issue with HttpListener and related types labels Dec 12, 2022
@rdeago
Copy link
Collaborator

rdeago commented Dec 12, 2022

Hello @lucapivato, thanks for using EmbedIO!

I agree with you that something is wrong here, but I'm not sure it's FileModule's fault.

As your screenshot shows, the request for favicon.ico went through WebServerBase<TOptions>.DoHandleContextAsync in about one millisecond (15:19:01.404 > 15:19:01.405). For reference, here is the code that writes the first and last log lines related to the request, at line 236 at 286 respectively.

Still, when the last of the three involved lines is logged, the HTTP context has an age (time elapsed since creation) of more than 18 seconds. This seems to indicate that most of that time was spent between the creation of the HTTP context and its handling, therefore in the not-yet-fully-explored (by me, at least) territory of HttpListener and related classes.

If you can (i.e. if your server runs on Windows) try replacing the first line of your code with the following and see if you observe the same behavior:

var server = new WebServer(o => o
    .WithMode(HttpListenerMode.Microsoft)
    .WithUrlPrefix("http://localhost:5000/"));

Also, the log of the first overly-delayed request and the two or three previous requests might help.

@lucapivato
Copy link
Author

lucapivato commented Dec 12, 2022

Yes, favicon is a side effect. After returning a js file of about 1Mb to 6Mb it starts hanging for other files too. I tried returning it directly WithAction() and using the OpenResponseStream() but it's more or less the same, the browser keeps spinning as if the connection was kept open. Tried closing the stream, flushing, etc. Tried writing directly to the OutputStream but same reasult.

.WithMode(HttpListenerMode.Microsoft) didn't change the behavior.

In case you want to test it, I have attached one of the js files. I don't know if the issue is the UTF-8 encoding (at one point we got an exception related to the 1252 encoding on MAUI but cannot reproduce), we tried with a 6Mb xml file and it worked fine. Tried the managed HttpListener directly in Windows and iOS with the same files and it worked fine.

Wisej.Platform.qx.zip

Thank you.

@rdeago
Copy link
Collaborator

rdeago commented Dec 13, 2022

Thanks for the file, but this issue does not seem to be about the specific file being requested.

The delay happens before EmbedIO even has a chance of dispatching the request; that's why using an ActionModule makes no difference. It looks like the request gets stuck in EmbedIO's request queue, as if the thread pool has no thread left to handle it, which is unusual to say the least.

Can you get a screenshot showing the sequence of requests made to the server? I think Chrome's DevTools may help with this.

A complete log from the server may also be of help. You can activate logging on file by adding the following line before server initialization:

using Swan.Logging; // <-- You need this too

Logger.RegisterLogger(new FileLogger("PATH_TO_LOG_FILE", false));

@cho-trackman
Copy link

I'm stuck debugging this issue. I did come to the same conclusion that the thread pool get exhausted somehow, because all "life signs" vanishes after hitting the issue.
It seems to affect all module types.
For now my "solution" is to keep the JSON responses under 1MB (which is sometimes needed).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:http Issue with HttpListener and related types bug v3.x
Projects
None yet
Development

No branches or pull requests

3 participants