Background jobs with #fork

Eric Wong normalperson at
Thu Apr 12 22:10:22 UTC 2012

Hongli Lai <hongli at> wrote:
> On Thu, Apr 12, 2012 at 10:39 PM, Eric Wong <normalperson at> wrote:
> > paddor wrote:
> >> The problem persists even when multiple workers are started. And the
> >> problem was not present in the old setup with Passenger.
> >
> > The difference between nginx+unicorn and Passenger is probabably: nginx
> > relies on unicorn generating an EOF to signal the end-of-response (nginx
> > <-> unicorn uses HTTP/1.0), this I'm sure about.  I think Passenger uses a
> > protocol which can signal the end-of-request inline without relying on
> > an EOF on the socket (Hongli can correct me on this if I'm wrong).
> We don't. We call #close_write on the socket to prevent this problem.
> #close_write calls shutdown(fd, SHUT_WR) which isn't affected by the
> number of processes that have inherited the socket handle.

Ah, thanks for that clarification.  It's an extra syscall for an
uncommon case, but I doubt most apps will notice the hit...

Might as well shutdown(SHUT_RDWR), too:

diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index ede6264..f942e2f 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -536,6 +536,7 @@ class Unicorn::HttpServer
     @request.headers? or headers = nil
     http_response_write(client, status, headers, body)
+    client.shutdown # in case of fork() in Rack app
     client.close # flush and uncork socket immediately, no keepalive
   rescue => e
     handle_error(client, e)

More information about the mongrel-unicorn mailing list