Michael Fischer | 24 Mar 23:43 2015

nginx reverse proxy getting ECONNRESET

We have an nginx 1.6.2 proxy in front of a Unicorn 4.8.3 server that
is frequently reporting the following error:

2015/03/24 01:46:01 [error] 11217#0: *872231 readv() failed (104:
Connection reset by peer) while reading upstream

The interesting things are:

1) The upstream is a Unix domain socket (to which Unicorn is bound)
2) Unicorn isn't reporting that a child died in the error log (and I
verified their lifetimes with ps(1))

Any hints as to what we should look for?



胡明 | 24 Mar 16:28 2015

Is it possible to create a thread in Rails subscribe to Redis message channel?

Hi there

I have one question about related to thread in Unicorn; I have asked the
quesiton on stackoverflow.com but no one answers:


I also pasted the question in this email, hope that someone could help me
with this:


I am trying to create a thread in Rails to subscribe a message channel of
Redis. Is there a way to do this? I am using unicorn.

I have tried to do this in the unicorn configuration like this:

after_fork do |server, worker|

  Thread.new do
      $redis.subscribe(:one, :two) do |on|
        on.subscribe do |channel, subscriptions|
          puts "Subscribed to ##{channel} (#{subscriptions} subscriptions)"
        on.message do |channel, message|
          puts "##{channel}: #{message}"
          $redis.unsubscribe if message == "exit"
        on.unsubscribe do |channel, subscriptions|
(Continue reading)

Eric Wong | 12 Mar 23:32 2015

[PATCH] doc: document UNICORN_FD in manpage

Due to the prevalence of socket activation in modern init systems,
we shall document UNICORN_FD (previously an implementation detail)
in the manpage.
 Documentation/unicorn.1.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index 376a6c6..b03962e 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
 <at>  <at>  -163,6 +163,13  <at>  <at>  set in the old master process are inherited by the new master process.
 Unicorn only uses (and will overwrite) the UNICORN_FD environment
 variable internally when doing transparent upgrades.

+UNICORN_FD is a comma-delimited list of one or more file descriptors
+used to implement USR2 upgrades.  Init systems may bind listen sockets
+itself and spawn unicorn with UNICORN_FD set to the file descriptor
+numbers of the listen socket(s).  The unicorn CONFIG_FILE must still
+have the inherited listen socket parameters defined as in a normal
+startup, otherwise the socket will be closed.

 * unicorn_rails(1)


Eric Wong | 12 Mar 23:32 2015

[PATCH] doc: document Etc.nprocessors for worker_processes

Ruby 2.2 has Etc.nprocessors, and using that (directly or as a
factor) for setting worker_processes is often (but not always)
 TUNING | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/TUNING b/TUNING
index 542ebdc..6a6d7db 100644
--- a/TUNING
+++ b/TUNING
 <at>  <at>  -17,9 +17,12  <at>  <at>  See Unicorn::Configurator for details on the config file format.
   \Unicorn is NOT for serving slow clients, that is the job of nginx.

 * worker_processes should be *at* *least* the number of CPU cores on
-  a dedicated server.  If your application has occasionally slow
-  responses that are /not/ CPU-intensive, you may increase this to
-  workaround those inefficiencies.
+  a dedicated server (unless you do not have enough memory).
+  If your application has occasionally slow responses that are /not/
+  CPU-intensive, you may increase this to workaround those inefficiencies.
+* Under Ruby 2.2 or later, Etc.nprocessors may be used to determine
+  the number of CPU cores present.

 * worker_processes may be increased for Unicorn::OobGC users to provide
   more consistent response times.


(Continue reading)

Kevin Yank | 12 Mar 02:04 2015

On USR2, new master runs with same PID

Having recently migrated our Rails app to MRI 2.2.0 (which may or may not be related), we’re experiencing
problems with our Unicorn zero-downtime restarts.

When I send USR2 to the master process (PID 19216 in this example), I get the following in the Unicorn log:

I, [2015-03-11T23:47:33.992274 #6848]  INFO -- : executing
["/srv/ourapp/shared/bundle/ruby/2.2.0/bin/unicorn", "/srv/ourapp/current/config.ru",
"-Dc", "/srv/ourapp/shared/config/unicorn.rb",
{10=>#<Kgio::UNIXServer:/srv/ourapp/shared/sockets/unicorn.sock>}] (in /srv/ourapp/releases/a0e8b5df474ad5129200654f92a76af00a750f47)
I, [2015-03-11T23:47:36.504235 #6848]  INFO -- : inherited
addr=/srv/ourapp/shared/sockets/unicorn.sock fd=10
`pid=': Already running on PID:19216 (or pid=/srv/ourapp/shared/pids/unicorn.pid is stale) (ArgumentError)
/srv/ourapp/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.1/lib/unicorn/http_server.rb:134:in `start'
  from /srv/ourapp/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.1/bin/unicorn:126:in `<top (required)>'
  from /srv/ourapp/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `load'
  from /srv/ourapp/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `<main>'
E, [2015-03-11T23:47:36.519549 #19216] ERROR -- : reaped #<Process::Status: pid 6848 exit 1> exec()-ed
E, [2015-03-11T23:47:36.520296 #19216] ERROR -- : master loop error: Already running on PID:19216 (or
pid=/srv/ourapp/shared/pids/unicorn.pid is stale) (ArgumentError)
E, [2015-03-11T23:47:36.520496 #19216] ERROR -- :
/srv/ourapp/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.1/lib/unicorn/http_server.rb:206:in `pid='
E, [2015-03-11T23:47:36.520650 #19216] ERROR -- :
/srv/ourapp/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.1/lib/unicorn/http_server.rb:404:in `reap_all_workers'
E, [2015-03-11T23:47:36.520790 #19216] ERROR -- :
/srv/ourapp/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.1/lib/unicorn/http_server.rb:279:in `join'
E, [2015-03-11T23:47:36.520928 #19216] ERROR -- :
/srv/ourapp/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.1/bin/unicorn:126:in `<top (required)>'
E, [2015-03-11T23:47:36.521115 #19216] ERROR -- :
(Continue reading)

Sarkis Varozian | 3 Mar 23:24 2015

Request Queueing after deploy + USR2 restart

We have a rails application with the following unicorn.rb:

When we deploy to the application, a USR2 signal is sent to the unicorn
master which spins up a new master and we use the before_fork in the
unicorn.rb config above to send signals to the old master as the new
workers come online.

I've been trying to debug a weird issue that manifests as "Request
Queueing" in our Newrelic APM. The graph shows what happens after a
deployment (represented by the vertical lines). Here is the graph:
http://goo.gl/iFZPMv . As you see from the graph, it is inconsistent -
there is always a latency spike - however, at times Request Queueing is
higher than previous deploys.

Any ideas on what exactly is going on here? Any suggestions on
tools/profilers to use to get to the bottom of this? Should we expect this
to happen on each deploy?



*Sarkis Varozian*
svarozian <at> gmail.com

Eric Wong | 2 Mar 21:34 2015

[RFC] http: remove experimental dechunk! method

It was never used anywhere AFAIK and wastes precious bytes.
 RFC since this didn't go through a deprecation period, but it's
 never been documented or heavily publicized (but that goes for
 this entire project :P)

 ext/unicorn_http/unicorn_http.rl | 29 ---------------------------
 test/unit/test_http_parser_ng.rb | 43 ----------------------------------------
 2 files changed, 72 deletions(-)

diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
index 03b4726..4254540 100644
--- a/ext/unicorn_http/unicorn_http.rl
+++ b/ext/unicorn_http/unicorn_http.rl
 <at>  <at>  -590,34 +590,6  <at>  <at>  static VALUE HttpParser_clear(VALUE self)
   return self;

- * call-seq:
- *    parser.dechunk! => parser
- *
- * Resets the parser to a state suitable for dechunking response bodies
- *
- */
-static VALUE HttpParser_dechunk_bang(VALUE self)
-  struct http_parser *hp = data_get(self);
-  http_parser_init(hp);
(Continue reading)

Eric Wong | 2 Mar 21:32 2015

[PATCH] http: remove deprecated reset method

We use the `clear' method everywhere nowadays.
 ext/unicorn_http/unicorn_http.rl | 22 ----------------------
 1 file changed, 22 deletions(-)

diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
index 932d259..03b4726 100644
--- a/ext/unicorn_http/unicorn_http.rl
+++ b/ext/unicorn_http/unicorn_http.rl
 <at>  <at>  -618,27 +618,6  <at>  <at>  static VALUE HttpParser_dechunk_bang(VALUE self)
   return self;

- * call-seq:
- *    parser.reset => nil
- *
- * Resets the parser to it's initial state so that you can reuse it
- * rather than making new ones.
- *
- * This method is deprecated and to be removed in Unicorn 4.x
- */
-static VALUE HttpParser_reset(VALUE self)
-  static int warned;
-  if (!warned) {
-    rb_warn("Unicorn::HttpParser#reset is deprecated; "
-            "use Unicorn::HttpParser#clear instead");
-  }
(Continue reading)

Eric Wong | 2 Mar 21:24 2015

[PATCH] save about 200 bytes of memory on x86-64

Empty classes do not need a heavy class definition scope.
 lib/unicorn.rb | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index dd02761..467245d 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
 <at>  <at>  -21,8 +21,7  <at>  <at>  module Unicorn
   # since there is nothing in the application stack that is responsible
   # for client shutdowns/disconnects.  This exception is visible to Rack
   # applications unless PrereadInput middleware is loaded.
-  class ClientShutdown < EOFError
-  end
+  ClientShutdown = Class.new(EOFError)

   # :stopdoc:



Eric Wong | 18 Feb 10:36 2015

[PATCH] explain 11 byte magic number for self-pipe

Oops, this should've been explained long ago but apparently not.

In response to a comment on

> Does anybody know why both unicorn and foreman read 11 bytes from
> self-pipe?

Unfortunately I couldn't find a way to comment on the site on a
JavaScript-free browser nor does it seem possible without

Again, anybody can send plain-text mail to:
unicorn-public <at> bogomips.org

No registration, no real name policy, no terms-of-service, just
plain-text.  Feel free to use Tor, mixmaster or any anonymity
service, too.
 lib/unicorn/http_server.rb | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 015bd94..683eb82 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
 <at>  <at>  -370,6 +370,10  <at>  <at>  class Unicorn::HttpServer
   # wait for a signal hander to wake us up and then consume the pipe
   def master_sleep(sec)
     IO.select([  <at> self_pipe[0] ], nil, nil, sec) or return
(Continue reading)

Steven Stewart-Gallus | 16 Feb 03:19 2015

Bug, Unicorn can drop signals in extreme conditions


While reading the article at
http://www.sitepoint.com/the-self-pipe-trick-explained/ I realized
that the signal handling code shown there and of the same type in your
application is broken.  As you have a single nonblocking pipe in your
application you can drop signals entirely (and not just fold multiple
signals of the same type into one).  The simplest fix is to use a pipe
for each individual type of signal or to just use pselect or similar.
I'm pretty sure that there is a way to use a single pipe but it seems
complicated and very difficult to implement correctly.

Thank you,
Steven Stewart-Gallus