-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Fix leaks in HTTP::Server specs #7197
Fix leaks in HTTP::Server specs #7197
Conversation
The CI failure shows there are even more specs leaking open ports in other files. I'll take a look at it tomorrow. |
59a4d98
to
f256ff6
Compare
The |
@j8r No it's not. I'm mainly using it to manually detect any leaking open ports. It's not solid enough to be included in automatic tests. That being said, it would be nice if specs could automatically fail if they leak fibers or open file descriptors. I don't think this can be implemented, though. |
e0e8e33
to
e4e0a5d
Compare
fd782e2
to
24c3f37
Compare
This PR is ready for review. It hopefully removes all interdependencies between individual server specs, and so far it looks good. The initial example with deactivating a specific spec no longer reproduces. I've run over a thousand permutations of specs (random order + leaving some out) and found no other breaking specs. This should eliminate fiber and port leaks in most places of the stdlib spec suite. A few specs specs still leak fibers (see CI results). Some are caused by the implementation of The websocket spec The |
9a97619
to
e4e0a5d
Compare
e4e0a5d
to
f8ef17f
Compare
@straight-shoota I'd really like to see this merged. IMHO this is as good as it's, just needs a rebase. |
f8ef17f
to
a6c98eb
Compare
If I checkout this branch and run: bin/crystal spec spec/std/http/client/client_spec.cr I get:
in four specs. I don't know what's going on... This is on mac osx. I don't know why CI is happy. |
I don't have a Mac, can anyone reproduce? Which specs are failing exactly? And is it this plain branch or with |
@straight-shoota The specs that fail for me, without
What I see happening is: the server writes the response and then does If I put However, I don't understand now why it never happens that the server ends up raising because of writing the response after waiting for And also, if you try it locally but put everything inside |
Okay, so it effectively happens in all the specs using However, I can't reproduce any such error on linux. So it seems to be specific to MacOS. But since it doesn't trigger on CI, there must be something else to it. Would be great if a few Mac users could test this on other machines. |
a6c98eb
to
932035a
Compare
I'd like to see this merged. New PRs like #7610 add specs that could benefit from the spec helpers defined here. I can't debug the issues on MacOS. But they seem to be related to changes to the |
Oh, I thought this was already merged. Yes, let's please merge this in whatever way that works. |
932035a
to
091d0ec
Compare
@asterite I removed the changes to |
|
Ooops, sry. Fixed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@straight-shoota It's working fine now, thanks!
Feel free to merge. Then I'll rebase the |
`#bind_tcp`, `#bind_unix` and `#bind_tls` would bind a new socket and try to add it to the server. If that failed (because the server was already closed), it would raise an error but the newly created socket would not be terminated, effectively leaking it.
Spec helper for concurrently running an `HTTP::Server` in a spec and finally closing it before continuing execution in the parent scope.
197243c
to
2f07b56
Compare
This fixes several issues with
HTTP::Server
specs.Previously, there were some weird influences between individual specs. For example, when disabling
handles exception during SSL handshake
(e.g. marking itpending
), the following speccloses gracefully
would fail with the following error:@RX14 had already identified reusing fildescriptors by leftover fibers as probable reason.
And in fact, a large number of specs was not fully contained and leaking either open ports or unstopped fibers.
One issue was an actual bug in
HTTP::Server#bind_tcp
(and similar methods) which would bind a new socket and try to add it to the server. If that failed (because the server was already closed), it would raise an error but the newly created socket would not be terminated.The other issues were all introduced by the specs themselves, a few missing
server.close
.I also added a helper
run_server
which starts the server in a new fiber, then yields to a block for interacting with it and finally ensures that it is properly shut down. This should avoid any breaking specs from leaking server fibers.I'm not sure if
ensure_no_ports_leaking
should stay around. It's rather rudimentary. If a open port is leaked at some point, all following specs will fail because of this.This might not fix all the issues and I still don't completely understand the reasons why exactly one spec failed when the other was deactivated. But it already improves quite a lot.
I'll try to run the specs randomized to see if there might be any other issues with couplings between specs.