-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
net: timed out socket blocks process termination #795
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
Comments
Here's some debug: WiFi on:
WiFi off:
edit: added |
I think there are actually two issues here:
|
I couldn't reproduce, when I turn my wifi (only net connection) off on OS X, I hit the error path with ENOTFOUND. I'm not saying its not a bug, but its not trivially reproducible. |
@sam-github I think what you're seeing is the local dns cache on your mac (which is probably disabled on my machine). Try this between runs: http://support.apple.com/en-us/HT202516 |
Sorry, didn't help. |
Give it one more try with |
|
Hrm, must be some special condition on my machine that I don't run into any error with WiFi down. I also tried connecting to an IP, but that gave me a quick ENETUNREACH. |
Can it be that this is nodejs/node-v0.x-archive#7077 or nodejs/node-v0.x-archive#7149? |
nodejs/node-v0.x-archive#7149 could be it, given that it errors correctly on an IP but not an hostname. Your mentioned 5-30 sec glibc timeout could be what I'm seeing. Anything that speaks against making |
Are you sure you are calling it? process.exit is pretty direct: |
Yes, I get the var socket = new require("net").Socket();
process.on("exit", console.log.bind(console, "exit"));
socket.unref();
socket.setTimeout(1000, function() {
console.log("timeout");
process.exit();
})
socket.connect(80, "does.not.exist"); which prints
and hangs 29 seconds afterwards. Maybe the libuv call happens in another thread which keeps the main threat from exiting? (You see, I have no idea how this works) |
That's correct. Libuv shuts down the thread pool gracefully on exit. In your test case however, one of the threads is still locked up in the libc getaddrinfo() call. That's intentional, by the way. Force-killing a thread may lead to unpredictable behavior. |
Makes sense, but I still think there should be a way to force termination if I don't care about pending operations. How about something like |
What I mean with 'unpredictable' is that force-killing threads is a great way to crash the process or corrupt data. |
Are there less dangerous ways to signal all libuv (or or threads) to stop whatever they are doing? Does libuv support something like SIGTERM? |
Not really. Sending signals wouldn't really help, not in general, because whatever operation is ongoing might not be interruptible. POSIX threads have the concept of cancellable operations (see It requires that you carefully write your application code around the fact that execution may cease at almost any point. The thread pool is a general purpose pool and may execute user code that is not written with that assumption in mind. It would require splitting the thread pool in two, one for user tasks, the other for libuv internal tasks (at least, conceptually; in practice, it would probably be a per-thread status flag.) It's not a bad idea and not just because of this issue but it's a lot of work. Also, it won't help on Windows. To the best of my knowledge, Windows only has TerminateThread() and that's like sending a SIGKILL to a thread. |
Alright, thanks for the detailed explanation. Maybe the route of adding |
closing this issue here in favor of libuv/libuv#203, because both feasible solutions depend on changes in libuv. |
@bnoordhuis maybe you can open a second libuv issue for the |
It seems that when a unref()'ed socket runs into a timeout, the program keeps running for 30 seconds after the event, even when calling
process.exit
. I reproduced it with below example, on OS X with WiFi (my only network connection) disabled:With Wifi enabled, the socket runs the
error
callback and the process exits immediately as expected. I also attempted to release the socket withsocket.destroy()
andsocket.end()
but that didn't have any effect.I found these related commits:
nodejs/node-v0.x-archive@f46ad01
nodejs/node-v0.x-archive@a846d93
The issue exists in the 0.10 branch too.
The text was updated successfully, but these errors were encountered: