about summary refs log tree commit homepage
diff options
authorEric Wong <normalperson@yhbt.net>2011-12-05 01:33:41 +0000
committerEric Wong <normalperson@yhbt.net>2011-12-05 01:33:41 +0000
commitee6ffca0a8d129dd930f4c63d0c4c9ef034b245f (patch)
parent27f666a973a59c8c6738a65b69f9060c41e6958c (diff)
Even LANs can break or be unreliable sometimes and socket
disconnect messages get lost, which means we fall back to
the global (kill -9) timeout in Unicorn.

While the default global timeout is much shorter (60s) than
typical TCP timeouts, some HTTP application dispatches take much
I/O or computational time (streaming many gigabytes), so the
global timeout becomes ineffective.

Under Linux, sysadmins are encouraged to lower the default
net.ipv4.tcp_keepalive_* knobs in sysctl.  There should be
similar knobs in other operating systems (the default keepalive
intervals are usually ridiculously high, too high for anything).

When the listen socket has SO_KEEPALIVE set, the flag should be
inherited by accept()-ed sockets.
1 files changed, 4 insertions, 0 deletions
diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb
index 168a487..879ad6b 100644
--- a/lib/unicorn/socket_helper.rb
+++ b/lib/unicorn/socket_helper.rb
@@ -51,6 +51,10 @@ module Unicorn
     def set_tcp_sockopt(sock, opt)
+      # just in case, even LANs can break sometimes.  Linux sysadmins are
+      # can lower net.ipv4.tcp_keepalive_* sysctl knobs to very low values.
+      sock.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1) if defined?(SO_KEEPALIVE)
       if defined?(TCP_NODELAY)
         val = opt[:tcp_nodelay]
         val = DEFAULTS[:tcp_nodelay] if nil == val