unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 0/4] a small pile of patches
@ 2024-03-23 19:45  4% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2024-03-23 19:45 UTC (permalink / raw)
  To: unicorn-public

[-- Attachment #1: Type: text/plain, Size: 4446 bytes --]

Some stuff to future-proof against future Ruby incompatibilities.
More coming....

I've also pushed out preliminary work (started in 2021) to the
`pico' branch to switch the HTTP parser from Ragel to
picohttpparser.  It will simplify the build + maintenance,
especially when distros carry different Ragel versions (or don't
package it all, as some hackers can't afford bandwidth and disk
for a C++ toolchain).

Other notes: New releases will probably be hosted on yhbt.net if
the Rubygems.org MFA threshold is reached.  Caring about the
identity of hackers is totally misguided when we already show
our code (and even document it!).  If you can't audit the code
yourself, get an actual professional to do it and don't bother
amateurs like me.

Eric Wong (4):
  t/integration: disable proxies when running curl(1)
  tests: port back-out-of-upgrade to Perl 5
  doc: various updates and disclaimers
  treewide: future-proof frozen_string_literal changes

 HACKING                             |  13 +++-
 README                              |   9 +++
 Rakefile                            |   1 +
 TODO                                |   4 +-
 bin/unicorn                         |   1 +
 bin/unicorn_rails                   |   1 +
 examples/big_app_gc.rb              |   1 +
 examples/echo.ru                    |   1 +
 examples/logger_mp_safe.rb          |   1 +
 examples/unicorn.conf.minimal.rb    |   1 +
 examples/unicorn.conf.rb            |   1 +
 ext/unicorn_http/extconf.rb         |   1 +
 lib/unicorn.rb                      |   1 +
 lib/unicorn/app/old_rails.rb        |   1 +
 lib/unicorn/app/old_rails/static.rb |   1 +
 lib/unicorn/cgi_wrapper.rb          |   1 +
 lib/unicorn/configurator.rb         |   1 +
 lib/unicorn/const.rb                |   1 +
 lib/unicorn/http_request.rb         |   1 +
 lib/unicorn/http_response.rb        |   1 +
 lib/unicorn/http_server.rb          |   1 +
 lib/unicorn/launcher.rb             |   1 +
 lib/unicorn/oob_gc.rb               |   1 +
 lib/unicorn/preread_input.rb        |   1 +
 lib/unicorn/select_waiter.rb        |   1 +
 lib/unicorn/socket_helper.rb        |   1 +
 lib/unicorn/stream_input.rb         |   1 +
 lib/unicorn/tee_input.rb            |   1 +
 lib/unicorn/tmpio.rb                |   1 +
 lib/unicorn/util.rb                 |   1 +
 lib/unicorn/worker.rb               |   1 +
 setup.rb                            |   1 +
 t/back-out-of-upgrade.t             |  44 +++++++++++
 t/broken-app.ru                     |   1 +
 t/client_body_buffer_size.ru        |   1 +
 t/detach.ru                         |   1 +
 t/env.ru                            |   1 +
 t/fails-rack-lint.ru                |   1 +
 t/heartbeat-timeout.ru              |   1 +
 t/integration.ru                    |   1 +
 t/integration.t                     |   1 +
 t/lib.perl                          |  67 ++++++++++++++---
 t/listener_names.ru                 |   1 +
 t/oob_gc.ru                         |   1 +
 t/oob_gc_path.ru                    |   1 +
 t/pid.ru                            |   1 +
 t/preread_input.ru                  |   1 +
 t/reopen-logs.ru                    |   1 +
 t/t0008-back_out_of_upgrade.sh      | 110 ----------------------------
 t/t0013.ru                          |   1 +
 t/t0014.ru                          |   1 +
 t/t0301.ru                          |   1 +
 test/aggregate.rb                   |   1 +
 test/benchmark/dd.ru                |   1 +
 test/benchmark/ddstream.ru          |   1 +
 test/benchmark/readinput.ru         |   1 +
 test/benchmark/stack.ru             |   1 +
 test/exec/test_exec.rb              |   1 +
 test/test_helper.rb                 |   1 +
 test/unit/test_ccc.rb               |   1 +
 test/unit/test_configurator.rb      |   1 +
 test/unit/test_droplet.rb           |   1 +
 test/unit/test_http_parser.rb       |   1 +
 test/unit/test_http_parser_ng.rb    |   1 +
 test/unit/test_request.rb           |   1 +
 test/unit/test_server.rb            |   1 +
 test/unit/test_signals.rb           |   1 +
 test/unit/test_socket_helper.rb     |   1 +
 test/unit/test_stream_input.rb      |   1 +
 test/unit/test_tee_input.rb         |   1 +
 test/unit/test_util.rb              |   1 +
 test/unit/test_waiter.rb            |   1 +
 unicorn.gemspec                     |   1 +
 73 files changed, 188 insertions(+), 126 deletions(-)
 create mode 100644 t/back-out-of-upgrade.t
 delete mode 100755 t/t0008-back_out_of_upgrade.sh

[-- Attachment #2: 0001-t-integration-disable-proxies-when-running-curl-1.patch --]
[-- Type: text/x-diff, Size: 737 bytes --]

From f3acce5dce62ac4b0288d3c0ddf0a6db2cbd9e7f Mon Sep 17 00:00:00 2001
From: Eric Wong <BOFH@YHBT.net>
Date: Tue, 9 Jan 2024 21:35:08 +0000
Subject: [PATCH 1/4] t/integration: disable proxies when running curl(1)

This was also done in t/test-lib.sh, but using '*' is more
encompassing.
---
 t/integration.t | 1 +
 1 file changed, 1 insertion(+)

diff --git a/t/integration.t b/t/integration.t
index 7310ff2..d17ace0 100644
--- a/t/integration.t
+++ b/t/integration.t
@@ -27,6 +27,7 @@ listen "$u1"
 EOM
 my $ar = unicorn(qw(-E none t/integration.ru -c), $u_conf, { 3 => $srv });
 my $curl = which('curl');
+local $ENV{NO_PROXY} = '*'; # for curl
 my $fifo = "$tmpdir/fifo";
 POSIX::mkfifo($fifo, 0600) or die "mkfifo: $!";
 my %PUT = (

[-- Attachment #3: 0002-tests-port-back-out-of-upgrade-to-Perl-5.patch --]
[-- Type: text/x-diff, Size: 8889 bytes --]

From 724fb631c76f09964ec289ee8e144886ba15d380 Mon Sep 17 00:00:00 2001
From: Eric Wong <BOFH@YHBT.net>
Date: Mon, 6 Nov 2023 05:45:29 +0000
Subject: [PATCH 2/4] tests: port back-out-of-upgrade to Perl 5

Another place where we can be faster without adding more
dependencies on Ruby maintaining stable behavior.
---
 t/back-out-of-upgrade.t        |  44 +++++++++++++
 t/lib.perl                     |  67 +++++++++++++++++---
 t/t0008-back_out_of_upgrade.sh | 110 ---------------------------------
 3 files changed, 102 insertions(+), 119 deletions(-)
 create mode 100644 t/back-out-of-upgrade.t
 delete mode 100755 t/t0008-back_out_of_upgrade.sh

diff --git a/t/back-out-of-upgrade.t b/t/back-out-of-upgrade.t
new file mode 100644
index 0000000..cf3b09f
--- /dev/null
+++ b/t/back-out-of-upgrade.t
@@ -0,0 +1,44 @@
+#!perl -w
+# Copyright (C) unicorn hackers <unicorn-public@yhbt.net>
+# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
+# test backing out of USR2 upgrade
+use v5.14; BEGIN { require './t/lib.perl' };
+use autodie;
+my $srv = tcp_server();
+mkfifo_die $fifo;
+write_file '>', $u_conf, <<EOM;
+preload_app true
+stderr_path "$err_log"
+pid "$pid_file"
+after_fork { |s,w| File.open('$fifo', 'w') { |fp| fp.write "pid=#\$\$" } }
+EOM
+my $ar = unicorn(qw(-E none t/pid.ru -c), $u_conf, { 3 => $srv });
+
+like(my $wpid_orig_1 = slurp($fifo), qr/\Apid=\d+\z/a, 'got worker pid');
+
+ok $ar->do_kill('USR2'), 'USR2 to start upgrade';
+ok $ar->do_kill('WINCH'), 'drop old worker';
+
+like(my $wpid_new = slurp($fifo), qr/\Apid=\d+\z/a, 'got pid from new master');
+chomp(my $new_pid = slurp($pid_file));
+isnt $new_pid, $ar->{pid}, 'PID file changed';
+chomp(my $pid_oldbin = slurp("$pid_file.oldbin"));
+is $pid_oldbin, $ar->{pid}, '.oldbin PID valid';
+
+ok $ar->do_kill('HUP'), 'HUP old master';
+like(my $wpid_orig_2 = slurp($fifo), qr/\Apid=\d+\z/a, 'got worker new pid');
+ok kill('QUIT', $new_pid), 'abort old master';
+kill_until_dead $new_pid;
+
+my ($st, $hdr, $req_pid) = do_req $srv, 'GET /';
+chomp $req_pid;
+is $wpid_orig_2, "pid=$req_pid", 'new worker on old worker serves';
+
+ok !-f "$pid_file.oldbin", '.oldbin PID file gone';
+chomp(my $old_pid = slurp($pid_file));
+is $old_pid, $ar->{pid}, 'PID file restored';
+
+my @log = grep !/ERROR -- : reaped .*? exec\(\)-ed/, slurp($err_log);
+check_stderr @log;
+undef $tmpdir;
+done_testing;
diff --git a/t/lib.perl b/t/lib.perl
index 9254b23..b20a2c6 100644
--- a/t/lib.perl
+++ b/t/lib.perl
@@ -6,30 +6,58 @@ use v5.14;
 use parent qw(Exporter);
 use autodie;
 use Test::More;
+use Socket qw(SOMAXCONN);
 use Time::HiRes qw(sleep time);
 use IO::Socket::INET;
+use IO::Socket::UNIX;
+use Carp qw(croak);
 use POSIX qw(dup2 _exit setpgid :signal_h SEEK_SET F_SETFD);
 use File::Temp 0.19 (); # 0.19 for ->newdir
 our ($tmpdir, $errfh, $err_log, $u_sock, $u_conf, $daemon_pid,
-	$pid_file);
+	$pid_file, $wtest_sock, $fifo);
 our @EXPORT = qw(unicorn slurp tcp_server tcp_start unicorn
 	$tmpdir $errfh $err_log $u_sock $u_conf $daemon_pid $pid_file
+	$wtest_sock $fifo
 	SEEK_SET tcp_host_port which spawn check_stderr unix_start slurp_hdr
-	do_req stop_daemon sleep time);
+	do_req stop_daemon sleep time mkfifo_die kill_until_dead write_file);
 
 my ($base) = ($0 =~ m!\b([^/]+)\.[^\.]+\z!);
 $tmpdir = File::Temp->newdir("unicorn-$base-XXXX", TMPDIR => 1);
+
+$wtest_sock = "$tmpdir/wtest.sock";
 $err_log = "$tmpdir/err.log";
 $pid_file = "$tmpdir/pid";
+$fifo = "$tmpdir/fifo";
 $u_sock = "$tmpdir/u.sock";
 $u_conf = "$tmpdir/u.conf.rb";
 open($errfh, '>>', $err_log);
 
+if (my $t = $ENV{TAIL}) {
+	my @tail = $t =~ /tail/ ? split(/\s+/, $t) : (qw(tail -F));
+	push @tail, $err_log;
+	my $pid = fork;
+	if ($pid == 0) {
+		open STDOUT, '>&', \*STDERR;
+		exec @tail;
+		die "exec(@tail): $!";
+	}
+	say "# @tail";
+	sleep 0.2;
+	UnicornTest::AutoReap->new($pid);
+}
+
+sub kill_until_dead ($;%) {
+	my ($pid, %opt) = @_;
+	my $tries = $opt{tries} // 1000;
+	my $sig = $opt{sig} // 0;
+	while (CORE::kill($sig, $pid) && --$tries) { sleep(0.01) }
+	$tries or croak "PID: $pid died after signal ($sig)";
+}
+
 sub stop_daemon (;$) {
 	my ($is_END) = @_;
 	kill('TERM', $daemon_pid);
-	my $tries = 1000;
-	while (CORE::kill(0, $daemon_pid) && --$tries) { sleep(0.01) }
+	kill_until_dead $daemon_pid;
 	if ($is_END && CORE::kill(0, $daemon_pid)) { # after done_testing
 		CORE::kill('KILL', $daemon_pid);
 		die "daemon_pid=$daemon_pid did not die";
@@ -44,8 +72,9 @@ END {
 	stop_daemon(1) if defined $daemon_pid;
 };
 
-sub check_stderr () {
-	my @log = slurp($err_log);
+sub check_stderr (@) {
+	my @log = @_;
+	slurp($err_log) if !@log;
 	diag("@log") if $ENV{V};
 	my @err = grep(!/NameError.*Unicorn::Waiter/, grep(/error/i, @log));
 	@err = grep(!/failed to set accept_filter=/, @err);
@@ -63,6 +92,16 @@ sub slurp_hdr {
 	($status, \@hdr);
 }
 
+sub unix_server (;$@) {
+	my $l = shift // $u_sock;
+	IO::Socket::UNIX->new(Listen => SOMAXCONN, Local => $l, Blocking => 0,
+				Type => SOCK_STREAM, @_);
+}
+
+sub unix_connect ($) {
+	IO::Socket::UNIX->new(Peer => $_[0], Type => SOCK_STREAM);
+}
+
 sub tcp_server {
 	my %opt = (
 		ReuseAddr => 1,
@@ -95,8 +134,7 @@ sub tcp_host_port {
 
 sub unix_start ($@) {
 	my ($dst, @req) = @_;
-	my $s = IO::Socket::UNIX->new(Peer => $dst, Type => SOCK_STREAM) or
-		BAIL_OUT "unix connect $dst: $!";
+	my $s = unix_connect($dst) or BAIL_OUT "unix connect $dst: $!";
 	$s->autoflush(1);
 	print $s @req, "\r\n\r\n" if @req;
 	$s;
@@ -201,7 +239,7 @@ sub unicorn {
 	state $ver = $ENV{TEST_RUBY_VERSION} // `$ruby -e 'print RUBY_VERSION'`;
 	state $eng = $ENV{TEST_RUBY_ENGINE} // `$ruby -e 'print RUBY_ENGINE'`;
 	state $ext = File::Spec->rel2abs("test/$eng-$ver/ext/unicorn_http");
-	state $exe = File::Spec->rel2abs('bin/unicorn');
+	state $exe = File::Spec->rel2abs("test/$eng-$ver/bin/unicorn");
 	my $pid = spawn(\%env, $ruby, '-I', $lib, '-I', $ext, $exe, @args);
 	UnicornTest::AutoReap->new($pid);
 }
@@ -219,6 +257,17 @@ sub do_req ($@) {
 	($status, $hdr, $bdy);
 }
 
+sub mkfifo_die ($;$) {
+	POSIX::mkfifo($_[0], $_[1] // 0600) or croak "mkfifo: $!";
+}
+
+sub write_file ($$@) { # mode, filename, LIST (for print)
+	open(my $fh, shift, shift);
+	print $fh @_;
+	# return $fh for futher writes if user wants it:
+	defined(wantarray) && !wantarray ? $fh : close $fh;
+}
+
 # automatically kill + reap children when this goes out-of-scope
 package UnicornTest::AutoReap;
 use v5.14;
diff --git a/t/t0008-back_out_of_upgrade.sh b/t/t0008-back_out_of_upgrade.sh
deleted file mode 100755
index 96d4057..0000000
--- a/t/t0008-back_out_of_upgrade.sh
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/bin/sh
-. ./test-lib.sh
-t_plan 13 "backout of USR2 upgrade"
-
-worker_wait_start () {
-	test xSTART = x"$(cat $fifo)"
-	unicorn_pid=$(cat $pid)
-}
-
-t_begin "setup and start" && {
-	unicorn_setup
-	rm -f $pid.oldbin
-
-cat >> $unicorn_config <<EOF
-after_fork do |server, worker|
-  # test script will block while reading from $fifo,
-  # so notify the script on the first worker we spawn
-  # by opening the FIFO
-  if worker.nr == 0
-    File.open("$fifo", "wb") { |fp| fp.syswrite "START" }
-  end
-end
-EOF
-	unicorn -D -c $unicorn_config pid.ru
-	worker_wait_start
-	orig_master_pid=$unicorn_pid
-}
-
-t_begin "read original worker pid" && {
-	orig_worker_pid=$(curl -sSf http://$listen/)
-	test -n "$orig_worker_pid" && kill -0 $orig_worker_pid
-}
-
-t_begin "upgrade to new master" && {
-	kill -USR2 $orig_master_pid
-}
-
-t_begin "kill old worker" && {
-	kill -WINCH $orig_master_pid
-}
-
-t_begin "wait for new worker to start" && {
-	worker_wait_start
-	test $unicorn_pid -ne $orig_master_pid
-	new_master_pid=$unicorn_pid
-}
-
-t_begin "old master pid is stashed in $pid.oldbin" && {
-	test -s "$pid.oldbin"
-	test $orig_master_pid -eq $(cat $pid.oldbin)
-}
-
-t_begin "ensure old worker is no longer running" && {
-	i=0
-	while kill -0 $orig_worker_pid 2>/dev/null
-	do
-		i=$(( $i + 1 ))
-		test $i -lt 600 || die "timed out"
-		sleep 1
-	done
-}
-
-t_begin "capture pid of new worker" && {
-	new_worker_pid=$(curl -sSf http://$listen/)
-}
-
-t_begin "reload old master process" && {
-	kill -HUP $orig_master_pid
-	worker_wait_start
-}
-
-t_begin "gracefully kill new master and ensure it dies" && {
-	kill -QUIT $new_master_pid
-	i=0
-	while kill -0 $new_worker_pid 2>/dev/null
-	do
-		i=$(( $i + 1 ))
-		test $i -lt 600 || die "timed out"
-		sleep 1
-	done
-}
-
-t_begin "ensure $pid.oldbin does not exist" && {
-	i=0
-	while test -s $pid.oldbin
-	do
-		i=$(( $i + 1 ))
-		test $i -lt 600 || die "timed out"
-		sleep 1
-	done
-	while ! test -s $pid
-	do
-		i=$(( $i + 1 ))
-		test $i -lt 600 || die "timed out"
-		sleep 1
-	done
-}
-
-t_begin "ensure $pid is correct" && {
-	cur_master_pid=$(cat $pid)
-	test $orig_master_pid -eq $cur_master_pid
-}
-
-t_begin "killing succeeds" && {
-	kill $orig_master_pid
-}
-
-dbgcat r_err
-
-t_done

[-- Attachment #4: 0003-doc-various-updates-and-disclaimers.patch --]
[-- Type: text/x-diff, Size: 3343 bytes --]

From 69d15a7a51a096b6acf00ccf23e1b988076d3b5f Mon Sep 17 00:00:00 2001
From: Eric Wong <bofh@yhbt.net>
Date: Mon, 1 Jan 2024 10:43:13 +0000
Subject: [PATCH 3/4] doc: various updates and disclaimers

Covering my ass from draconian legislation.
---
 HACKING | 13 +++++++++----
 README  |  9 +++++++++
 TODO    |  4 +---
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/HACKING b/HACKING
index 5aca83e..777e75e 100644
--- a/HACKING
+++ b/HACKING
@@ -6,6 +6,8 @@ Like Mongrel, we use Ruby where it makes sense, and Ragel with C where
 it helps performance.  All of the code that actually runs your Rack
 application is written Ruby, Ragel or C.
 
+Ragel may be dropped in favor of a picohttpparser-based one in the future.
+
 As far as tests and documentation goes, we're not afraid to embrace Unix
 and use traditional Unix tools where they make sense and get the job
 done.
@@ -16,6 +18,9 @@ Tests are good, but slow tests make development slow, so we make tests
 faster (in parallel) with GNU make (instead of Rake) and avoiding
 RubyGems.
 
+New tests are written in Perl 5 and use TAP <https://testanything.org/>
+to ensure stability and immunity from Ruby incompatibilities.
+
 Users of GNU-based systems (such as GNU/Linux) usually have GNU make
 installed as "make" instead of "gmake".
 
@@ -69,10 +74,10 @@ supported by the versions of Ruby we target.
 
 === Ragel Compatibility
 
-We target the latest released version of Ragel and will update our code
-to keep up with new releases.  Packaged tarballs and gems include the
-generated source code so they will remain usable if compatibility is
-broken.
+We target the latest released version of Ragel in Debian and will update
+our code to keep up with new releases.  Packaged tarballs and gems
+include the generated source code so they will remain usable if
+compatibility is broken.
 
 == Contributing
 
diff --git a/README b/README
index 84c0fdf..b60ed00 100644
--- a/README
+++ b/README
@@ -122,6 +122,7 @@ supported.  Run `unicorn -h` to see command-line options.
 
 There is NO WARRANTY whatsoever if anything goes wrong, but
 {let us know}[link:ISSUES.html] and maybe someone can fix it.
+No commercial support will ever be provided by the amateur maintainer.
 
 unicorn is designed to only serve fast clients either on the local host
 or a fast LAN.  See the PHILOSOPHY and DESIGN documents for more details
@@ -132,6 +133,14 @@ damage done to the entire Ruby ecosystem.  Its unintentional popularity
 set Ruby back decades in parallelism, concurrency and robustness since
 it prolongs and proliferates the existence of poorly-written code.
 
+unicorn hackers are NOT responsible for your supply chain security:
+read and understand it yourself or get someone you trust to audit it.
+Malicious commits and releases will be made if under duress.  The only
+defense you'll ever have is from reviewing the source code.
+
+No user or contributor will ever be expected to sacrifice their own
+security by running JavaScript or revealing any personal information.
+
 == Contact
 
 All feedback (bug reports, user/development dicussion, patches, pull
diff --git a/TODO b/TODO
index ebbccdc..a3b18fd 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1 @@
-* Documentation improvements
-
-* improve test suite
+* improve test suite (port to Perl 5 for stability and maintainability)

[-- Attachment #5: 0004-treewide-future-proof-frozen_string_literal-changes.patch --]
[-- Type: text/x-diff, Size: 24100 bytes --]

From ccf2443901c18ffb26b2785f52d921005e862167 Mon Sep 17 00:00:00 2001
From: Eric Wong <bofh@yhbt.net>
Date: Thu, 8 Feb 2024 12:16:31 +0000
Subject: [PATCH 4/4] treewide: future-proof frozen_string_literal changes

Once again Ruby seems ready to introduce more incompatibilities
and force busywork upon maintainers[1].  In order to avoid
incompatibilities in the future, I used a Perl script[2] to
prepend `frozen_string_literal: false' to every Ruby file.

Somebody interested will have to go through every Ruby source
file and enable frozen_string_literal once they've thoroughly
verified it's safe to do so.

[1] https://bugs.ruby-lang.org/issues/20205
[2] https://yhbt.net/add-fsl.git/74d7689/s/?b=add-fsl.perl
---
 Rakefile                            | 1 +
 bin/unicorn                         | 1 +
 bin/unicorn_rails                   | 1 +
 examples/big_app_gc.rb              | 1 +
 examples/echo.ru                    | 1 +
 examples/logger_mp_safe.rb          | 1 +
 examples/unicorn.conf.minimal.rb    | 1 +
 examples/unicorn.conf.rb            | 1 +
 ext/unicorn_http/extconf.rb         | 1 +
 lib/unicorn.rb                      | 1 +
 lib/unicorn/app/old_rails.rb        | 1 +
 lib/unicorn/app/old_rails/static.rb | 1 +
 lib/unicorn/cgi_wrapper.rb          | 1 +
 lib/unicorn/configurator.rb         | 1 +
 lib/unicorn/const.rb                | 1 +
 lib/unicorn/http_request.rb         | 1 +
 lib/unicorn/http_response.rb        | 1 +
 lib/unicorn/http_server.rb          | 1 +
 lib/unicorn/launcher.rb             | 1 +
 lib/unicorn/oob_gc.rb               | 1 +
 lib/unicorn/preread_input.rb        | 1 +
 lib/unicorn/select_waiter.rb        | 1 +
 lib/unicorn/socket_helper.rb        | 1 +
 lib/unicorn/stream_input.rb         | 1 +
 lib/unicorn/tee_input.rb            | 1 +
 lib/unicorn/tmpio.rb                | 1 +
 lib/unicorn/util.rb                 | 1 +
 lib/unicorn/worker.rb               | 1 +
 setup.rb                            | 1 +
 t/broken-app.ru                     | 1 +
 t/client_body_buffer_size.ru        | 1 +
 t/detach.ru                         | 1 +
 t/env.ru                            | 1 +
 t/fails-rack-lint.ru                | 1 +
 t/heartbeat-timeout.ru              | 1 +
 t/integration.ru                    | 1 +
 t/listener_names.ru                 | 1 +
 t/oob_gc.ru                         | 1 +
 t/oob_gc_path.ru                    | 1 +
 t/pid.ru                            | 1 +
 t/preread_input.ru                  | 1 +
 t/reopen-logs.ru                    | 1 +
 t/t0013.ru                          | 1 +
 t/t0014.ru                          | 1 +
 t/t0301.ru                          | 1 +
 test/aggregate.rb                   | 1 +
 test/benchmark/dd.ru                | 1 +
 test/benchmark/ddstream.ru          | 1 +
 test/benchmark/readinput.ru         | 1 +
 test/benchmark/stack.ru             | 1 +
 test/exec/test_exec.rb              | 1 +
 test/test_helper.rb                 | 1 +
 test/unit/test_ccc.rb               | 1 +
 test/unit/test_configurator.rb      | 1 +
 test/unit/test_droplet.rb           | 1 +
 test/unit/test_http_parser.rb       | 1 +
 test/unit/test_http_parser_ng.rb    | 1 +
 test/unit/test_request.rb           | 1 +
 test/unit/test_server.rb            | 1 +
 test/unit/test_signals.rb           | 1 +
 test/unit/test_socket_helper.rb     | 1 +
 test/unit/test_stream_input.rb      | 1 +
 test/unit/test_tee_input.rb         | 1 +
 test/unit/test_util.rb              | 1 +
 test/unit/test_waiter.rb            | 1 +
 unicorn.gemspec                     | 1 +
 66 files changed, 66 insertions(+)

diff --git a/Rakefile b/Rakefile
index 37569ce..fe1588b 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # optional rake-compiler support in case somebody needs to cross compile
 begin
   mk = "ext/unicorn_http/Makefile"
diff --git a/bin/unicorn b/bin/unicorn
index 00c8464..af8353c 100755
--- a/bin/unicorn
+++ b/bin/unicorn
@@ -1,5 +1,6 @@
 #!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 require 'unicorn/launcher'
 require 'optparse'
 
diff --git a/bin/unicorn_rails b/bin/unicorn_rails
index 354c1df..374fd8e 100755
--- a/bin/unicorn_rails
+++ b/bin/unicorn_rails
@@ -1,5 +1,6 @@
 #!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 require 'unicorn/launcher'
 require 'optparse'
 require 'fileutils'
diff --git a/examples/big_app_gc.rb b/examples/big_app_gc.rb
index c1bae10..0baea26 100644
--- a/examples/big_app_gc.rb
+++ b/examples/big_app_gc.rb
@@ -1,2 +1,3 @@
+# frozen_string_literal: false
 # see {Unicorn::OobGC}[https://yhbt.net/unicorn/Unicorn/OobGC.html]
 # Unicorn::OobGC was broken in Unicorn v3.3.1 - v3.6.1 and fixed in v3.6.2
diff --git a/examples/echo.ru b/examples/echo.ru
index e982180..453a5e6 100644
--- a/examples/echo.ru
+++ b/examples/echo.ru
@@ -1,4 +1,5 @@
 #\-E none
+# frozen_string_literal: false
 #
 # Example application that echoes read data back to the HTTP client.
 # This emulates the old echo protocol people used to run.
diff --git a/examples/logger_mp_safe.rb b/examples/logger_mp_safe.rb
index 05ad3fa..f2c0500 100644
--- a/examples/logger_mp_safe.rb
+++ b/examples/logger_mp_safe.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # Multi-Processing-safe monkey patch for Logger
 #
 # This monkey patch fixes the case where "preload_app true" is used and
diff --git a/examples/unicorn.conf.minimal.rb b/examples/unicorn.conf.minimal.rb
index 46fd634..4f96ede 100644
--- a/examples/unicorn.conf.minimal.rb
+++ b/examples/unicorn.conf.minimal.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # Minimal sample configuration file for Unicorn (not Rack) when used
 # with daemonization (unicorn -D) started in your working directory.
 #
diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index d90bdc4..5bae830 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # Sample verbose configuration file for Unicorn (not Rack)
 #
 # This configuration file documents many features of Unicorn
diff --git a/ext/unicorn_http/extconf.rb b/ext/unicorn_http/extconf.rb
index 11099cd..de896fe 100644
--- a/ext/unicorn_http/extconf.rb
+++ b/ext/unicorn_http/extconf.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 require 'mkmf'
 
 have_func("rb_hash_clear", "ruby.h") or abort 'Ruby 2.0+ required'
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index 564cb30..fb91679 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 require 'etc'
 require 'stringio'
 require 'raindrops'
diff --git a/lib/unicorn/app/old_rails.rb b/lib/unicorn/app/old_rails.rb
index 1e8c41a..54b3e69 100644
--- a/lib/unicorn/app/old_rails.rb
+++ b/lib/unicorn/app/old_rails.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # :enddoc:
 # This code is based on the original Rails handler in Mongrel
diff --git a/lib/unicorn/app/old_rails/static.rb b/lib/unicorn/app/old_rails/static.rb
index 2257270..cf34e02 100644
--- a/lib/unicorn/app/old_rails/static.rb
+++ b/lib/unicorn/app/old_rails/static.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 # :enddoc:
 # This code is based on the original Rails handler in Mongrel
 # Copyright (c) 2005 Zed A. Shaw
diff --git a/lib/unicorn/cgi_wrapper.rb b/lib/unicorn/cgi_wrapper.rb
index d9b7fe5..fb43605 100644
--- a/lib/unicorn/cgi_wrapper.rb
+++ b/lib/unicorn/cgi_wrapper.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # :enddoc:
 # This code is based on the original CGIWrapper from Mongrel
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index b21a01d..3c81596 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 require 'logger'
 
 # Implements a simple DSL for configuring a unicorn server.
diff --git a/lib/unicorn/const.rb b/lib/unicorn/const.rb
index 33ab4ac..8032863 100644
--- a/lib/unicorn/const.rb
+++ b/lib/unicorn/const.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 module Unicorn::Const # :nodoc:
   # default TCP listen host address (0.0.0.0, all interfaces)
diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb
index ab3bd6e..a48dab7 100644
--- a/lib/unicorn/http_request.rb
+++ b/lib/unicorn/http_request.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 # :enddoc:
 # no stable API here
 require 'unicorn_http'
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index 0ed0ae3..3634165 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 # :enddoc:
 # Writes a Rack response to your client using the HTTP/1.1 specification.
 # You use it by simply doing:
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index ed5bbf1..08fbe40 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # This is the process manager of Unicorn. This manages worker
 # processes which in turn handle the I/O and application process.
diff --git a/lib/unicorn/launcher.rb b/lib/unicorn/launcher.rb
index 78e8f39..bd3324e 100644
--- a/lib/unicorn/launcher.rb
+++ b/lib/unicorn/launcher.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # :enddoc:
 $stdout.sync = $stderr.sync = true
diff --git a/lib/unicorn/oob_gc.rb b/lib/unicorn/oob_gc.rb
index db9f2cb..efd9177 100644
--- a/lib/unicorn/oob_gc.rb
+++ b/lib/unicorn/oob_gc.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Strongly consider https://github.com/tmm1/gctools if using Ruby 2.1+
 # It is built on new APIs in Ruby 2.1, so it is more intelligent than
diff --git a/lib/unicorn/preread_input.rb b/lib/unicorn/preread_input.rb
index 12eb3e8..c62cc09 100644
--- a/lib/unicorn/preread_input.rb
+++ b/lib/unicorn/preread_input.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 module Unicorn
 # This middleware is used to ensure input is buffered to memory
diff --git a/lib/unicorn/select_waiter.rb b/lib/unicorn/select_waiter.rb
index cb84aab..d11ea57 100644
--- a/lib/unicorn/select_waiter.rb
+++ b/lib/unicorn/select_waiter.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # fallback for non-Linux and Linux <4.5 systems w/o EPOLLEXCLUSIVE
 class Unicorn::SelectWaiter # :nodoc:
   def get_readers(ready, readers, timeout) # :nodoc:
diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb
index 06ec2b2..986932f 100644
--- a/lib/unicorn/socket_helper.rb
+++ b/lib/unicorn/socket_helper.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 # :enddoc:
 require 'socket'
 
diff --git a/lib/unicorn/stream_input.rb b/lib/unicorn/stream_input.rb
index 9246f73..23a9976 100644
--- a/lib/unicorn/stream_input.rb
+++ b/lib/unicorn/stream_input.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # When processing uploads, unicorn may expose a StreamInput object under
 # "rack.input" of the Rack environment when
diff --git a/lib/unicorn/tee_input.rb b/lib/unicorn/tee_input.rb
index 2ccc2d9..b3c6535 100644
--- a/lib/unicorn/tee_input.rb
+++ b/lib/unicorn/tee_input.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Acts like tee(1) on an input input to provide a input-like stream
 # while providing rewindable semantics through a File/StringIO backing
diff --git a/lib/unicorn/tmpio.rb b/lib/unicorn/tmpio.rb
index 0bbf6ec..deecd80 100644
--- a/lib/unicorn/tmpio.rb
+++ b/lib/unicorn/tmpio.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 # :stopdoc:
 require 'tmpdir'
 
diff --git a/lib/unicorn/util.rb b/lib/unicorn/util.rb
index b826de4..f28d929 100644
--- a/lib/unicorn/util.rb
+++ b/lib/unicorn/util.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 require 'fcntl'
 module Unicorn::Util # :nodoc:
diff --git a/lib/unicorn/worker.rb b/lib/unicorn/worker.rb
index 4af31be..d2445d5 100644
--- a/lib/unicorn/worker.rb
+++ b/lib/unicorn/worker.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 require "raindrops"
 
 # This class and its members can be considered a stable interface
diff --git a/setup.rb b/setup.rb
index cf1abd9..96cf75a 100644
--- a/setup.rb
+++ b/setup.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 #
 # setup.rb
 #
diff --git a/t/broken-app.ru b/t/broken-app.ru
index d05d7ab..5966bff 100644
--- a/t/broken-app.ru
+++ b/t/broken-app.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # we do not want Rack::Lint or anything to protect us
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
diff --git a/t/client_body_buffer_size.ru b/t/client_body_buffer_size.ru
index 44161a5..1a0fb16 100644
--- a/t/client_body_buffer_size.ru
+++ b/t/client_body_buffer_size.ru
@@ -1,4 +1,5 @@
 #\ -E none
+# frozen_string_literal: false
 app = lambda do |env|
   input = env['rack.input']
   case env["PATH_INFO"]
diff --git a/t/detach.ru b/t/detach.ru
index bbd998e..8d35951 100644
--- a/t/detach.ru
+++ b/t/detach.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 use Rack::ContentType, "text/plain"
 fifo_path = ENV["TEST_FIFO"] or abort "TEST_FIFO not set"
 run lambda { |env|
diff --git a/t/env.ru b/t/env.ru
index 388412e..86c3cfa 100644
--- a/t/env.ru
+++ b/t/env.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
 run lambda { |env| [ 200, {}, [ env.inspect << "\n" ] ] }
diff --git a/t/fails-rack-lint.ru b/t/fails-rack-lint.ru
index 82bfb5f..8b8b5ec 100644
--- a/t/fails-rack-lint.ru
+++ b/t/fails-rack-lint.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # This rack app returns an invalid status code, which will cause
 # Rack::Lint to throw an exception if it is present.  This
 # is used to check whether Rack::Lint is in the stack or not.
diff --git a/t/heartbeat-timeout.ru b/t/heartbeat-timeout.ru
index 3eeb5d6..ccc6a8e 100644
--- a/t/heartbeat-timeout.ru
+++ b/t/heartbeat-timeout.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 use Rack::ContentLength
 headers = { 'content-type' => 'text/plain' }
 run lambda { |env|
diff --git a/t/integration.ru b/t/integration.ru
index 888833a..6df481c 100644
--- a/t/integration.ru
+++ b/t/integration.ru
@@ -1,4 +1,5 @@
 #!ruby
+# frozen_string_literal: false
 # Copyright (C) unicorn hackers <unicorn-public@80x24.org>
 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 
diff --git a/t/listener_names.ru b/t/listener_names.ru
index edb4e6a..f52c59b 100644
--- a/t/listener_names.ru
+++ b/t/listener_names.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
 names = Unicorn.listener_names.inspect # rely on preload_app=true
diff --git a/t/oob_gc.ru b/t/oob_gc.ru
index 224cb06..2ae58a8 100644
--- a/t/oob_gc.ru
+++ b/t/oob_gc.ru
@@ -1,4 +1,5 @@
 #\-E none
+# frozen_string_literal: false
 require 'unicorn/oob_gc'
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
diff --git a/t/oob_gc_path.ru b/t/oob_gc_path.ru
index 7f40601..5358222 100644
--- a/t/oob_gc_path.ru
+++ b/t/oob_gc_path.ru
@@ -1,4 +1,5 @@
 #\-E none
+# frozen_string_literal: false
 require 'unicorn/oob_gc'
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
diff --git a/t/pid.ru b/t/pid.ru
index f5fd31f..b49b137 100644
--- a/t/pid.ru
+++ b/t/pid.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
 run lambda { |env| [ 200, {}, [ "#$$\n" ] ] }
diff --git a/t/preread_input.ru b/t/preread_input.ru
index 18af221..5f68fe9 100644
--- a/t/preread_input.ru
+++ b/t/preread_input.ru
@@ -1,4 +1,5 @@
 #\-E none
+# frozen_string_literal: false
 require 'digest/md5'
 require 'unicorn/preread_input'
 use Unicorn::PrereadInput
diff --git a/t/reopen-logs.ru b/t/reopen-logs.ru
index c39e8f6..488da85 100644
--- a/t/reopen-logs.ru
+++ b/t/reopen-logs.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 use Rack::ContentLength
 use Rack::ContentType, "text/plain"
 run lambda { |env|
diff --git a/t/t0013.ru b/t/t0013.ru
index 48a3a34..e425093 100644
--- a/t/t0013.ru
+++ b/t/t0013.ru
@@ -1,4 +1,5 @@
 #\ -E none
+# frozen_string_literal: false
 use Rack::ContentLength
 use Rack::ContentType, 'text/plain'
 app = lambda do |env|
diff --git a/t/t0014.ru b/t/t0014.ru
index b0bd2b7..686d214 100644
--- a/t/t0014.ru
+++ b/t/t0014.ru
@@ -1,4 +1,5 @@
 #\ -E none
+# frozen_string_literal: false
 use Rack::ContentLength
 use Rack::ContentType, 'text/plain'
 app = lambda do |env|
diff --git a/t/t0301.ru b/t/t0301.ru
index ce68213..54929b1 100644
--- a/t/t0301.ru
+++ b/t/t0301.ru
@@ -1,4 +1,5 @@
 #\-N --debug
+# frozen_string_literal: false
 run(lambda do |env|
   case env['PATH_INFO']
   when '/vars'
diff --git a/test/aggregate.rb b/test/aggregate.rb
index 5eebbe5..0f32b2f 100755
--- a/test/aggregate.rb
+++ b/test/aggregate.rb
@@ -1,5 +1,6 @@
 #!/usr/bin/ruby -n
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 BEGIN { $tests = $assertions = $failures = $errors = 0 }
 
diff --git a/test/benchmark/dd.ru b/test/benchmark/dd.ru
index 111fa2e..5bd2739 100644
--- a/test/benchmark/dd.ru
+++ b/test/benchmark/dd.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # This benchmark is the simplest test of the I/O facilities in
 # unicorn.  It is meant to return a fixed-sized blob to test
 # the performance of things in Unicorn, _NOT_ the app.
diff --git a/test/benchmark/ddstream.ru b/test/benchmark/ddstream.ru
index b14c973..fd40ced 100644
--- a/test/benchmark/ddstream.ru
+++ b/test/benchmark/ddstream.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # This app is intended to test large HTTP responses with or without
 # a fully-buffering reverse proxy such as nginx. Without a fully-buffering
 # reverse proxy, unicorn will be unresponsive when client count exceeds
diff --git a/test/benchmark/readinput.ru b/test/benchmark/readinput.ru
index c91bec3..95c0226 100644
--- a/test/benchmark/readinput.ru
+++ b/test/benchmark/readinput.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 # This app is intended to test large HTTP requests with or without
 # a fully-buffering reverse proxy such as nginx. Without a fully-buffering
 # reverse proxy, unicorn will be unresponsive when client count exceeds
diff --git a/test/benchmark/stack.ru b/test/benchmark/stack.ru
index fc9193f..17a565b 100644
--- a/test/benchmark/stack.ru
+++ b/test/benchmark/stack.ru
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 run(lambda { |env|
   body = "#{caller.size}\n"
   h = {
diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb
index 8494452..807f724 100644
--- a/test/exec/test_exec.rb
+++ b/test/exec/test_exec.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 # Don't add to this file, new tests are in Perl 5. See t/README
 FLOCK_PATH = File.expand_path(__FILE__)
 require './test/test_helper'
diff --git a/test/test_helper.rb b/test/test_helper.rb
index d86f83b..0bf3c90 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Copyright (c) 2005 Zed A. Shaw
 # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
diff --git a/test/unit/test_ccc.rb b/test/unit/test_ccc.rb
index f518230..a0a2bff 100644
--- a/test/unit/test_ccc.rb
+++ b/test/unit/test_ccc.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 require 'socket'
 require 'unicorn'
 require 'io/wait'
diff --git a/test/unit/test_configurator.rb b/test/unit/test_configurator.rb
index 1298f0e..1a89aca 100644
--- a/test/unit/test_configurator.rb
+++ b/test/unit/test_configurator.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 require 'test/unit'
 require 'tempfile'
diff --git a/test/unit/test_droplet.rb b/test/unit/test_droplet.rb
index 81ad82b..4b2d2d0 100644
--- a/test/unit/test_droplet.rb
+++ b/test/unit/test_droplet.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 require 'test/unit'
 require 'unicorn'
 
diff --git a/test/unit/test_http_parser.rb b/test/unit/test_http_parser.rb
index 697af44..adcc84f 100644
--- a/test/unit/test_http_parser.rb
+++ b/test/unit/test_http_parser.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Copyright (c) 2005 Zed A. Shaw
 # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
diff --git a/test/unit/test_http_parser_ng.rb b/test/unit/test_http_parser_ng.rb
index 425d5ad..fd47246 100644
--- a/test/unit/test_http_parser_ng.rb
+++ b/test/unit/test_http_parser_ng.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 require './test/test_helper'
 require 'digest/md5'
diff --git a/test/unit/test_request.rb b/test/unit/test_request.rb
index 53ae944..9d1b350 100644
--- a/test/unit/test_request.rb
+++ b/test/unit/test_request.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Copyright (c) 2009 Eric Wong
 # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb
index 7ffa48f..5a2252f 100644
--- a/test/unit/test_server.rb
+++ b/test/unit/test_server.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Copyright (c) 2005 Zed A. Shaw
 # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
diff --git a/test/unit/test_signals.rb b/test/unit/test_signals.rb
index 6c48754..49ff3c7 100644
--- a/test/unit/test_signals.rb
+++ b/test/unit/test_signals.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 # Copyright (c) 2009 Eric Wong
 # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
diff --git a/test/unit/test_socket_helper.rb b/test/unit/test_socket_helper.rb
index a446f06..4363474 100644
--- a/test/unit/test_socket_helper.rb
+++ b/test/unit/test_socket_helper.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 require './test/test_helper'
 require 'tempfile'
diff --git a/test/unit/test_stream_input.rb b/test/unit/test_stream_input.rb
index 7986ca7..7ee98e4 100644
--- a/test/unit/test_stream_input.rb
+++ b/test/unit/test_stream_input.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 require 'test/unit'
 require 'digest/sha1'
diff --git a/test/unit/test_tee_input.rb b/test/unit/test_tee_input.rb
index 607ce87..8f05c77 100644
--- a/test/unit/test_tee_input.rb
+++ b/test/unit/test_tee_input.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 require 'test/unit'
 require 'digest/sha1'
diff --git a/test/unit/test_util.rb b/test/unit/test_util.rb
index bc7b233..ce53b86 100644
--- a/test/unit/test_util.rb
+++ b/test/unit/test_util.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 
 require './test/test_helper'
 require 'tempfile'
diff --git a/test/unit/test_waiter.rb b/test/unit/test_waiter.rb
index 0995de2..a20994b 100644
--- a/test/unit/test_waiter.rb
+++ b/test/unit/test_waiter.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
 require 'test/unit'
 require 'unicorn'
 require 'unicorn/select_waiter'
diff --git a/unicorn.gemspec b/unicorn.gemspec
index e7e3ef7..36700a8 100644
--- a/unicorn.gemspec
+++ b/unicorn.gemspec
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+# frozen_string_literal: false
 manifest = File.exist?('.manifest') ?
   IO.readlines('.manifest').map!(&:chomp!) : `git ls-files`.split("\n")
 

^ permalink raw reply related	[relevance 4%]

* Re: [PATCH] doc: various updates ahead of the release
  2023-09-10 20:14  3% [PATCH] doc: various updates ahead of the release Eric Wong
@ 2023-09-16 20:46  0% ` ideal.water4095
  0 siblings, 0 replies; 200+ results
From: ideal.water4095 @ 2023-09-16 20:46 UTC (permalink / raw)
  To: Eric Wong, unicorn-public

> The damage unicorn has done to the entire Ruby, Rack and Rails
> ecosystems with its ability to tolerate buggy code is
> unforgivable.  Update the documentation to further discourage
> its use and clarify a few wordings noticed along the way.
> ---
>  DESIGN                      |  4 ++++
>  ISSUES                      |  6 +++++-
>  README                      | 38 ++++++++++++++++++++-----------------
>  lib/unicorn/configurator.rb |  7 ++++++-
>  4 files changed, 36 insertions(+), 19 deletions(-)
>
> diff --git a/DESIGN b/DESIGN
> index 46d7923..0bac24f 100644
> --- a/DESIGN
> +++ b/DESIGN
> @@ -1,5 +1,9 @@
>  == Design
> 
> +Unicorn was designed to support poorly-written codebases back in 2008.
> +Its unfortunate popularity has only proliferated the existence of
> +poorly-written code ever since...
> +
>  * Simplicity: Unicorn is a traditional UNIX prefork web server.
>    No threads are used at all, this makes applications easier to debug
>    and fix.  When your application goes awry, a BOFH can just
> diff --git a/ISSUES b/ISSUES
> index 083b1c8..d6c2a7a 100644
> --- a/ISSUES
> +++ b/ISSUES
> @@ -32,6 +32,10 @@ and such.
>  If you don't get a response within a few days, we may have forgotten
>  about it so feel free to ask again.
> 
> +The project does not and will never endorse nor promote commercial
> +services (including support).  The author of unicorn must never be
> +allowed to profit off the damage it's done to the entire Ruby world.
> +
>  == Bugs in related projects
> 
>  unicorn is sometimes affected by bugs in its dependencies.  Bugs
> @@ -65,7 +69,7 @@ There is a kernel.org Bugzilla instance, but it is 
> ignored by most.
> 
>  Likewise for any rare glibc bugs we might encounter, we should Cc:
>  mailto:libc-alpha@sourceware.org
> -Unofficial archives are available at: https://public-inbox.org/libc-alpha/
> +Archives are available at: https://inbox.sourceware.org/libc-alpha/
>  Keep in mind glibc upstream does use Bugzilla for tracking bugs:
>  https://sourceware.org/bugzilla/
> 
> diff --git a/README b/README
> index 5411003..c5c5222 100644
> --- a/README
> +++ b/README
> @@ -1,10 +1,13 @@
>  = unicorn: Rack HTTP server for fast clients and Unix
> 
> -unicorn is an HTTP server for Rack applications designed to only serve
> -fast clients on low-latency, high-bandwidth connections and take
> -advantage of features in Unix/Unix-like kernels.  Slow clients should
> -only be served by placing a reverse proxy capable of fully buffering
> -both the the request and response in between unicorn and slow clients.
> +unicorn is an HTTP server for Rack applications that has done
> +decades of damage to the entire Ruby ecosystem due to its ability
> +to tolerate (and thus encourage) bad code.  It is only designed
> +to only handle fast clients on low-latency, high-bandwidth connections
> +and take advantage of features in Unix/Unix-like kernels.
> +Slow clients must only be served by placing a reverse proxy capable of
> +fully buffering both the the request and response in between unicorn
> +and slow clients.

Double "only" here.

^ permalink raw reply	[relevance 0%]

* [PATCH] doc: various updates ahead of the release
@ 2023-09-10 20:14  3% Eric Wong
  2023-09-16 20:46  0% ` ideal.water4095
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2023-09-10 20:14 UTC (permalink / raw)
  To: unicorn-public

The damage unicorn has done to the entire Ruby, Rack and Rails
ecosystems with its ability to tolerate buggy code is
unforgivable.  Update the documentation to further discourage
its use and clarify a few wordings noticed along the way.
---
 DESIGN                      |  4 ++++
 ISSUES                      |  6 +++++-
 README                      | 38 ++++++++++++++++++++-----------------
 lib/unicorn/configurator.rb |  7 ++++++-
 4 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/DESIGN b/DESIGN
index 46d7923..0bac24f 100644
--- a/DESIGN
+++ b/DESIGN
@@ -1,5 +1,9 @@
 == Design
 
+Unicorn was designed to support poorly-written codebases back in 2008.
+Its unfortunate popularity has only proliferated the existence of
+poorly-written code ever since...
+
 * Simplicity: Unicorn is a traditional UNIX prefork web server.
   No threads are used at all, this makes applications easier to debug
   and fix.  When your application goes awry, a BOFH can just
diff --git a/ISSUES b/ISSUES
index 083b1c8..d6c2a7a 100644
--- a/ISSUES
+++ b/ISSUES
@@ -32,6 +32,10 @@ and such.
 If you don't get a response within a few days, we may have forgotten
 about it so feel free to ask again.
 
+The project does not and will never endorse nor promote commercial
+services (including support).  The author of unicorn must never be
+allowed to profit off the damage it's done to the entire Ruby world.
+
 == Bugs in related projects
 
 unicorn is sometimes affected by bugs in its dependencies.  Bugs
@@ -65,7 +69,7 @@ There is a kernel.org Bugzilla instance, but it is ignored by most.
 
 Likewise for any rare glibc bugs we might encounter, we should Cc:
 mailto:libc-alpha@sourceware.org
-Unofficial archives are available at: https://public-inbox.org/libc-alpha/
+Archives are available at: https://inbox.sourceware.org/libc-alpha/
 Keep in mind glibc upstream does use Bugzilla for tracking bugs:
 https://sourceware.org/bugzilla/
 
diff --git a/README b/README
index 5411003..c5c5222 100644
--- a/README
+++ b/README
@@ -1,10 +1,13 @@
 = unicorn: Rack HTTP server for fast clients and Unix
 
-unicorn is an HTTP server for Rack applications designed to only serve
-fast clients on low-latency, high-bandwidth connections and take
-advantage of features in Unix/Unix-like kernels.  Slow clients should
-only be served by placing a reverse proxy capable of fully buffering
-both the the request and response in between unicorn and slow clients.
+unicorn is an HTTP server for Rack applications that has done
+decades of damage to the entire Ruby ecosystem due to its ability
+to tolerate (and thus encourage) bad code.  It is only designed
+to only handle fast clients on low-latency, high-bandwidth connections
+and take advantage of features in Unix/Unix-like kernels.
+Slow clients must only be served by placing a reverse proxy capable of
+fully buffering both the the request and response in between unicorn
+and slow clients.
 
 == Features
 
@@ -14,8 +17,8 @@ both the the request and response in between unicorn and slow clients.
 
 * Compatible with Ruby 2.0.0 and later.
 
-* Process management: unicorn will reap and restart workers that
-  die from broken apps.  There is no need to manage multiple processes
+* Process management: unicorn reaps and restarts workers that die
+  from broken code.  There is no need to manage multiple processes
   or ports yourself.  unicorn can spawn and manage any number of
   worker processes you choose to scale to your backend.
 
@@ -57,7 +60,7 @@ both the the request and response in between unicorn and slow clients.
 
 == License
 
-unicorn is copyright 2009-2018 by all contributors (see logs in git).
+unicorn is copyright all contributors (see logs in git).
 It is based on Mongrel 1.1.5.
 Mongrel is copyright 2007 Zed A. Shaw and contributors.
 
@@ -79,8 +82,8 @@ You may install it via RubyGems on RubyGems.org:
 You can get the latest source via git from the following locations
 (these versions may not be stable):
 
-  https://yhbt.net/unicorn.git
-  https://repo.or.cz/unicorn.git (mirror)
+  git clone https://yhbt.net/unicorn.git
+  git clone https://repo.or.cz/unicorn.git # mirror
 
 You may browse the code from the web:
 
@@ -118,23 +121,24 @@ supported.  Run `unicorn -h` to see command-line options.
 == Disclaimer
 
 There is NO WARRANTY whatsoever if anything goes wrong, but
-{let us know}[link:ISSUES.html] and we'll try our best to fix it.
+{let us know}[link:ISSUES.html] and maybe someone can fix it.
 
 unicorn is designed to only serve fast clients either on the local host
 or a fast LAN.  See the PHILOSOPHY and DESIGN documents for more details
 regarding this.
 
-Due to its ability to tolerate crashes and isolate clients, unicorn
-is unfortunately known to prolong the existence of bugs in applications
-and libraries which run on top of it.
+The use of unicorn in new deployments is STRONGLY DISCOURAGED due to the
+damage done to the entire Ruby ecosystem.  Its unintentional popularity
+set Ruby back decades in parallelism, concurrency and robustness since
+it prolongs and proliferates the existence of poorly-written code.
 
 == Contact
 
 All feedback (bug reports, user/development dicussion, patches, pull
-requests) go to the mailing list/newsgroup.  See the ISSUES document for
-information on the {mailing list}[mailto:unicorn-public@yhbt.net].
+requests) go to the public mailbox.  See the ISSUES document for
+information on posting to mailto:unicorn-public@yhbt.net
 
-The mailing list is archived at https://yhbt.net/unicorn-public/
+Mirror-able mail archives are at https://yhbt.net/unicorn-public/
 
 Read-only NNTP access is available at:
 nntps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index ecdf03e..b21a01d 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -216,7 +216,12 @@ def before_exec(*args, &block)
     set_hook(:before_exec, block_given? ? block : args[0], 1)
   end
 
-  # sets the timeout of worker processes to +seconds+.  Workers
+  # Strongly consider using link:/Application_Timeouts.html instead
+  # of this misfeature.  This misfeature has done decades of damage
+  # to Ruby since it demotivates the use of fine-grained timeout
+  # mechanisms.
+  #
+  # Sets the timeout of worker processes to +seconds+.  Workers
   # handling the request/app.call/response cycle taking longer than
   # this time period will be forcibly killed (via SIGKILL).  This
   # timeout is enforced by the master process itself and not subject

^ permalink raw reply related	[relevance 3%]

* [PATCH] add chunk_response config directive for compatibility
@ 2023-06-20 12:28 11% EW
  0 siblings, 0 replies; 200+ results
From: EW @ 2023-06-20 12:28 UTC (permalink / raw)
  To: unicorn-public

Since Rack::Chunked is gone in Rack 3.1+ and no longer loaded by
default, we've learned to chunk HTTP/1.1 responses w/o
Content-Length to allow clients to detect truncated responses.

Unfortunately, there exist broken HTTP clients which advertise
"HTTP/1.1" in the request but cannot parse chunked responses.
Thus, we must continue to send unchunked responses as we have in
prior releases if that's what clients expect.  That is, chunked
responses are opt-in unless RACK_ENV is "deployment" or
"development".

It doesn't matter if clients are in the wrong: they've worked
this way for 14 years and we must do everything in our power to
avoid breaking existing expectations on upgrades.

I hate adding config directives, but breaking changes are even
worse since users upgrading unicorn often have no easy way to
to fix broken clients even if they're on the same LAN.
---
  Of course, if users upgrading to unicorn could fix everything;
  they wouldn't need unicorn at all :P
  unicorn was created to support broken code and now exists to
  perpetuate broken code into eternity.

 Documentation/unicorn.1      |  1 +
 lib/unicorn.rb               |  2 +
 lib/unicorn/configurator.rb  | 17 ++++++-
 lib/unicorn/http_response.rb |  2 +-
 lib/unicorn/http_server.rb   |  3 +-
 t/integration.ru             |  7 +++
 t/integration.t              | 88 +++++++++++++++++++++++++++++++++---
 7 files changed, 110 insertions(+), 10 deletions(-)

diff --git a/Documentation/unicorn.1 b/Documentation/unicorn.1
index b2c5e70..502f44a 100644
--- a/Documentation/unicorn.1
+++ b/Documentation/unicorn.1
@@ -69,6 +69,7 @@ options.
 Disables loading middleware implied by RACK_ENV.  This bypasses the
 configuration documented in the RACK ENVIRONMENT section, but still
 allows RACK_ENV to be used for application/framework\-specific purposes.
+This also affects the "chunk_response" config file directive in unicorn 7.0+
 .RS
 .RE
 .SH RACKUP COMPATIBILITY OPTIONS
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index b817b77..e7b2806 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -78,7 +78,9 @@ def self.builder(ru, op)
       # middlewares will need ContentLength middleware.
       case ENV["RACK_ENV"]
       when "development"
+        server.chunk_response = true if server.chunk_response.nil?
       when "deployment"
+        server.chunk_response = true if server.chunk_response.nil?
         middleware.delete(:ShowExceptions)
         middleware.delete(:Lint)
       else
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index ecdf03e..bbc0448 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -59,6 +59,7 @@ class Unicorn::Configurator
     :check_client_connection => false,
     :rewindable_input => true,
     :client_body_buffer_size => Unicorn::Const::MAX_BODY,
+    :chunk_response => nil,
   }
   #:startdoc:
 
@@ -129,6 +130,19 @@ def [](key) # :nodoc:
     set[key]
   end
 
+  # Whether or not to chunk eligible HTTP/1.1 responses.  This is
+  # necessary for Rack 3.1+ users where the Rack::Chunked middleware
+  # no longer exists.
+  # Default: +true+ if +default_middleware+ is +true+ AND
+  # RACK_ENV is either +development+ or +deployment+.
+  # It is +false+ otherwise to support broken clients advertising
+  # HTTP/1.1 but lacking the ability to parse chunked responses.
+  # +chunk_response+ only exists since unicorn 7.0+ (the first release
+  # with Rack 3.x support).
+  def chunk_response(bool)
+    set_bool(:chunk_response, bool)
+  end
+
   # sets object to the +obj+ Logger-like object.  The new Logger-like
   # object must respond to the following methods:
   # * debug
@@ -270,7 +284,8 @@ def worker_processes(nr)
   end
 
   # sets whether to add default middleware in the development and
-  # deployment RACK_ENVs.
+  # deployment RACK_ENVs.  This also affects the +chunk_response+
+  # directive in unicorn 7.0+
   #
   # default_middleware is only available in unicorn 5.5.0+
   def default_middleware(bool)
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index 0ed0ae3..c73efe9 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -68,7 +68,7 @@ def http_response_write(socket, status, headers, body,
           append_header(buf, key, value)
         end
       end
-      if !hijack && !term && req.chunkable_response?
+      if !hijack && !term && req.chunkable_response? && @chunk_response
         do_chunk = true
         buf << "Transfer-Encoding: chunked\r\n".freeze
       end
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index f1b4a54..93d7141 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -15,7 +15,7 @@ class Unicorn::HttpServer
                 :before_fork, :after_fork, :before_exec,
                 :listener_opts, :preload_app,
                 :orig_app, :config, :ready_pipe, :user,
-                :default_middleware, :early_hints
+                :default_middleware, :early_hints, :chunk_response
   attr_writer   :after_worker_exit, :after_worker_ready, :worker_exec
 
   attr_reader :pid, :logger
@@ -69,6 +69,7 @@ class Unicorn::HttpServer
   # incoming requests on the socket.
   def initialize(app, options = {})
     @app = app
+    @chunk_response = nil
     @reexec_pid = 0
     @default_middleware = true
     options = options.dup
diff --git a/t/integration.ru b/t/integration.ru
index 086126a..d8a8178 100644
--- a/t/integration.ru
+++ b/t/integration.ru
@@ -85,6 +85,12 @@ def rack_input_tests(env)
   [ 200, h, [ dig.hexdigest ] ]
 end
 
+class NoArray
+  def each
+    yield "HI\n"
+  end
+end
+
 run(lambda do |env|
   case env['REQUEST_METHOD']
   when 'GET'
@@ -98,6 +104,7 @@ def rack_input_tests(env)
     when '/pid'; [ 200, {}, [ "#$$\n" ] ]
     when '/early_hints_rack2'; early_hints(env, "r\n2")
     when '/early_hints_rack3'; early_hints(env, %w(r 3))
+    when '/no-ary'; [ 200, {}, NoArray.new ]
     else '/'; [ 200, {}, [ env_dump(env) ] ]
     end # case PATH_INFO (GET)
   when 'POST'
diff --git a/t/integration.t b/t/integration.t
index bb2ab51..115a761 100644
--- a/t/integration.t
+++ b/t/integration.t
@@ -22,6 +22,13 @@ my $ar = unicorn(qw(-E none t/integration.ru -c), $conf, { 3 => $srv });
 my $curl = which('curl');
 my $fifo = "$tmpdir/fifo";
 POSIX::mkfifo($fifo, 0600) or die "mkfifo: $!";
+my $wait_fifo = sub {
+	open my $fifo_fh, '<', $fifo;
+	my $wpid = readline($fifo_fh);
+	like($wpid, qr/\Apid=\d+\z/a , 'new worker ready');
+	$wpid;
+};
+
 my %PUT = (
 	chunked_md5 => sub {
 		my ($in, $out, $path, %opt) = @_;
@@ -176,6 +183,78 @@ if ('bad requests') {
 	like($status, qr!\AHTTP/1\.[01] 414 \b!, '414 on FRAGMENT > (1024)');
 }
 
+my $tmp = { 3 => tcp_server() };
+my $no_ary = "GET /no-ary HTTP/1.1\r\nHost: example.com\r\n\r\n";
+if (diag('chunk_response is off by default w/ RACK_ENV=none') || 1) {
+	print { $c = tcp_start($srv) } $no_ary;
+	($status, $hdr) = slurp_hdr($c);
+	unlike("@$hdr", qr/Transfer-Encoding/i,
+		'no Transfer-Encoding for RACK_ENV=none despite HTTP/1.1');
+	local $/;
+	is(readline($c), "HI\n", 'unchunked body response');
+}
+
+# pretend we have Rack::Chunked for RACK_ENV=(deployment|development)
+for my $rack_env (qw(deployment development)) {
+	my $cfg = "$tmpdir/nochunk.conf.rb";
+	open my $fh, '>', $cfg;
+	my $u = unicorn('-E', $rack_env, qw(t/integration.ru -c), $cfg, $tmp);
+	$c = tcp_start($tmp->{3});
+	print $c $no_ary;
+	($status, $hdr) = slurp_hdr($c);
+	like("@$hdr", qr/Transfer-Encoding/i,
+		"Transfer-Encoding set by default for RACK_ENV=$rack_env");
+	is(do { local $/; readline($c) },
+		"3\r\nHI\n\r\n0\r\n\r\n", 'chunked body response');
+
+	print $fh <<EOM;
+chunk_response false
+after_fork { |_,_| File.open('$fifo', 'w') { |fp| fp.write "pid=#\$\$" } }
+EOM
+	close $fh;
+	$u->do_kill('HUP');
+	$wait_fifo->();
+	$c = tcp_start($tmp->{3});
+	print $c $no_ary;
+	($status, $hdr) = slurp_hdr($c);
+	unlike("@$hdr", qr/Transfer-Encoding/i,
+			"RACK_ENV=$rack_env w/o chunk_response");
+	is(do { local $/; readline($c) },
+		"HI\n", 'unchunked body response');
+}
+
+if (diag('chunk_response true w/ RACK_ENV=none') || 1) {
+	my $cfg = "$tmpdir/chunk.conf.rb";
+	open my $fh, '>', $cfg;
+	print $fh "chunk_response true\n";
+	close $fh;
+	my $u = unicorn(qw(-E none t/integration.ru -c), $cfg, $tmp);
+	$c = tcp_start($tmp->{3});
+	print $c $no_ary;
+	($status, $hdr) = slurp_hdr($c);
+	like("@$hdr", qr/Transfer-Encoding/i,
+		"Transfer-Encoding set by chunk_response false");
+	is(do { local $/; readline($c) },
+		"3\r\nHI\n\r\n0\r\n\r\n", 'chunked body response');
+
+	# reset to default:
+	open $fh, '>', $cfg;
+	print $fh <<EOM;
+after_fork { |_,_| File.open('$fifo', 'w') { |fp| fp.write "pid=#\$\$" } }
+EOM
+	close $fh;
+	$u->do_kill('HUP');
+	$wait_fifo->();
+
+	$c = tcp_start($tmp->{3});
+	print $c $no_ary;
+	($status, $hdr) = slurp_hdr($c);
+	unlike("@$hdr", qr/Transfer-Encoding/i,
+			'chunk_response false after HUP reset');
+	is(do { local $/; readline($c) },
+		"HI\n", 'unchunked body response after HUP reset');
+}
+
 # input tests
 my ($blob_size, $blob_hash);
 SKIP: {
@@ -287,9 +366,7 @@ check_client_connection true
 after_fork { |_,_| File.open('$fifo', 'w') { |fp| fp.write "pid=#\$\$" } }
 EOM
 	$ar->do_kill('HUP');
-	open my $fifo_fh, '<', $fifo;
-	my $wpid = readline($fifo_fh);
-	like($wpid, qr/\Apid=\d+\z/a , 'new worker ready');
+	$wait_fifo->();
 	$ck_early_hints->('ccc on');
 }
 
@@ -301,10 +378,7 @@ if ('max_header_len internal API') {
 Unicorn::HttpParser.max_header_len = $len
 EOM
 	$ar->do_kill('HUP');
-	open my $fifo_fh, '<', $fifo;
-	my $wpid = readline($fifo_fh);
-	like($wpid, qr/\Apid=\d+\z/a , 'new worker ready');
-	close $fifo_fh;
+	my $wpid = $wait_fifo->();
 	$wpid =~ s/\Apid=// or die;
 	ok(CORE::kill(0, $wpid), 'worker PID retrieved');
 

^ permalink raw reply related	[relevance 11%]

* [PATCH v2] chunk unterminated HTTP/1.1 responses for Rack 3.1
  @ 2023-06-05  9:12 12%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2023-06-05  9:12 UTC (permalink / raw)
  To: Jeremy Evans; +Cc: unicorn-public

Jeremy Evans <code@jeremyevans.net> wrote:
> We deprecated Rack::Chunked in Rack 3.0 and plan to remove it in Rack
> 3.1. I agree it would be best to deal with this now, I just wasn't sure
> how you wanted to handle it.  Your patch below to deal with it at the
> server level looks good, though it doesn't appear to remove the Chunked
> usage at line 69 of unicorn.rb.  I recommend that also be removed.

OK.  Also added HEAD and STATUS_WITH_NO_ENTITY_BODY checks...

No tests, yet; they'll be in Perl 5.  (I started rewriting a bunch
of tests in Perl5 last year since tests are where Ruby's yearly
breaking changes are most unacceptable to me).

No trailers for responses yet, either; I didn't realize Rack::Chunked
added special support for that in 2020.

I care deeply about trailers in requests, but never used them
for responses.

--------8<-------
Subject: [PATCH v2] chunk unterminated HTTP/1.1 responses for Rack 3.1

Rack::Chunked will be gone in Rack 3.1, so provide a
non-middleware fallback which takes advantage of IO#write
supporting multiple arguments in Ruby 2.5+.

We still need to support Ruby 2.4, at least, since Rack 3.0
does.  So a new (GC-unfriendly) Unicorn::WriteSplat module now
exists for Ruby <= 2.4 users.
---
  v2: remove Rack::Chunk load attempt
      fix arity check for Ruby <= 2.4
      update docs + examples
Interdiff:
  diff --git a/Documentation/unicorn.1 b/Documentation/unicorn.1
  index d76d40f..b2c5e70 100644
  --- a/Documentation/unicorn.1
  +++ b/Documentation/unicorn.1
  @@ -176,7 +176,7 @@ As of Unicorn 0.94.0, RACK_ENV is exported as a process\-wide environment
   variable as well.  While not current a part of the Rack specification as
   of Rack 1.0.1, this has become a de facto standard in the Rack world.
   .PP
  -Note the Rack::ContentLength and Rack::Chunked middlewares are also
  +Note the Rack::ContentLength middleware is also
   loaded by "deployment" and "development", but no other values of
   RACK_ENV.  If needed, they must be individually specified in the
   RACKUP_FILE, some frameworks do not require them.
  diff --git a/examples/echo.ru b/examples/echo.ru
  index 14908c5..e982180 100644
  --- a/examples/echo.ru
  +++ b/examples/echo.ru
  @@ -19,7 +19,6 @@ def each(&block)
   
   end
   
  -use Rack::Chunked
   run lambda { |env|
     /\A100-continue\z/i =~ env['HTTP_EXPECT'] and return [100, {}, []]
     [ 200, { 'Content-Type' => 'application/octet-stream' },
  diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
  index c339024..afdf680 100644
  --- a/ext/unicorn_http/unicorn_http.rl
  +++ b/ext/unicorn_http/unicorn_http.rl
  @@ -28,11 +28,15 @@ void init_unicorn_httpdate(void);
   #define UH_FL_TO_CLEAR 0x200
   #define UH_FL_RESSTART 0x400 /* for check_client_connection */
   #define UH_FL_HIJACK 0x800
  -#define UH_FL_RES_CHUNK_OK (1U << 12)
  +#define UH_FL_RES_CHUNK_VER (1U << 12)
  +#define UH_FL_RES_CHUNK_METHOD (1U << 13)
   
   /* all of these flags need to be set for keepalive to be supported */
   #define UH_FL_KEEPALIVE (UH_FL_KAVERSION | UH_FL_REQEOF | UH_FL_HASHEADER)
   
  +/* we can only chunk responses for non-HEAD HTTP/1.1 requests */
  +#define UH_FL_RES_CHUNKABLE (UH_FL_RES_CHUNK_VER | UH_FL_RES_CHUNK_METHOD)
  +
   static unsigned int MAX_HEADER_LEN = 1024 * (80 + 32); /* same as Mongrel */
   
   /* this is only intended for use with Rainbows! */
  @@ -146,6 +150,9 @@ request_method(struct http_parser *hp, const char *ptr, size_t len)
   {
     VALUE v = rb_str_new(ptr, len);
   
  +  if (len != 4 || memcmp(ptr, "HEAD", 4))
  +    HP_FL_SET(hp, RES_CHUNK_METHOD);
  +
     rb_hash_aset(hp->env, g_request_method, v);
   }
   
  @@ -159,7 +166,7 @@ http_version(struct http_parser *hp, const char *ptr, size_t len)
     if (CONST_MEM_EQ("HTTP/1.1", ptr, len)) {
       /* HTTP/1.1 implies keepalive unless "Connection: close" is set */
       HP_FL_SET(hp, KAVERSION);
  -    HP_FL_SET(hp, RES_CHUNK_OK);
  +    HP_FL_SET(hp, RES_CHUNK_VER);
       v = g_http_11;
     } else if (CONST_MEM_EQ("HTTP/1.0", ptr, len)) {
       v = g_http_10;
  @@ -806,9 +813,9 @@ static VALUE HttpParser_keepalive(VALUE self)
   /* :nodoc: */
   static VALUE chunkable_response_p(VALUE self)
   {
  -  struct http_parser *hp = data_get(self);
  +  const struct http_parser *hp = data_get(self);
   
  -  return HP_FL_ALL(hp, RES_CHUNK_OK) ? Qtrue : Qfalse;
  +  return HP_FL_ALL(hp, RES_CHUNKABLE) ? Qtrue : Qfalse;
   }
   
   /**
  diff --git a/lib/unicorn.rb b/lib/unicorn.rb
  index 8b1cda7..b817b77 100644
  --- a/lib/unicorn.rb
  +++ b/lib/unicorn.rb
  @@ -66,7 +66,6 @@ def self.builder(ru, op)
   
         middleware = { # order matters
           ContentLength: nil,
  -        Chunked: nil,
           CommonLogger: [ $stderr ],
           ShowExceptions: nil,
           Lint: nil,
  diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
  index 342dd0b..0ed0ae3 100644
  --- a/lib/unicorn/http_response.rb
  +++ b/lib/unicorn/http_response.rb
  @@ -12,6 +12,12 @@ module Unicorn::HttpResponse
   
     STATUS_CODES = defined?(Rack::Utils::HTTP_STATUS_CODES) ?
                    Rack::Utils::HTTP_STATUS_CODES : {}
  +  STATUS_WITH_NO_ENTITY_BODY = defined?(
  +                 Rack::Utils::STATUS_WITH_NO_ENTITY_BODY) ?
  +                 Rack::Utils::STATUS_WITH_NO_ENTITY_BODY : begin
  +    warn 'Rack::Utils::STATUS_WITH_NO_ENTITY_BODY missing'
  +    {}
  +  end
   
     # internal API, code will always be common-enough-for-even-old-Rack
     def err_response(code, response_start_sent)
  @@ -40,7 +46,7 @@ def http_response_write(socket, status, headers, body,
         code = status.to_i
         msg = STATUS_CODES[code]
         start = req.response_start_sent ? ''.freeze : 'HTTP/1.1 '.freeze
  -      term = false
  +      term = STATUS_WITH_NO_ENTITY_BODY.include?(code) || false
         buf = "#{start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
               "Date: #{httpdate}\r\n" \
               "Connection: close\r\n"
  diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb
  index 4ae4c85..c2ba75e 100644
  --- a/lib/unicorn/socket_helper.rb
  +++ b/lib/unicorn/socket_helper.rb
  @@ -15,7 +15,7 @@ def kgio_tryaccept # :nodoc:
       end
     end
   
  -  if IO.instance_method(:write).arity # Ruby <= 2.4
  +  if IO.instance_method(:write).arity == 1 # Ruby <= 2.4
       require 'unicorn/write_splat'
       UNIXClient = Class.new(Kgio::Socket) # :nodoc:
       class UNIXSrv < Kgio::UNIXServer # :nodoc:
  diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb
  index cea9791..fe98fcc 100644
  --- a/test/unit/test_server.rb
  +++ b/test/unit/test_server.rb
  @@ -196,7 +196,7 @@ def test_client_shutdown_writes
       # continue to process our request and never hit EOFError on our sock
       sock.shutdown(Socket::SHUT_WR)
       buf = sock.read
  -    assert_match %r{\bhello!\\n\b}, buf.split(/\r\n\r\n/).last
  +    assert_match %r{\bhello!\\n\b}, buf.split(/\r\n\r\n/, 2).last
       next_client = Net::HTTP.get(URI.parse("http://127.0.0.1:#@port/"))
       assert_equal 'hello!\n', next_client
       lines = File.readlines("test_stderr.#$$.log")

 Documentation/unicorn.1          |  2 +-
 examples/echo.ru                 |  1 -
 ext/unicorn_http/unicorn_http.rl | 18 ++++++++++++++++++
 lib/unicorn.rb                   |  5 ++---
 lib/unicorn/http_response.rb     | 27 ++++++++++++++++++++++++++-
 lib/unicorn/socket_helper.rb     | 18 ++++++++++++++++--
 lib/unicorn/write_splat.rb       |  7 +++++++
 test/unit/test_server.rb         |  2 +-
 8 files changed, 71 insertions(+), 9 deletions(-)
 create mode 100644 lib/unicorn/write_splat.rb

diff --git a/Documentation/unicorn.1 b/Documentation/unicorn.1
index d76d40f..b2c5e70 100644
--- a/Documentation/unicorn.1
+++ b/Documentation/unicorn.1
@@ -176,7 +176,7 @@ As of Unicorn 0.94.0, RACK_ENV is exported as a process\-wide environment
 variable as well.  While not current a part of the Rack specification as
 of Rack 1.0.1, this has become a de facto standard in the Rack world.
 .PP
-Note the Rack::ContentLength and Rack::Chunked middlewares are also
+Note the Rack::ContentLength middleware is also
 loaded by "deployment" and "development", but no other values of
 RACK_ENV.  If needed, they must be individually specified in the
 RACKUP_FILE, some frameworks do not require them.
diff --git a/examples/echo.ru b/examples/echo.ru
index 14908c5..e982180 100644
--- a/examples/echo.ru
+++ b/examples/echo.ru
@@ -19,7 +19,6 @@ def each(&block)
 
 end
 
-use Rack::Chunked
 run lambda { |env|
   /\A100-continue\z/i =~ env['HTTP_EXPECT'] and return [100, {}, []]
   [ 200, { 'Content-Type' => 'application/octet-stream' },
diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
index ba23438..afdf680 100644
--- a/ext/unicorn_http/unicorn_http.rl
+++ b/ext/unicorn_http/unicorn_http.rl
@@ -28,10 +28,15 @@ void init_unicorn_httpdate(void);
 #define UH_FL_TO_CLEAR 0x200
 #define UH_FL_RESSTART 0x400 /* for check_client_connection */
 #define UH_FL_HIJACK 0x800
+#define UH_FL_RES_CHUNK_VER (1U << 12)
+#define UH_FL_RES_CHUNK_METHOD (1U << 13)
 
 /* all of these flags need to be set for keepalive to be supported */
 #define UH_FL_KEEPALIVE (UH_FL_KAVERSION | UH_FL_REQEOF | UH_FL_HASHEADER)
 
+/* we can only chunk responses for non-HEAD HTTP/1.1 requests */
+#define UH_FL_RES_CHUNKABLE (UH_FL_RES_CHUNK_VER | UH_FL_RES_CHUNK_METHOD)
+
 static unsigned int MAX_HEADER_LEN = 1024 * (80 + 32); /* same as Mongrel */
 
 /* this is only intended for use with Rainbows! */
@@ -145,6 +150,9 @@ request_method(struct http_parser *hp, const char *ptr, size_t len)
 {
   VALUE v = rb_str_new(ptr, len);
 
+  if (len != 4 || memcmp(ptr, "HEAD", 4))
+    HP_FL_SET(hp, RES_CHUNK_METHOD);
+
   rb_hash_aset(hp->env, g_request_method, v);
 }
 
@@ -158,6 +166,7 @@ http_version(struct http_parser *hp, const char *ptr, size_t len)
   if (CONST_MEM_EQ("HTTP/1.1", ptr, len)) {
     /* HTTP/1.1 implies keepalive unless "Connection: close" is set */
     HP_FL_SET(hp, KAVERSION);
+    HP_FL_SET(hp, RES_CHUNK_VER);
     v = g_http_11;
   } else if (CONST_MEM_EQ("HTTP/1.0", ptr, len)) {
     v = g_http_10;
@@ -801,6 +810,14 @@ static VALUE HttpParser_keepalive(VALUE self)
   return HP_FL_ALL(hp, KEEPALIVE) ? Qtrue : Qfalse;
 }
 
+/* :nodoc: */
+static VALUE chunkable_response_p(VALUE self)
+{
+  const struct http_parser *hp = data_get(self);
+
+  return HP_FL_ALL(hp, RES_CHUNKABLE) ? Qtrue : Qfalse;
+}
+
 /**
  * call-seq:
  *    parser.next? => true or false
@@ -981,6 +998,7 @@ void Init_unicorn_http(void)
   rb_define_method(cHttpParser, "content_length", HttpParser_content_length, 0);
   rb_define_method(cHttpParser, "body_eof?", HttpParser_body_eof, 0);
   rb_define_method(cHttpParser, "keepalive?", HttpParser_keepalive, 0);
+  rb_define_method(cHttpParser, "chunkable_response?", chunkable_response_p, 0);
   rb_define_method(cHttpParser, "headers?", HttpParser_has_headers, 0);
   rb_define_method(cHttpParser, "next?", HttpParser_next, 0);
   rb_define_method(cHttpParser, "buf", HttpParser_buf, 0);
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index 1a50631..b817b77 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -66,7 +66,6 @@ def self.builder(ru, op)
 
       middleware = { # order matters
         ContentLength: nil,
-        Chunked: nil,
         CommonLogger: [ $stderr ],
         ShowExceptions: nil,
         Lint: nil,
@@ -75,8 +74,8 @@ def self.builder(ru, op)
 
       # return value, matches rackup defaults based on env
       # Unicorn does not support persistent connections, but Rainbows!
-      # and Zbatery both do.  Users accustomed to the Rack::Server default
-      # middlewares will need ContentLength/Chunked middlewares.
+      # does.  Users accustomed to the Rack::Server default
+      # middlewares will need ContentLength middleware.
       case ENV["RACK_ENV"]
       when "development"
       when "deployment"
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index 19469b4..0ed0ae3 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -12,6 +12,12 @@ module Unicorn::HttpResponse
 
   STATUS_CODES = defined?(Rack::Utils::HTTP_STATUS_CODES) ?
                  Rack::Utils::HTTP_STATUS_CODES : {}
+  STATUS_WITH_NO_ENTITY_BODY = defined?(
+                 Rack::Utils::STATUS_WITH_NO_ENTITY_BODY) ?
+                 Rack::Utils::STATUS_WITH_NO_ENTITY_BODY : begin
+    warn 'Rack::Utils::STATUS_WITH_NO_ENTITY_BODY missing'
+    {}
+  end
 
   # internal API, code will always be common-enough-for-even-old-Rack
   def err_response(code, response_start_sent)
@@ -35,11 +41,12 @@ def append_header(buf, key, value)
   def http_response_write(socket, status, headers, body,
                           req = Unicorn::HttpRequest.new)
     hijack = nil
-
+    do_chunk = false
     if headers
       code = status.to_i
       msg = STATUS_CODES[code]
       start = req.response_start_sent ? ''.freeze : 'HTTP/1.1 '.freeze
+      term = STATUS_WITH_NO_ENTITY_BODY.include?(code) || false
       buf = "#{start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
             "Date: #{httpdate}\r\n" \
             "Connection: close\r\n"
@@ -47,6 +54,12 @@ def http_response_write(socket, status, headers, body,
         case key
         when %r{\A(?:Date|Connection)\z}i
           next
+        when %r{\AContent-Length\z}i
+          append_header(buf, key, value)
+          term = true
+        when %r{\ATransfer-Encoding\z}i
+          append_header(buf, key, value)
+          term = true if /\bchunked\b/i === value # value may be Array :x
         when "rack.hijack"
           # This should only be hit under Rack >= 1.5, as this was an illegal
           # key in Rack < 1.5
@@ -55,12 +68,24 @@ def http_response_write(socket, status, headers, body,
           append_header(buf, key, value)
         end
       end
+      if !hijack && !term && req.chunkable_response?
+        do_chunk = true
+        buf << "Transfer-Encoding: chunked\r\n".freeze
+      end
       socket.write(buf << "\r\n".freeze)
     end
 
     if hijack
       req.hijacked!
       hijack.call(socket)
+    elsif do_chunk
+      begin
+        body.each do |b|
+          socket.write("#{b.bytesize.to_s(16)}\r\n", b, "\r\n".freeze)
+        end
+      ensure
+        socket.write("0\r\n\r\n".freeze)
+      end
     else
       body.each { |chunk| socket.write(chunk) }
     end
diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb
index 8a6f6ee..c2ba75e 100644
--- a/lib/unicorn/socket_helper.rb
+++ b/lib/unicorn/socket_helper.rb
@@ -15,6 +15,20 @@ def kgio_tryaccept # :nodoc:
     end
   end
 
+  if IO.instance_method(:write).arity == 1 # Ruby <= 2.4
+    require 'unicorn/write_splat'
+    UNIXClient = Class.new(Kgio::Socket) # :nodoc:
+    class UNIXSrv < Kgio::UNIXServer # :nodoc:
+      include Unicorn::WriteSplat
+      def kgio_tryaccept # :nodoc:
+        super(UNIXClient)
+      end
+    end
+    TCPClient.__send__(:include, Unicorn::WriteSplat)
+  else # Ruby 2.5+
+    UNIXSrv = Kgio::UNIXServer
+  end
+
   module SocketHelper
 
     # internal interface
@@ -135,7 +149,7 @@ def bind_listen(address = '0.0.0.0:8080', opt = {})
         end
         old_umask = File.umask(opt[:umask] || 0)
         begin
-          Kgio::UNIXServer.new(address)
+          UNIXSrv.new(address)
         ensure
           File.umask(old_umask)
         end
@@ -203,7 +217,7 @@ def server_cast(sock)
         Socket.unpack_sockaddr_in(sock.getsockname)
         TCPSrv.for_fd(sock.fileno)
       rescue ArgumentError
-        Kgio::UNIXServer.for_fd(sock.fileno)
+        UNIXSrv.for_fd(sock.fileno)
       end
     end
 
diff --git a/lib/unicorn/write_splat.rb b/lib/unicorn/write_splat.rb
new file mode 100644
index 0000000..7e6e363
--- /dev/null
+++ b/lib/unicorn/write_splat.rb
@@ -0,0 +1,7 @@
+# -*- encoding: binary -*-
+# compatibility module for Ruby <= 2.4, remove when we go Ruby 2.5+
+module Unicorn::WriteSplat # :nodoc:
+  def write(*arg) # :nodoc:
+    super(arg.join(''))
+  end
+end
diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb
index 98e85ab..fe98fcc 100644
--- a/test/unit/test_server.rb
+++ b/test/unit/test_server.rb
@@ -196,7 +196,7 @@ def test_client_shutdown_writes
     # continue to process our request and never hit EOFError on our sock
     sock.shutdown(Socket::SHUT_WR)
     buf = sock.read
-    assert_equal 'hello!\n', buf.split(/\r\n\r\n/).last
+    assert_match %r{\bhello!\\n\b}, buf.split(/\r\n\r\n/, 2).last
     next_client = Net::HTTP.get(URI.parse("http://127.0.0.1:#@port/"))
     assert_equal 'hello!\n', next_client
     lines = File.readlines("test_stderr.#$$.log")



^ permalink raw reply related	[relevance 12%]

* Re: [PATCH] Master promotion with SIGURG (CoW optimization)
  2022-07-06  7:40  0%   ` Jean Boussier
@ 2022-07-07 10:23  0%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2022-07-07 10:23 UTC (permalink / raw)
  To: Jean Boussier; +Cc: unicorn-public

Jean Boussier <jean.boussier@shopify.com> wrote:
> > OK, any numbers from Puma users which can be used to project
> > improvements for unicorn (and other servers)?
> 
> There are some user reports here: https://github.com/puma/puma/issues/2258
> but they are mixed in reports for two other new featurs.
> 
> Some reports are up to 20-30% savings, but I'd expect unicorn to benefit
> even more from it, given that typical puma users spawn less processes
> than with unicorn.

OK, those numbers sound very good (but I can't view
graphics/screenshots from w3m)

> > > They also include automatic reforking after a predetermined amount
> > > of requests (1k by default).
> >
> > 1k seems like a lot of requests (more on this below)
> 
> Agreed. Shared pages start being invalidated much faster than that.
> 
> > > - master: on `SIGURG`
> > >   - Forward `SIGURG` to a chosen worker.
> >
> > OK, I guess SIGURG is safe to use since nobody else relies on it (right?).
> 
> That's my understanding, an alternative could be to re-use USR2 and have a
> config flag to define wether it is a rexec or refork.

SIGURG is fine, having SIGUSR2 mean two things seems fragile and error-prone

> > Right.  PID file races and corner cases were painful to deal
> > with in the earliest days of this project, and I don't look
> > forward to having to deal with them ever again...
> >
> > It looked like the world was moving towards socket-activation
> > with dedicated process managers and away from fragile PID files;
> > so being self-daemonization dependent seems like a step back.
> 
> Agreed. We're currently running unicorn as PID 1 inside containers
> and I'm not exactly looking forward to have to minitor a PID file.
> 
> Another avenue I explored was to keep the existing master and
> refork from one of the worker like puma, but re-assign the parent
> to the orignal master using PR_SET_CHILD_SUBREAPER.
> 
> Here's my notes of how it works:
> 
> ### Requirements:
> 
> - Need `PR_SET_CHILD_SUBREAPER`, so Linux 3.4+ only (May 2012)

I'm fine with requiring Linux for this feature, existing
features need to continue working on *BSD...

> - Need `File.mkfifo`, so Ruby 2.3 (Dec 2015), but can be shimed for older
>   rubies.

I don't think it's necessary to use FIFOs at all (see below)

> ### Flow:
> 
> - master: set `PR_SET_CHILD_SUBREAPER` during boot.
> - master: create a temporary directory (`$TMP`).
> - master: spawn initial workers the old way.
> 
> - master: on `SIGCHLD` (a child died):
>   - Fake signal oldest worker (`SIGURG`).
>   - Write the new worker number in the fake signal pipe (at the same time).
> 
> - worker: on `SIGURG` (should spawn a sibling):
>   - Note: worker fake signals are processed after the current request is
>     completed.
>   - Run `before_fork` callback (MAYBE: need a special `before_refork`
>     callback?)
>   - create a pipe.
>   - daemonize (fork twice so that the new process is attributed to the
>     nearest `CHILD_SUBREAPER`, aka the original master).
>   - wait for the first child to exit.
>   - write into the pipe to signal the parent is dead.
>   - Run `after_fork` callback (MAYBE: need a special `after_refork` callback?)

*_fork callbacks already work for your current patch, though, right?;
so hopefully *_refork won't be needed...

> - new sibling after fork:
>   - wait for the parent to exit (though the temporary pipe).
>   - create a named pipe (`File.mkfifo`) at `$TMP/$WORKER_NUM.pipe`.
>   - create a pidfile at `$TMP/WORKER_NUM.pid`.
>   - Open the named pipe in `IO::RDONLY | IO::NONBLOCK` (otherwise it would
>     block until the master open in write mode).
>     - NB: Need to convert it to a `Kgio::Pipe` with
>       `Kgio::Pipe.for_fd(f.to_i)`, and keep `f` need `autoclose = false`.

sidenote: no need for kgio, I've been meaning to get rid of it
(Ruby 2.3+ has everything we'd need, I think...)

>   - Create the `Unicorn::Worker` instance with that pipe and worker number.
>   - Send `SIGURG` to the parent process (should be the master).
>   - Wait for `SIGCONT` in the named pipe.
>   - enter the worker loop.
> 
> - master: on `SIGURG`:
>   - for each outstanding refork order:
>     - Look for `$TMP/$WORKER_NUM.pid` and `$TMP/$WORKER_NUM.pipe`
>     - Read the pidfile
>     - Open the pipe with `IO::RDONLY | IO::NONBLOCK`
>       - NB: Need to convert it to a `Kgio::Pipe` with
>         `Kgio::Pipe.for_fd(f.to_i)`, and keep `f` need `autoclose = false`.
>     - Delete pidfile and named pipe.
>     - Register that new worker normally.
>     - Write `SIGCONT` into the pipe.
> 
> I can share the patch if you are interested, but the extra complexity
> and Linux only features made me prefer the master-promotion approach.

I would prefer this Linux-only approach if it gets rid of PID
files and doesn't introduce new temporary files/FIFOs.

It seems socketpair(..., SOCK_SEQPACKET) can be used for
packetized bidirectional IPC, perhaps with send_io + recv_io iff
necessary.  There shouldn't be any need for new, fragile FS
interactions.


Another idea, have you considered letting master work on some requests?
Signal handling would be delayed, and EINTR handling bugs in
gems could be exposed, but it'd be completely portable...

> > > However it work well enough for demonstration.
> > >
> > > So I figured I'd ask wether the feature is desired upstream
> > > before investing more effort into it.
> >
> > It really depends on:
> >
> > 1) what memory savings and/or speedups can be achieved
> >
> > 2) what support can we expect from you (and other users) for
> >    this feature and potential regressions going forward?
> >
> > I don't have the free time nor mental capacity to deal with
> > fallout from major new features such as this, myself.
> 
> Yeah, this is just a RFC, I wouldn't submit a final patch without
> first deploying it on our infra with good results. I'm just on the
> fence between trying to get this upstream vs maintaining our own
> server that solely work like this, hence somewhat simpler and that
> can make more assumptions.

Of course you also realize unicorn remains culturally-incompatible
with 99.9% of the open source world since I refuse to rely on
graphics drivers to work on a daemon, proprietary software,
terms-of-service, etc...

If anything goes wrong, I'd likely CC you anyways.

> > The hook interface would be yet another documentation+support
> > burden I'm worried about (and also more unicorn-specific stuff
> > to lock people in :<).
> 
> Understandable. I suppose it can be done with a monitoring process.
> Check `smaps_rollup` and send `SIGURG` when deemed necessary.
> 
> More moving pieces but keep unicorn simpler.

*shrug*  I've also been favoring more vertical integration in
other places to keep the overall stack simpler.

It depends on whether the monitoring process/library can work
with other Rack servers, probably; and signal compatibility.

> > A completely different idea which should achieve the same goal,
> > completely independent of unicorn:
> >
> >   App startup/loading can be made to trigger warmup paths which
> >   hit common endpoints.  IOW, app loading could run a small
> >   warmup suite which simulates common requests to heat up caches
> >   and trigger JIT.
> 
> Yeah, I don't really believe in this for a few reasons:
> 
>   - That would slow boot time.

Yes, and startup time is already a nasty thing, anyways...

>   - On large apps there's just too many codepath for this to be realistic.

I was thinking a lazy solution could be to have some middleware
measure coverage and log requests to support auto-replay, somehow.

>   - Many endpoints require database and other network access you probably
>     don't want in the master.

Wouldn't the *_fork hooks handle that, anyways?

>   - Endpoints may have side effects.

Yeah, this would optimize the GET endpoints, at least.
Not sure what percentage of POST needs to be optimized...

> > Ultimately (long-term for ruby-core), it would be better to make
> > JIT (and perhaps even VM cache) results persistent and shareable
> > across different processes, somehow...  That would help all Ruby
> > tools, even short-lived CLI tools.  Portable locking would be a
> > pain, I suppose, but proprietary OSes are always a pain :P
> 
> Based on my limited understanding of both JIT and VM caches, I don't think
> that's really possible.

Ugh, I still think it can be made possible, somehow.  But I no longer
use Ruby for new projects...

> The VM itself could definitely do better CoW wise, and I have some proposals
> on that front (https://bugs.ruby-lang.org/issues/18885) but that will take
> time and will never be perfect.
> 
> That's why I think periodically promoting a new master has potential.
> 
> > There's some line-wrapping issues caused by your MUA;
> 
> Urk. Ok, trying another client now, and I'll resend the patch.

Nope, still wrapped.  According to the git-format-patch(1) manpage,
Thunderbird can work w/o extensions, actually.

IME attachments might work mostly well, nowadays (test sending
to yourself and using "git am" to apply, first, of course).
Most on vger will disagree with me on attachments, though...

"git send-email" and "git imap-send" remain the recommended
options, but mutt works well, too.

> > Perhaps documenting this as experimental and subject to removal
> > at any time would make the addition of a major new feature an
> > easier pill to swallow; but I still think this is better outside
> > of app servers.
> 
> Up to you, if you don't feel like maintaining such a feature I would
> perfectly understand.

I'm fine with "maintaining it" if it just means Cc-ing you on
bugs related to this :>

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] Master promotion with SIGURG (CoW optimization)
  2022-07-06  2:33  4% ` Eric Wong
@ 2022-07-06  7:40  0%   ` Jean Boussier
  2022-07-07 10:23  0%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Jean Boussier @ 2022-07-06  7:40 UTC (permalink / raw)
  Cc: unicorn-public

> OK, any numbers from Puma users which can be used to project
> improvements for unicorn (and other servers)?

There are some user reports here: https://github.com/puma/puma/issues/2258
but they are mixed in reports for two other new featurs.

Some reports are up to 20-30% savings, but I'd expect unicorn to benefit
even more from it, given that typical puma users spawn less processes
than with unicorn.

> > They also include automatic reforking after a predetermined amount
> > of requests (1k by default).
>
> 1k seems like a lot of requests (more on this below)

Agreed. Shared pages start being invalidated much faster than that.

> > - master: on `SIGURG`
> >   - Forward `SIGURG` to a chosen worker.
>
> OK, I guess SIGURG is safe to use since nobody else relies on it (right?).

That's my understanding, an alternative could be to re-use USR2 and have a
config flag to define wether it is a rexec or refork.

> Right.  PID file races and corner cases were painful to deal
> with in the earliest days of this project, and I don't look
> forward to having to deal with them ever again...
>
> It looked like the world was moving towards socket-activation
> with dedicated process managers and away from fragile PID files;
> so being self-daemonization dependent seems like a step back.

Agreed. We're currently running unicorn as PID 1 inside containers
and I'm not exactly looking forward to have to minitor a PID file.

Another avenue I explored was to keep the existing master and
refork from one of the worker like puma, but re-assign the parent
to the orignal master using PR_SET_CHILD_SUBREAPER.

Here's my notes of how it works:

### Requirements:

- Need `PR_SET_CHILD_SUBREAPER`, so Linux 3.4+ only (May 2012)
- Need `File.mkfifo`, so Ruby 2.3 (Dec 2015), but can be shimed for older
  rubies.

### Flow:

- master: set `PR_SET_CHILD_SUBREAPER` during boot.
- master: create a temporary directory (`$TMP`).
- master: spawn initial workers the old way.

- master: on `SIGCHLD` (a child died):
  - Fake signal oldest worker (`SIGURG`).
  - Write the new worker number in the fake signal pipe (at the same time).

- worker: on `SIGURG` (should spawn a sibling):
  - Note: worker fake signals are processed after the current request is
    completed.
  - Run `before_fork` callback (MAYBE: need a special `before_refork`
    callback?)
  - create a pipe.
  - daemonize (fork twice so that the new process is attributed to the
    nearest `CHILD_SUBREAPER`, aka the original master).
  - wait for the first child to exit.
  - write into the pipe to signal the parent is dead.
  - Run `after_fork` callback (MAYBE: need a special `after_refork` callback?)

- new sibling after fork:
  - wait for the parent to exit (though the temporary pipe).
  - create a named pipe (`File.mkfifo`) at `$TMP/$WORKER_NUM.pipe`.
  - create a pidfile at `$TMP/WORKER_NUM.pid`.
  - Open the named pipe in `IO::RDONLY | IO::NONBLOCK` (otherwise it would
    block until the master open in write mode).
    - NB: Need to convert it to a `Kgio::Pipe` with
      `Kgio::Pipe.for_fd(f.to_i)`, and keep `f` need `autoclose = false`.
  - Create the `Unicorn::Worker` instance with that pipe and worker number.
  - Send `SIGURG` to the parent process (should be the master).
  - Wait for `SIGCONT` in the named pipe.
  - enter the worker loop.

- master: on `SIGURG`:
  - for each outstanding refork order:
    - Look for `$TMP/$WORKER_NUM.pid` and `$TMP/$WORKER_NUM.pipe`
    - Read the pidfile
    - Open the pipe with `IO::RDONLY | IO::NONBLOCK`
      - NB: Need to convert it to a `Kgio::Pipe` with
        `Kgio::Pipe.for_fd(f.to_i)`, and keep `f` need `autoclose = false`.
    - Delete pidfile and named pipe.
    - Register that new worker normally.
    - Write `SIGCONT` into the pipe.

I can share the patch if you are interested, but the extra complexity
and Linux only features made me prefer the master-promotion approach.

> > However it work well enough for demonstration.
> >
> > So I figured I'd ask wether the feature is desired upstream
> > before investing more effort into it.
>
> It really depends on:
>
> 1) what memory savings and/or speedups can be achieved
>
> 2) what support can we expect from you (and other users) for
>    this feature and potential regressions going forward?
>
> I don't have the free time nor mental capacity to deal with
> fallout from major new features such as this, myself.

Yeah, this is just a RFC, I wouldn't submit a final patch without
first deploying it on our infra with good results. I'm just on the
fence between trying to get this upstream vs maintaining our own
server that solely work like this, hence somewhat simpler and that
can make more assumptions.

> The hook interface would be yet another documentation+support
> burden I'm worried about (and also more unicorn-specific stuff
> to lock people in :<).

Understandable. I suppose it can be done with a monitoring process.
Check `smaps_rollup` and send `SIGURG` when deemed necessary.

More moving pieces but keep unicorn simpler.

> A completely different idea which should achieve the same goal,
> completely independent of unicorn:
>
>   App startup/loading can be made to trigger warmup paths which
>   hit common endpoints.  IOW, app loading could run a small
>   warmup suite which simulates common requests to heat up caches
>   and trigger JIT.

Yeah, I don't really believe in this for a few reasons:

  - That would slow boot time.
  - On large apps there's just too many codepath for this to be realistic.
  - Many endpoints require database and other network access you probably
    don't want in the master.
  - Endpoints may have side effects.

> Ultimately (long-term for ruby-core), it would be better to make
> JIT (and perhaps even VM cache) results persistent and shareable
> across different processes, somehow...  That would help all Ruby
> tools, even short-lived CLI tools.  Portable locking would be a
> pain, I suppose, but proprietary OSes are always a pain :P

Based on my limited understanding of both JIT and VM caches, I don't think
that's really possible.

The VM itself could definitely do better CoW wise, and I have some proposals
on that front (https://bugs.ruby-lang.org/issues/18885) but that will take
time and will never be perfect.

That's why I think periodically promoting a new master has potential.

> There's some line-wrapping issues caused by your MUA;

Urk. Ok, trying another client now, and I'll resend the patch.

> Perhaps documenting this as experimental and subject to removal
> at any time would make the addition of a major new feature an
> easier pill to swallow; but I still think this is better outside
> of app servers.

Up to you, if you don't feel like maintaining such a feature I would
perfectly understand.

---
 SIGNALS                        |   4 ++
 lib/unicorn.rb                 |   2 +-
 lib/unicorn/http_server.rb     | 115 +++++++++++++++++++++++++--------
 lib/unicorn/promoted_worker.rb |  40 ++++++++++++
 4 files changed, 134 insertions(+), 27 deletions(-)
 create mode 100644 lib/unicorn/promoted_worker.rb

diff --git a/SIGNALS b/SIGNALS
index 7321f2b..f5716b9 100644
--- a/SIGNALS
+++ b/SIGNALS
@@ -39,6 +39,10 @@ https://yhbt.net/unicorn/examples/init.sh
 * WINCH - gracefully stops workers but keep the master running.
   This will only work for daemonized processes.

+* URG - promote one of the existing workers as a new master, and gracefully
+  stop workers.
+  This will only work for daemonized processes.
+
 * TTIN - increment the number of worker processes by one

 * TTOU - decrement the number of worker processes by one
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index 1a50631..832f78d 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -133,6 +133,6 @@ def self.pipe # :nodoc:
 # :enddoc:

 %w(const socket_helper stream_input tee_input http_request configurator
-   tmpio util http_response worker http_server).each do |s|
+   tmpio util http_response worker promoted_worker http_server).each do |s|
   require_relative "unicorn/#{s}"
 end
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 21f2a05..dd8f021 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -50,6 +50,7 @@ class Unicorn::HttpServer
   #   Unicorn::HttpServer::START_CTX[0] = "/home/bofh/2.3.0/bin/unicorn"
   START_CTX = {
     :argv => ARGV.map(&:dup),
+    :generation => 0,
     0 => $0.dup,
   }
   # We favor ENV['PWD'] since it is (usually) symlink aware for Capistrano
@@ -106,7 +107,7 @@ def initialize(app, options = {})
     @orig_app = app
     # list of signals we care about and trap in master.
     @queue_sigs = [
-      :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
+      :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU, :URG ]

     @worker_data = if worker_data = ENV['UNICORN_WORKER']
       worker_data = worker_data.split(',').map!(&:to_i)
@@ -119,7 +120,24 @@ def initialize(app, options = {})

   # Runs the thing.  Returns self so you can run join on it
   def start
+    @new_master = false
     inherit_listeners!
+    promote
+
+    # write pid early for Mongrel compatibility if we're not inheriting sockets
+    # This is needed for compatibility some Monit setups at least.
+    # This unfortunately has the side effect of clobbering valid PID if
+    # we upgrade and the upgrade breaks during preload_app==true && build_app!
+    self.pid = config[:pid]
+
+    build_app! if preload_app
+    bind_new_listeners!
+
+    spawn_missing_workers
+    self
+  end
+
+  def promote
     # this pipe is used to wake us up from select(2) in #join when signals
     # are trapped.  See trap_deferred.
     @self_pipe.replace(Unicorn.pipe)
@@ -130,18 +148,6 @@ def start
     # Note that signals don't actually get handled until the #join method
     @queue_sigs.each { |sig| trap(sig) { @sig_queue << sig; awaken_master } }
     trap(:CHLD) { awaken_master }
-
-    # write pid early for Mongrel compatibility if we're not inheriting sockets
-    # This is needed for compatibility some Monit setups at least.
-    # This unfortunately has the side effect of clobbering valid PID if
-    # we upgrade and the upgrade breaks during preload_app==true && build_app!
-    self.pid = config[:pid]
-
-    build_app! if preload_app
-    bind_new_listeners!
-
-    spawn_missing_workers
-    self
   end

   # replaces current listener set with +listeners+.  This will
@@ -178,16 +184,16 @@ def logger=(obj)
     Unicorn::HttpRequest::DEFAULTS["rack.logger"] = @logger = obj
   end

-  def clobber_pid(path)
+  def clobber_pid(path, content = $$)
     unlink_pid_safe(@pid) if @pid
     if path
       fp = begin
-        tmp = "#{File.dirname(path)}/#{rand}.#$$"
+        tmp = "#{File.dirname(path)}/#{rand}.#{content}"
         File.open(tmp, File::RDWR|File::CREAT|File::EXCL, 0644)
       rescue Errno::EEXIST
         retry
       end
-      fp.syswrite("#$$\n")
+      fp.syswrite("#{content}\n")
       File.rename(fp.path, path)
       fp.close
     end
@@ -279,6 +285,11 @@ def join
       end
       @ready_pipe = @ready_pipe.close rescue nil
     end
+
+    if @promoted
+      Process.kill(:WINCH, Process.ppid)
+    end
+
     begin
       reap_all_workers
       case @sig_queue.shift
@@ -292,6 +303,13 @@ def join
           @logger.debug("waiting #{sleep_time}s after suspend/hibernation")
         end
         maintain_worker_count if respawn
+
+        if @new_master && @new_master.ready? && @workers.empty?
+          # TODO: we should handle the new master dying like with reexec.
+          clobber_pid(pid, @new_master.pid)
+          break
+        end
+
         master_sleep(sleep_time)
       when :QUIT # graceful shutdown
         break
@@ -305,10 +323,20 @@ def join
         soft_kill_each_worker(:USR1)
       when :USR2 # exec binary, stay alive in case something went wrong
         reexec
+      when :URG
+        if $stdin.tty?
+          logger.info "SIGURG ignored because we're not daemonized"
+        else
+          promote_new_master
+        end
       when :WINCH
         if $stdin.tty?
           logger.info "SIGWINCH ignored because we're not daemonized"
         else
+          if @new_master
+            @new_master.ready!
+          end
+
           respawn = false
           logger.info "gracefully stopping all workers"
           soft_kill_each_worker(:QUIT)
@@ -408,11 +436,30 @@ def reap_all_workers
         worker = @workers.delete(wpid) and worker.close rescue nil
         @after_worker_exit.call(self, worker, status)
       end
+
+      if @new_master && @new_master.ready?
+        @new_master.scale(@workers.size)
+      end
     rescue Errno::ECHILD
       break
     end while true
   end

+  def promote_new_master
+    # Promoting the oldest worker
+    # TODO: handle `@new_master` being dead.
+    if @new_master
+      logger.error "can't promote because worker=#{@new_master.nr} is
being promoted"
+    elsif pair = @workers.first
+      @new_master = Unicorn::PromotedWorker.new(*pair, worker_processes)
+      @workers.delete(@new_master.pid)
+      logger.info "master promoting worker=#{@new_master.worker.nr}"
+      @new_master.promote
+    else
+      logger.error "can't promote because there is no existing workers"
+    end
+  end
+
   # reexecutes the START_CTX with a new binary
   def reexec
     if @reexec_pid > 0
@@ -516,10 +563,11 @@ def murder_lazy_workers
   end

   def after_fork_internal
+    self.worker_processes = 0
     @self_pipe.each(&:close).clear # this is master-only, now
     @ready_pipe.close if @ready_pipe
     Unicorn::Configurator::RACKUP.clear
-    @ready_pipe = @init_listeners = @before_exec = @before_fork = nil
+    @ready_pipe = nil

     # The OpenSSL PRNG is seeded with only the pid, and apps with frequently
     # dying workers can recycle pids
@@ -545,6 +593,13 @@ def spawn_missing_workers
       unless pid
         after_fork_internal
         worker_loop(worker)
+
+        if @promoted
+          worker.tick = 0
+          promote
+          join
+        end
+
         exit
       end

@@ -678,19 +733,22 @@ def init_worker_process(worker)
     trap(:CHLD, 'DEFAULT')
     @sig_queue.clear
     proc_name "worker[#{worker.nr}]"
-    START_CTX.clear
     @workers.clear

     after_fork.call(self, worker) # can drop perms and create listeners
     LISTENERS.each { |sock| sock.close_on_exec = true }

     worker.user(*user) if user.kind_of?(Array) && ! worker.switched
-    @config = nil
     build_app! unless preload_app
-    @after_fork = @listener_opts = @orig_app = nil
+    @listener_opts = @orig_app = nil
     readers = LISTENERS.dup
     readers << worker
     trap(:QUIT) { nuke_listeners!(readers) }
+    @promoted = false
+    trap(:URG) do
+      @promoted = true
+      START_CTX[:generation] += 1
+    end
     readers
   end

@@ -706,11 +764,11 @@ def reopen_worker_logs(worker_nr)

   def prep_readers(readers)
     wtr = Unicorn::Waiter.prep_readers(readers)
-    @timeout *= 500 # to milliseconds for epoll, but halved
+    @select_timeout = @timeout * 500 # to milliseconds for epoll, but halved
     wtr
   rescue
     require_relative 'select_waiter'
-    @timeout /= 2.0 # halved for IO.select
+    @select_timeout = @timeout / 2.0 # halved for IO.select
     Unicorn::SelectWaiter.new
   end

@@ -720,7 +778,7 @@ def prep_readers(readers)
   def worker_loop(worker)
     readers = init_worker_process(worker)
     waiter = prep_readers(readers)
-    reopen = false
+    promote = reopen = false

     # this only works immediately if the master sent us the signal
     # (which is the normal case)
@@ -739,12 +797,17 @@ def worker_loop(worker)
           process_client(client)
           worker.tick = time_now.to_i
         end
+        if @promoted
+          worker.tick = time_now.to_i
+          return
+        end
+
         break if reopen
       end

       # timeout so we can .tick and keep parent from SIGKILL-ing us
       worker.tick = time_now.to_i
-      waiter.get_readers(ready, readers, @timeout)
+      waiter.get_readers(ready, readers, @select_timeout)
     rescue => e
       redo if reopen && readers[0]
       Unicorn.log_error(@logger, "listen loop error", e) if readers[0]
@@ -823,8 +886,8 @@ def build_app!
   end

   def proc_name(tag)
-    $0 = ([ File.basename(START_CTX[0]), tag
-          ]).concat(START_CTX[:argv]).join(' ')
+    $0 = ([ File.basename(START_CTX[0]), tag, "(gen:
#{START_CTX[:generation]})",
+          ]).concat(START_CTX[:argv]).compact.join(' ')
   end

   def redirect_io(io, path)
diff --git a/lib/unicorn/promoted_worker.rb b/lib/unicorn/promoted_worker.rb
new file mode 100644
index 0000000..2595182
--- /dev/null
+++ b/lib/unicorn/promoted_worker.rb
@@ -0,0 +1,40 @@
+# -*- encoding: binary -*-
+
+class Unicorn::PromotedWorker
+  attr_reader :pid, :worker
+
+  def initialize(pid, worker, expected_worker_processes)
+    @pid = pid
+    @worker = worker
+    @worker_processes = 0
+    @expected_worker_processes = expected_worker_processes
+    @ready = false
+  end
+
+  def ready?
+    @ready
+  end
+
+  def ready!
+    @ready = true
+  end
+
+  def promote
+    @worker.soft_kill(:URG)
+  end
+
+  def scale(old_master_worker_processes)
+    diff = @expected_worker_processes -
+      old_master_worker_processes -
+      @worker_processes
+
+    if diff > 0
+      diff.times { kill(:TTIN) }
+      @worker_processes += diff
+    end
+  end
+
+  def kill(sig)
+    Process.kill(sig, @pid)
+  end
+end
-- 
2.35.1

^ permalink raw reply related	[relevance 0%]

* Re: [PATCH] Master promotion with SIGURG (CoW optimization)
  @ 2022-07-06  2:33  4% ` Eric Wong
  2022-07-06  7:40  0%   ` Jean Boussier
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2022-07-06  2:33 UTC (permalink / raw)
  To: Jean Boussier; +Cc: unicorn-public

Jean Boussier <jean.boussier@shopify.com> wrote:
> Unicorn rely on Copy on Write to limit applications' memory usage,
> however Ruby Copy on Write performance isn't exactly perfect.
> As code get executed various internal performance caches get warmed
> which cause shared pages to be invalidated.
> 
> While there's certainly some improvements to be made to Ruby itself
> on that front, it will likely get worse in the near future if YJIT
> become popular, as it will generate executable code in the workers
> hence won't be shared.
> 
> One way effective CoW performance could be improved would be to
> periodically promote one worker as the new master. Since that worker
> processed some requests, VM caches, JITed code, etc should be somewhat
> warm already, hence shared pages should be dirtied less frequently after
> each promotion.

Agreed, there's potential for savings, here...

> Puma 5.0.0 introduced a similar experimental feature called
> `fork_worker` or `refork`.
> 
> It's a bit more limited though, as instead of promoting a new
> master and exiting, they only ask worker #0 to fork itself to
> replace its siblings. So once all workers are replaces, there
> is 3 levels of processes: cluster -> first_worker -> other_workers.

OK, any numbers from Puma users which can be used to project
improvements for unicorn (and other servers)?

> They also include automatic reforking after a predetermined amount
> of requests (1k by default).

1k seems like a lot of requests (more on this below)

> The happy path works pretty much like this:
> 
> - Assume daemonized mode.
> 
> - master: on `SIGURG`
>   - Forward `SIGURG` to a chosen worker.

OK, I guess SIGURG is safe to use since nobody else relies on it (right?).

> - worker: on `SIGURG` (become a master)
>   - do the prep, register traps, open self-pipe, etc
>   - don't spawn any worker, set number of wokers to 0.
>   - send `SIGWHINCH` to master.
> 
> - old master: on `SIGWHINCH`
>   - Gracefully shutdown workers, like during a reexec.

nit: only one `H' in `SIGWINCH`

> - old master: when a worker is reaped.
>   - Send `SIGTTIN` to the new master
>   - If it was the last worker:
>     - replace pidfile
>     - exit
> 
> This patch is not exactly production quality yet:
> 
>   - I need to write some tests
>   - There's a race condition that can cause the promoted master
>     master to have one less worker than required. Need to be addressed.
>   - The pidfile replacement should be improved.
>   - Multiple corner cases like a `QUIT` during promotion are not handled.

Right.  PID file races and corner cases were painful to deal
with in the earliest days of this project, and I don't look
forward to having to deal with them ever again...

It looked like the world was moving towards socket-activation
with dedicated process managers and away from fragile PID files;
so being self-daemonization dependent seems like a step back.

> However it work well enough for demonstration.
> 
> So I figured I'd ask wether the feature is desired upstream
> before investing more effort into it.

It really depends on:

1) what memory savings and/or speedups can be achieved

2) what support can we expect from you (and other users) for
   this feature and potential regressions going forward?

I don't have the free time nor mental capacity to deal with
fallout from major new features such as this, myself.

> For this to be used in production without too much integration effort
> I think automatic promotion based on some criteria like number of
> request or process lifetime would be needed.
> 
> Ideally a hook interface to programatically trigger promotion would
> be very valuable as I'd likely want to trigger promotion
> based on memory metrics read from `/proc/<pid>/smaps_rollup`.

The hook interface would be yet another documentation+support
burden I'm worried about (and also more unicorn-specific stuff
to lock people in :<).


A completely different idea which should achieve the same goal,
completely independent of unicorn:

  App startup/loading can be made to trigger warmup paths which
  hit common endpoints.  IOW, app loading could run a small
  warmup suite which simulates common requests to heat up caches
  and trigger JIT.

  That would be completely self-contained in each app and work
  on every single app server; not just ones with special
  provisions to deal with this.  Of course, CoW-aware setups
  (preload_app) will still have the advantage, here.

  Best of all, it could be deterministic, too, instead of
  waiting and hoping 1k random requests will be sufficient
  warmup, developers can tune and mock exactly the requests
  required for warmup.  Of course, a lazy developer replay 1k
  requests from an old log, too.


Ultimately (long-term for ruby-core), it would be better to make
JIT (and perhaps even VM cache) results persistent and shareable
across different processes, somehow...  That would help all Ruby
tools, even short-lived CLI tools.  Portable locking would be a
pain, I suppose, but proprietary OSes are always a pain :P

>  4 files changed, 134 insertions(+), 27 deletions(-)
>  create mode 100644 lib/unicorn/promoted_worker.rb

There's some line-wrapping issues caused by your MUA;
I got this from "git am":

  warning: Patch sent with format=flowed; space at the end of lines might be lost.
  Applying: Master promotion with SIGURG (CoW optimization)
  error: corrupt patch at line 14

The git-format-patch(1) manpage has a section for Thunderbird users
which may help.

> --- a/SIGNALS
> +++ b/SIGNALS
> @@ -39,6 +39,10 @@ https://yhbt.net/unicorn/examples/init.sh
>  * WINCH - gracefully stops workers but keep the master running.
>    This will only work for daemonized processes.
> 
> +* URG - promote one of the existing workers as a new master, and gracefully
> +  stop workers.
> +  This will only work for daemonized processes.

Perhaps documenting this as experimental and subject to removal
at any time would make the addition of a major new feature an
easier pill to swallow; but I still think this is better outside
of app servers.

^ permalink raw reply	[relevance 4%]

* [PATCH 3/3] doc: v3 .onion updates, nntp => nntps, minor wording changes
  @ 2021-12-25 17:41 10% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2021-12-25 17:41 UTC (permalink / raw)
  To: unicorn-public

Tor v2 .onion support is deprecated, so we're stuck with longer
(but more secure :P) v3 .onion names.  Use NNTPS where available
instead of NNTP to reduce the likelyhood of MiTM censorship and
injection.
---
 .olddoc.yml  | 11 +++++++----
 CONTRIBUTORS |  8 ++++++--
 ISSUES       | 38 ++++++++++++++++++--------------------
 README       |  8 ++++----
 4 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/.olddoc.yml b/.olddoc.yml
index 0609bdbf..10ddc073 100644
--- a/.olddoc.yml
+++ b/.olddoc.yml
@@ -3,7 +3,7 @@ cgit_url: https://yhbt.net/unicorn.git
 rdoc_url: https://yhbt.net/unicorn/
 ml_url:
 - https://yhbt.net/unicorn-public/
-- http://ou63pmih66umazou.onion/unicorn-public/
+- http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/unicorn-public/
 merge_html:
   unicorn_1: Documentation/unicorn.1.html
   unicorn_rails_1: Documentation/unicorn_rails.1.html
@@ -13,10 +13,13 @@ noindex:
 - TODO
 - unicorn_rails_1
 public_email: unicorn-public@yhbt.net
+imap_url:
+- imaps://yhbt.net/inbox.comp.lang.ruby.unicorn.0
+- imap://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.unicorn.0
 nntp_url:
-- nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-- nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.unicorn
+- nntps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
+- nntp://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.unicorn
 - nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
 source_code:
 - git clone https://yhbt.net/unicorn.git
-- torsocks git clone http://ou63pmih66umazou.onion/unicorn.git
+- torsocks git clone http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/unicorn.git
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index bda399bc..9991fdca 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1,5 +1,9 @@
-Unicorn developers (let us know if we forgot you):
-* Eric Wong (BDFL, BOFH)
+Unicorn developers (let us know if we forgot you, ...or if you no longer wish
+to be associated with the doofus running this disaster :P):
+* Eric Wong (Bozo Doofus For Life, Bastard Operator From Hell)
+
+There's numerous contributors over email the years, all of our mail
+is archived @ https://yhbt.net/unicorn-public/
 * Suraj N. Kurapati
 * Andrey Stikheev
 * Wayne Larsen
diff --git a/ISSUES b/ISSUES
index 4513ad5b..015de37c 100644
--- a/ISSUES
+++ b/ISSUES
@@ -20,6 +20,10 @@ can interoperate with any bug tracker which can Cc: us plain-text to
 mailto:unicorn-public@yhbt.net   This includes the Debian BTS
 at https://bugs.debian.org/unicorn and possibly others.
 
+unicorn is a server; it does not depend on graphics/audio.  Nobody
+communicating with us will ever be expected to go through the trouble
+of setting up graphics nor audio support.
+
 If your issue is of a sensitive nature or you're just shy in public,
 use anonymity tools such as Tor or Mixmaster; and rely on the public
 mail archives for responses.  Be sure to scrub sensitive log messages
@@ -73,27 +77,21 @@ document distributed with git) on guidelines for patch submission.
 
 == Contact Info
 
-* public: mailto:unicorn-public@yhbt.net
-* nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
-* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-* imaps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn.0
-* https://yhbt.net/unicorn-public/
-* http://ou63pmih66umazou.onion/unicorn-public/
-
-Mailing list subscription is optional, so Cc: all participants.
+Mail is publicly-archived, SMTP subscription is discouraged to avoid
+servers being a single-point-of-failure, so Cc: all participants.
 
-You can follow along via NNTP or IMAP (read-only):
+The HTTP(S) archives have links to per-thread Atom feeds and downloadable
+mboxes.  Read-only IMAP(S) folders and NNTP(S) newsgroups are also available.
 
-	nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-	nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
-	imaps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn.0
-	imap://ou63pmih66umazou.onion/inbox.comp.lang.ruby.unicorn.0
-
-Or Atom feeds:
+* https://yhbt.net/unicorn-public/
+* http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/unicorn-public/
+* imaps://yhbt.net/inbox.comp.lang.ruby.unicorn.0
+* imap://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.unicorn.0
+* nntps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
+* nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
 
-	https://yhbt.net/unicorn-public/new.atom
-	http://ou63pmih66umazou.onion/unicorn-public/new.atom
+Full Atom feeds:
+* https://yhbt.net/unicorn-public/new.atom
+* http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/unicorn-public/new.atom
 
-	The HTML archives at https://yhbt.net/unicorn-public/
-	also has links to per-thread Atom feeds and downloadable
-	mboxes.
+We only accept plain-text mail: mailto:unicorn-public@yhbt.net
diff --git a/README b/README
index 5fdd1e8c..22c27e84 100644
--- a/README
+++ b/README
@@ -137,13 +137,13 @@ information on the {mailing list}[mailto:unicorn-public@yhbt.net].
 The mailing list is archived at https://yhbt.net/unicorn-public/
 
 Read-only NNTP access is available at:
-nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
+nntps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
 nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
 
 Read-only IMAP access is also avaialble at:
-imaps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn.0 and
-imap://ou63pmih66umazou.onion/inbox.comp.lang.ruby.unicorn.0
-AUTH=ANONYMOUS mechanism is supported, as is any username+password
+imaps://yhbt.net/inbox.comp.lang.ruby.unicorn.0 and
+imap://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.unicorn.0
+The AUTH=ANONYMOUS mechanism is supported, as is any username+password
 combination.
 
 For the latest on unicorn releases, you may also finger us at

^ permalink raw reply related	[relevance 10%]

* [PATCH 3/6] HACKING: drop outdated information about pandoc
  @ 2021-10-01  3:09 16% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2021-10-01  3:09 UTC (permalink / raw)
  To: unicorn-public

It's been outdated since d9b5943af26d5df5 (doc: replace
pandoc-"Markdown" with real manpages, 2019-12-15)
---
 HACKING | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/HACKING b/HACKING
index 7c41eba..020209e 100644
--- a/HACKING
+++ b/HACKING
@@ -50,9 +50,6 @@ programming experience will come in handy (or be learned) here.
 
 === Documentation
 
-Due to the lack of RDoc-to-manpage converters we know about, we're
-writing manpages in Markdown and converting to troff/HTML with Pandoc.
-
 Please wrap documentation at 72 characters-per-line or less (long URLs
 are exempt) so it is comfortably readable from terminals.
 
@@ -102,10 +99,6 @@ don't email the git mailing list or maintainer with Unicorn patches :)
 
 == Building a Gem
 
-In order to build the gem, you must install the following components:
-
- * pandoc
-
 You can build the Unicorn gem with the following command:
 
   gmake gem

^ permalink raw reply related	[relevance 16%]

* [PATCH 2/2] build: revamp and avoid unnecessary rebuilds
  @ 2020-07-26  1:57  5% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2020-07-26  1:57 UTC (permalink / raw)
  To: unicorn-public

We can limit the amount of Ruby-version-specific code to
just the stuff in ext/* and bin/*, reducing I/O traffic
and FS + page cache footprint.

Furthermore, rely on GNU make behavior to copy all the necessary
files so we don't trigger unnecessary extconf.rb invocations
just by touching a .rb file in lib.
---
 GNUmakefile   | 160 ++++++++++++++++++++++++++++++++------------------
 t/GNUmakefile |  75 +----------------------
 2 files changed, 105 insertions(+), 130 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile
index eac3473f..d80e6080 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -10,6 +10,7 @@ RAGEL = ragel
 RSYNC = rsync
 OLDDOC = olddoc
 RDOC = rdoc
+INSTALL = install
 
 GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
 	@./GIT-VERSION-GEN
@@ -25,7 +26,38 @@ endif
 
 RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
 
-MYLIBS = $(RUBYLIB)
+# we should never package more than one ext to avoid DSO proliferation:
+# https://udrepper.livejournal.com/8790.html
+ext := $(firstword $(wildcard ext/*))
+
+ragel: $(ext)/unicorn_http.c
+
+rl_files := $(wildcard $(ext)/*.rl)
+ragel: $(ext)/unicorn_http.c
+$(ext)/unicorn_http.c: $(rl_files)
+	cd $(@D) && $(RAGEL) unicorn_http.rl -C $(RLFLAGS) -o $(@F)
+ext_pfx := test/$(RUBY_ENGINE)-$(RUBY_VERSION)
+tmp_bin := $(ext_pfx)/bin
+ext_h := $(wildcard $(ext)/*/*.h $(ext)/*.h)
+ext_src := $(sort $(wildcard $(ext)/*.c) $(ext_h) $(ext)/unicorn_http.c)
+ext_pfx_src := $(addprefix $(ext_pfx)/,$(ext_src))
+ext_dir := $(ext_pfx)/$(ext)
+$(ext)/extconf.rb: $(wildcard $(ext)/*.h)
+	@>>$@
+$(ext_dir) $(tmp_bin) man/man1 doc/man1 pkg t/trash:
+	@mkdir -p $@
+$(ext_pfx)/$(ext)/%: $(ext)/% | $(ext_dir)
+	$(INSTALL) -m 644 $< $@
+$(ext_pfx)/$(ext)/Makefile: $(ext)/extconf.rb $(ext_h) | $(ext_dir)
+	$(RM) -f $(@D)/*.o
+	cd $(@D) && $(RUBY) $(CURDIR)/$(ext)/extconf.rb $(EXTCONF_ARGS)
+ext_sfx := _ext.$(DLEXT)
+ext_dl := $(ext_pfx)/$(ext)/$(notdir $(ext)_ext.$(DLEXT))
+$(ext_dl): $(ext_src) $(ext_pfx_src) $(ext_pfx)/$(ext)/Makefile
+	$(MAKE) -C $(@D)
+lib := $(CURDIR)/lib:$(CURDIR)/$(ext_pfx)/$(ext)
+http build: $(ext_dl)
+$(ext_pfx)/$(ext)/unicorn_http.c: ext/unicorn_http/unicorn_http.c
 
 # dunno how to implement this as concisely in Ruby, and hell, I love awk
 awk_slow := awk '/def test_/{print FILENAME"--"$$2".n"}' 2>/dev/null
@@ -37,44 +69,21 @@ T := $(filter-out $(slow_tests), $(wildcard test/*/test*.rb))
 T_n := $(shell $(awk_slow) $(slow_tests))
 T_log := $(subst .rb,$(log_suffix),$(T))
 T_n_log := $(subst .n,$(log_suffix),$(T_n))
-test_prefix = $(CURDIR)/test/$(RUBY_ENGINE)-$(RUBY_VERSION)
 
-ext := ext/unicorn_http
-c_files := $(ext)/unicorn_http.c $(ext)/httpdate.c $(wildcard $(ext)/*.h)
-rl_files := $(wildcard $(ext)/*.rl)
 base_bins := unicorn unicorn_rails
 bins := $(addprefix bin/, $(base_bins))
 man1_rdoc := $(addsuffix _1, $(base_bins))
 man1_bins := $(addsuffix .1, $(base_bins))
 man1_paths := $(addprefix man/man1/, $(man1_bins))
-rb_files := $(bins) $(shell find lib ext -type f -name '*.rb')
-inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb
-
-ragel: $(ext)/unicorn_http.c
-$(ext)/unicorn_http.c: $(rl_files)
-	cd $(@D) && $(RAGEL) unicorn_http.rl -C $(RLFLAGS) -o $(@F)
-$(ext)/Makefile: $(ext)/extconf.rb $(c_files)
-	cd $(@D) && $(RUBY) extconf.rb
-$(ext)/unicorn_http.$(DLEXT): $(ext)/Makefile
-	$(MAKE) -C $(@D)
-http: $(ext)/unicorn_http.$(DLEXT)
+tmp_bins = $(addprefix $(tmp_bin)/, unicorn unicorn_rails)
+pid := $(shell echo $$PPID)
 
-# only used for tests
-http-install: $(ext)/unicorn_http.$(DLEXT)
-	install -m644 $< lib/
+$(tmp_bin)/%: bin/% | $(tmp_bin)
+	$(INSTALL) -m 755 $< $@.$(pid)
+	$(MRI) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $@.$(pid)
+	mv $@.$(pid) $@
 
-test-install: $(test_prefix)/.stamp
-$(test_prefix)/.stamp: $(inst_deps)
-	mkdir -p $(test_prefix)/.ccache
-	tar cf - $(inst_deps) GIT-VERSION-GEN | \
-	  (cd $(test_prefix) && tar xf -)
-	$(MAKE) -C $(test_prefix) clean
-	$(MAKE) -C $(test_prefix) http-install shebang RUBY="$(RUBY)"
-	> $@
-
-# this is only intended to be run within $(test_prefix)
-shebang: $(bins)
-	$(MRI) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
+bins: $(tmp_bins)
 
 t_log := $(T_log) $(T_n_log)
 test: $(T) $(T_n)
@@ -83,15 +92,54 @@ test: $(T) $(T_n)
 
 test-exec: $(wildcard test/exec/test_*.rb)
 test-unit: $(wildcard test/unit/test_*.rb)
-$(slow_tests): $(test_prefix)/.stamp
+$(slow_tests): $(ext_dl)
 	@$(MAKE) $(shell $(awk_slow) $@)
 
 # ensure we can require just the HTTP parser without the rest of unicorn
-test-require: $(ext)/unicorn_http.$(DLEXT)
-	$(RUBY) --disable-gems -I$(ext) -runicorn_http -e Unicorn
+test-require: $(ext_dl)
+	$(RUBY) --disable-gems -I$(ext_pfx)/$(ext) -runicorn_http -e Unicorn
+
+test_prereq := $(tmp_bins) $(ext_dl)
+
+SH_TEST_OPTS =
+ifdef V
+  ifeq ($(V),2)
+    SH_TEST_OPTS += --trace
+  else
+    SH_TEST_OPTS += --verbose
+  endif
+endif
 
-test-integration: $(test_prefix)/.stamp
-	$(MAKE) -C t
+# do we trust Ruby behavior to be stable? some tests are
+# (mostly) POSIX sh (not bash or ksh93, so no "set -o pipefail"
+# TRACER = strace -f -o $(t_pfx).strace -s 100000
+# TRACER = /usr/bin/time -o $(t_pfx).time
+t_pfx = trash/$@-$(RUBY_ENGINE)-$(RUBY_VERSION)
+T_sh = $(wildcard t/t[0-9][0-9][0-9][0-9]-*.sh)
+$(T_sh): export RUBY := $(RUBY)
+$(T_sh): export PATH := $(CURDIR)/$(tmp_bin):$(PATH)
+$(T_sh): export RUBYLIB := $(lib):$(RUBYLIB)
+$(T_sh): dep $(test_prereq) t/random_blob t/trash/.gitignore
+	cd t && $(TRACER) $(SHELL) $(SH_TEST_OPTS) $(@F) $(TEST_OPTS)
+
+t/trash/.gitignore : | t/trash
+	echo '*' >$@
+
+dependencies := socat curl
+deps := $(addprefix t/.dep+,$(dependencies))
+$(deps): dep_bin = $(lastword $(subst +, ,$@))
+$(deps):
+	@which $(dep_bin) > $@.$(pid) 2>/dev/null || :
+	@test -s $@.$(pid) || \
+	  { echo >&2 "E '$(dep_bin)' not found in PATH=$(PATH)"; exit 1; }
+	@mv $@.$(pid) $@
+dep: $(deps)
+
+t/random_blob:
+	dd if=/dev/urandom bs=1M count=30 of=$@.$(pid)
+	mv $@.$(pid) $@
+
+test-integration: $(T_sh)
 
 check: test-require test test-integration
 test-all: check
@@ -122,16 +170,16 @@ run_test = $(quiet_pre) \
 
 %.n: arg = $(subst .n,,$(subst --, -n ,$@))
 %.n: t = $(subst .n,$(log_suffix),$@)
-%.n: export PATH := $(test_prefix)/bin:$(PATH)
-%.n: export RUBYLIB := $(test_prefix)/lib:$(MYLIBS)
-%.n: $(test_prefix)/.stamp
+%.n: export PATH := $(CURDIR)/$(tmp_bin):$(PATH)
+%.n: export RUBYLIB := $(lib):$(RUBYLIB)
+%.n: $(test_prereq)
 	$(run_test)
 
 $(T): arg = $@
 $(T): t = $(subst .rb,$(log_suffix),$@)
-$(T): export PATH := $(test_prefix)/bin:$(PATH)
-$(T): export RUBYLIB := $(test_prefix)/lib:$(MYLIBS)
-$(T): $(test_prefix)/.stamp
+$(T): export PATH := $(CURDIR)/$(tmp_bin):$(PATH)
+$(T): export RUBYLIB := $(lib):$(RUBYLIB)
+$(T): $(test_prereq)
 	$(run_test)
 
 install: $(bins) $(ext)/unicorn_http.c
@@ -152,18 +200,16 @@ clean:
 	-$(MAKE) -C $(ext) clean
 	$(RM) $(ext)/Makefile
 	$(RM) $(setup_rb_files) $(t_log)
-	$(RM) -r $(test_prefix) man
-	$(RM) $(man1) $(html1)
+	$(RM) -r $(ext_pfx) man t/trash
+	$(RM) $(html1)
 
 man1 := $(addprefix Documentation/, unicorn.1 unicorn_rails.1)
 html1 := $(addsuffix .html, $(man1))
-man :
-	mkdir -p man/man1
-	install -m 644 $(man1) man/man1
+man : $(man1) | man/man1
+	$(INSTALL) -m 644 $(man1) man/man1
 
-html : $(html1)
-	mkdir -p doc/man1
-	install -m 644 $(html1) doc/man1
+html : $(html1) | doc/man1
+	$(INSTALL) -m 644 $(html1) doc/man1
 
 %.1.html: %.1
 	$(OLDDOC) man2html -o $@ ./$<
@@ -187,10 +233,10 @@ doc: .document $(ext)/unicorn_http.c man html .olddoc.yml $(PLACEHOLDERS)
 	$(OLDDOC) prepare
 	$(RDOC) -f dark216
 	$(OLDDOC) merge
-	install -m644 COPYING doc/COPYING
-	install -m644 NEWS.atom.xml doc/NEWS.atom.xml
-	install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
-	install -m644 $(man1_paths) doc/
+	$(INSTALL) -m 644 COPYING doc/COPYING
+	$(INSTALL) -m 644 NEWS.atom.xml doc/NEWS.atom.xml
+	$(INSTALL) -m 644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
+	$(INSTALL) -m 644 $(man1_paths) doc/
 	tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
 
 # publishes docs to https://yhbt.net/unicorn/
@@ -231,9 +277,8 @@ gem: $(pkggem)
 install-gem: $(pkggem)
 	gem install --local $(CURDIR)/$<
 
-$(pkggem): .manifest fix-perms
+$(pkggem): .manifest fix-perms | pkg
 	gem build $(rfpackage).gemspec
-	mkdir -p pkg
 	mv $(@F) $@
 
 $(pkgtgz): distdir = $(basename $@)
@@ -264,5 +309,4 @@ check-warnings:
 	  do $(RUBY) --disable-gems -d -W2 -c \
 	  $$i; done) | grep -v '^Syntax OK$$' || :
 
-.PHONY: .FORCE-GIT-VERSION-FILE doc $(T) $(slow_tests) man
-.PHONY: test-install
+.PHONY: .FORCE-GIT-VERSION-FILE doc $(T) $(slow_tests) man $(T_sh) clean
diff --git a/t/GNUmakefile b/t/GNUmakefile
index 5f5d9bc3..0ac9b9a3 100644
--- a/t/GNUmakefile
+++ b/t/GNUmakefile
@@ -1,74 +1,5 @@
-# we can run tests in parallel with GNU make
+# there used to be more, here, but we stopped relying on recursive make
 all::
+	$(MAKE) -C .. test-integration
 
-pid := $(shell echo $$PPID)
-
-RUBY = ruby
-RAKE = rake
--include ../local.mk
-ifeq ($(RUBY_VERSION),)
-  RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
-endif
-
-ifeq ($(RUBY_VERSION),)
-  $(error unable to detect RUBY_VERSION)
-endif
-
-RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
-export RUBY_ENGINE
-
-MYLIBS := $(RUBYLIB)
-
-T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
-
-all:: $(T)
-
-# can't rely on "set -o pipefail" since we don't require bash or ksh93 :<
-t_pfx = trash/$@-$(RUBY_ENGINE)-$(RUBY_VERSION)
-TEST_OPTS =
-# TRACER = strace -f -o $(t_pfx).strace -s 100000
-# TRACER = /usr/bin/time -o $(t_pfx).time
-
-ifdef V
-  ifeq ($(V),2)
-    TEST_OPTS += --trace
-  else
-    TEST_OPTS += --verbose
-  endif
-endif
-
-random_blob:
-	dd if=/dev/urandom bs=1M count=30 of=$@.$(pid)
-	mv $@.$(pid) $@
-
-$(T): random_blob
-
-dependencies := socat curl
-deps := $(addprefix .dep+,$(dependencies))
-$(deps): dep_bin = $(lastword $(subst +, ,$@))
-$(deps):
-	@which $(dep_bin) > $@.$(pid) 2>/dev/null || :
-	@test -s $@.$(pid) || \
-	  { echo >&2 "E '$(dep_bin)' not found in PATH=$(PATH)"; exit 1; }
-	@mv $@.$(pid) $@
-dep: $(deps)
-
-test_prefix := $(CURDIR)/../test/$(RUBY_ENGINE)-$(RUBY_VERSION)
-$(test_prefix)/.stamp:
-	$(MAKE) -C .. test-install
-
-$(T): export RUBY := $(RUBY)
-$(T): export RAKE := $(RAKE)
-$(T): export PATH := $(test_prefix)/bin:$(PATH)
-$(T): export RUBYLIB := $(test_prefix)/lib:$(MYLIBS)
-$(T): dep $(test_prefix)/.stamp trash/.gitignore
-	$(TRACER) $(SHELL) $(SH_TEST_OPTS) $@ $(TEST_OPTS)
-
-trash/.gitignore:
-	mkdir -p $(@D)
-	echo '*' > $@
-
-clean:
-	$(RM) -r trash/*
-
-.PHONY: $(T) clean
+.PHONY: all

^ permalink raw reply related	[relevance 5%]

* Re: [PATCH] Add early hints support
  2020-07-16 11:41  4%   ` Jean Boussier
@ 2020-07-16 12:16  0%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2020-07-16 12:16 UTC (permalink / raw)
  To: Jean Boussier; +Cc: unicorn-public

Jean Boussier <jean.boussier@shopify.com> wrote:
> Thanks for the very timely response.
> 
> > Since this RDoc ends up on the website, links to any relevant
> > Rails documentation and RFC 8297 would also be appropriate.
> > Otherwise non-Rails users like me might have no clue what
> > it's for.
> 
> I updated the documentation, let me know what you think of it.

It's fine, pushed for now.  Will release in a few days or a week
in case there's comments from others.

> > Are the method calls for .to_s necessary?
> 
> I don't think they are, I mostly took inspiration from the puma implementation
> that does all this defensive checks. Based on how that interface is
> used by Rails, we could assume both keys and values are strings already.
> 
> I simplified the implementation.

OK.

> > Eep, extra branch...  What's the performance impact for existing
> > users when not activated? (on Unix sockets).
> 
> Extremely small.

Alright, numbers would've been helpful but I'll take your word
for it.

If we get more branches in the main loop for other new features;
I wonder if generating the code for process_client dynamically
at initialize-time is worth it to avoid branches in the main
loop... (or if there's some way to hint MJIT to do that).

> > Perhaps bypassing the method and accessing the @early_hints ivar
> > directly can be slightly faster w/o method dispatch.  That
> > should also allow using attr_writer instead of attr_accessor,
> > I think.
> 
>  attr_reader is very optimized in MRI, it's barely slower than @early_hints.
> Also it ensure that it doesn't emit a warning in verbose mode if the variable
> isn't initialized.

Thanks again.

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] Add early hints support
  2020-07-16 10:50  6% ` Eric Wong
@ 2020-07-16 11:41  4%   ` Jean Boussier
  2020-07-16 12:16  0%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Jean Boussier @ 2020-07-16 11:41 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

Thanks for the very timely response.

> Since this RDoc ends up on the website, links to any relevant
> Rails documentation and RFC 8297 would also be appropriate.
> Otherwise non-Rails users like me might have no clue what
> it's for.

I updated the documentation, let me know what you think of it.

> Are the method calls for .to_s necessary?

I don't think they are, I mostly took inspiration from the puma implementation
that does all this defensive checks. Based on how that interface is
used by Rails, we could assume both keys and values are strings already.

I simplified the implementation.

> Eep, extra branch...  What's the performance impact for existing
> users when not activated? (on Unix sockets).

Extremely small.

> 
> Perhaps bypassing the method and accessing the @early_hints ivar
> directly can be slightly faster w/o method dispatch.  That
> should also allow using attr_writer instead of attr_accessor,
> I think.

 attr_reader is very optimized in MRI, it's barely slower than @early_hints.
Also it ensure that it doesn't emit a warning in verbose mode if the variable
isn't initialized.

From e0494e10de6549d1b513eef03e68bfa58a6b26ec Mon Sep 17 00:00:00 2001
From: Jean Boussier <jean.boussier@gmail.com>
Date: Thu, 16 Jul 2020 11:39:30 +0200
Subject: [PATCH] Add early hints support

While not part of the rack spec, this API is exposed
by both puma and falcon, and Rails use it when available.

The 103 Early Hints response code is specified in RFC 8297.
---
 lib/unicorn/configurator.rb |  9 +++++++++
 lib/unicorn/http_server.rb  | 31 +++++++++++++++++++++++++++++--
 test/unit/test_server.rb    | 30 ++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index c3a4f2d..b0606af 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -276,6 +276,15 @@ def default_middleware(bool)
     set_bool(:default_middleware, bool)
   end
 
+  # sets whether to enable the proposed early hints Rack API.
+  # If enabled, Rails 5.2+ will automatically send a 103 Early Hint
+  # for all the `javascript_include_tag` and `stylesheet_link_tag`
+  # in your response. See: https://api.rubyonrails.org/v5.2/classes/ActionDispatch/Request.html#method-i-send_early_hints
+  # See also https://tools.ietf.org/html/rfc8297
+  def early_hints(bool)
+    set_bool(:early_hints, bool)
+  end
+
   # sets listeners to the given +addresses+, replacing or augmenting the
   # current set.  This is for the global listener pool shared by all
   # worker processes.  For per-worker listeners, see the after_fork example
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 45a2e97..05dad99 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -15,7 +15,7 @@ class Unicorn::HttpServer
                 :before_fork, :after_fork, :before_exec,
                 :listener_opts, :preload_app,
                 :orig_app, :config, :ready_pipe, :user,
-                :default_middleware
+                :default_middleware, :early_hints
   attr_writer   :after_worker_exit, :after_worker_ready, :worker_exec
 
   attr_reader :pid, :logger
@@ -588,6 +588,25 @@ def handle_error(client, e)
   rescue
   end
 
+  def e103_response_write(client, headers)
+    response = if @request.response_start_sent
+      "103 Early Hints\r\n"
+    else
+      "HTTP/1.1 103 Early Hints\r\n"
+    end
+
+    headers.each_pair do |k, vs|
+      next if !vs || vs.empty?
+      values = vs.to_s.split("\n".freeze)
+      values.each do |v|
+        response << "#{k}: #{v}\r\n"
+      end
+    end
+    response << "\r\n".freeze
+    response << "HTTP/1.1 ".freeze if @request.response_start_sent
+    client.write(response)
+  end
+
   def e100_response_write(client, env)
     # We use String#freeze to avoid allocations under Ruby 2.1+
     # Not many users hit this code path, so it's better to reduce the
@@ -602,7 +621,15 @@ def e100_response_write(client, env)
   # once a client is accepted, it is processed in its entirety here
   # in 3 easy steps: read request, call app, write app response
   def process_client(client)
-    status, headers, body = @app.call(env = @request.read(client))
+    env = @request.read(client)
+
+    if early_hints
+      env["rack.early_hints"] = lambda do |headers|
+        e103_response_write(client, headers)
+      end
+    end
+
+    status, headers, body = @app.call(env)
 
     begin
       return if @request.hijacked?
diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb
index 8096955..d706243 100644
--- a/test/unit/test_server.rb
+++ b/test/unit/test_server.rb
@@ -23,6 +23,16 @@ def call(env)
   end
 end
 
+class TestEarlyHintsHandler
+  def call(env)
+    while env['rack.input'].read(4096)
+    end
+    env['rack.early_hints'].call(
+      "Link" => "</style.css>; rel=preload; as=style\n</script.js>; rel=preload"
+    )
+    [200, { 'Content-Type' => 'text/plain' }, ['hello!\n']]
+  end
+end
 
 class WebServerTest < Test::Unit::TestCase
 
@@ -84,6 +94,26 @@ def test_preload_app_config
     tmp.close!
   end
 
+  def test_early_hints
+    teardown
+    redirect_test_io do
+      @server = HttpServer.new(TestEarlyHintsHandler.new,
+                               :listeners => [ "127.0.0.1:#@port"],
+                               :early_hints => true)
+      @server.start
+    end
+
+    sock = TCPSocket.new('127.0.0.1', @port)
+    sock.syswrite("GET / HTTP/1.0\r\n\r\n")
+
+    responses = sock.sysread(4096)
+    assert_match %r{\AHTTP/1.[01] 103\b}, responses
+    assert_match %r{^Link: </style\.css>}, responses
+    assert_match %r{^Link: </script\.js>}, responses
+
+    assert_match %r{^HTTP/1.[01] 200\b}, responses
+  end
+
   def test_broken_app
     teardown
     app = lambda { |env| raise RuntimeError, "hello" }
-- 
2.26.2



^ permalink raw reply related	[relevance 4%]

* Re: [PATCH] Add early hints support
  @ 2020-07-16 10:50  6% ` Eric Wong
  2020-07-16 11:41  4%   ` Jean Boussier
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2020-07-16 10:50 UTC (permalink / raw)
  To: Jean Boussier; +Cc: unicorn-public

Jean Boussier <jean.boussier@shopify.com> wrote:
> While not part of the rack spec, this API is exposed
> by both puma and falcon, and Rails use it when available.
> 
> The 103 Early Hints response code is specified in RFC 8297.

Thanks, I can probably accept it with some minor tweaks.
Some comment below...

> ---
>  lib/unicorn/configurator.rb |  5 +++++
>  lib/unicorn/http_server.rb  | 33 +++++++++++++++++++++++++++++++--
>  test/unit/test_server.rb    | 30 ++++++++++++++++++++++++++++++
>  3 files changed, 66 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
> index c3a4f2d..43e91f4 100644
> --- a/lib/unicorn/configurator.rb
> +++ b/lib/unicorn/configurator.rb
> @@ -276,6 +276,11 @@ def default_middleware(bool)
>      set_bool(:default_middleware, bool)
>    end
>  
> +  # sets wether to enable rack's early hints API.

spelling: "whether".

Since it's not officially part of Rack, yet, perhaps something
like:

	Enable the proposed early hints Rack API.

I'm no grammar expert, so I also rephrased that sentence to
avoid the apostrophe.

Since this RDoc ends up on the website, links to any relevant
Rails documentation and RFC 8297 would also be appropriate.
Otherwise non-Rails users like me might have no clue what
it's for.

> +  def early_hints(bool)
> +    set_bool(:early_hints, bool)
> +  end
> +
>    # sets listeners to the given +addresses+, replacing or augmenting the
>    # current set.  This is for the global listener pool shared by all
>    # worker processes.  For per-worker listeners, see the after_fork example
> diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
> index 45a2e97..3e0c9a4 100644
> --- a/lib/unicorn/http_server.rb
> +++ b/lib/unicorn/http_server.rb
> @@ -15,7 +15,7 @@ class Unicorn::HttpServer
>                  :before_fork, :after_fork, :before_exec,
>                  :listener_opts, :preload_app,
>                  :orig_app, :config, :ready_pipe, :user,
> -                :default_middleware
> +                :default_middleware, :early_hints
>    attr_writer   :after_worker_exit, :after_worker_ready, :worker_exec
>  
>    attr_reader :pid, :logger
> @@ -588,6 +588,27 @@ def handle_error(client, e)
>    rescue
>    end
>  
> +  def e103_response_write(client, headers)
> +    response = if @request.response_start_sent
> +      "103 Early Hints\r\n"
> +    else
> +      "HTTP/1.1 103 Early Hints\r\n"
> +    end
> +
> +    headers.each_pair do |k, vs|
> +      if vs.respond_to?(:to_s) && !vs.to_s.empty?
> +        vs.to_s.split("\n".freeze).each do |v|

Are the method calls for .to_s necessary?  At least for regular
Rack responses, this bit from unicorn/http_response.rb seems to
handle odd apps which (improperly) give `nil' value:

          if value =~ /\n/
            # avoiding blank, key-only cookies with /\n+/
            value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
          else
            buf << "#{key}: #{value}\r\n"
          end

The split would never be attempted on nil since it wouldn't
match /\n/, and the /\n+/ was needed in the Rails 2.3.5 days:

https://public-inbox.org/rack-devel/20100105235845.GB3377@dcvr.yhbt.net/
https://yhbt.net/unicorn-public/52400de1c9e9437b5c9df899f273485f663bb5b5/s/

> +          response << "#{k}: #{v}\r\n"
> +        end
> +      else
> +        response << "#{k}: #{vs}\r\n"
> +      end
> +    end
> +    response << "\r\n".freeze
> +    response << "HTTP/1.1 ".freeze if @request.response_start_sent
> +    client.write(response)
> +  end
> +
>    def e100_response_write(client, env)
>      # We use String#freeze to avoid allocations under Ruby 2.1+
>      # Not many users hit this code path, so it's better to reduce the
> @@ -602,7 +623,15 @@ def e100_response_write(client, env)
>    # once a client is accepted, it is processed in its entirety here
>    # in 3 easy steps: read request, call app, write app response
>    def process_client(client)
> -    status, headers, body = @app.call(env = @request.read(client))
> +    env = @request.read(client)
> +
> +    if early_hints
> +      env["rack.early_hints"] = lambda do |headers|
> +        e103_response_write(client, headers)
> +      end
> +    end

Eep, extra branch...  What's the performance impact for existing
users when not activated? (on Unix sockets).

Perhaps bypassing the method and accessing the @early_hints ivar
directly can be slightly faster w/o method dispatch.  That
should also allow using attr_writer instead of attr_accessor,
I think.

Not sure how much people here care about minor performance
regressions, here...  I don't really upgrade or touch old
Rack apps, anymore; and I'm certainly never going to buy
a faster CPU.

> +    status, headers, body = @app.call(env)
>  
>      begin
>        return if @request.hijacked?

^ permalink raw reply	[relevance 6%]

* [ANN] unicorn 5.5.3 - Rack HTTP server for fast clients and *nix
@ 2020-01-31 20:48  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2020-01-31 20:48 UTC (permalink / raw)
  To: ruby-talk, unicorn-public

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

Disclaimer:

Due to its ability to tolerate crashes and isolate clients, unicorn
is unfortunately known to prolong the existence of bugs in applications
and libraries which run on top of it.

Consider this just an announcement to inform existing users of a
new version, not something to convince you to switch to something
that set the entire Ruby back decades in terms of concurrency.


.onion URLs below are available for Tor users and can reduce
our operating costs:

* https://yhbt.net/unicorn/
  http://unicorn.ou63pmih66umazou.onion/
* public list: unicorn-public@yhbt.net
* mail archives: https://yhbt.net/unicorn-public/
  http://ou63pmih66umazou.onion/unicorn-public/
* git clone https://yhbt.net/unicorn.git
  torsocks git clone http://ou63pmih66umazou.onion/unicorn.git
* https://yhbt.net/unicorn/NEWS.atom.xml
  http://unicorn.ou63pmih66umazou.onion/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
  nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.unicorn

Changes:

   unicorn 5.5.3

   Documentation updates to switch bogomips.org to yhbt.net since
   the .org TLD won't be affordable in the near future.

   There's also a few minor test cleanups.


80x24.org and public-inbox.org will be dead on expiry, too;
but I don't think I'll be around to care by then.

^ permalink raw reply	[relevance 6%]

* [PATCH] doc: s/bogomips.org/yhbt.net/g
  2020-01-14  7:46 23% [PATCH] doc: s/bogomips.org/yhbt.net/g Eric Wong
@ 2020-01-14  7:46 29% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2020-01-14  7:46 UTC (permalink / raw)
  To: unicorn-public

bogomips.org is due to expire, soon, and I'm not willing to pay
extortionist fees to Ethos Capital/PIR/ICANN to keep a .org.  So
it's at yhbt.net, for now, but it will change again to
whatever's affordable...  Identity is overrated.

Tor users can use .onions and kick ICANN to the curb:

	torsocks w3m http://unicorn.ou63pmih66umazou.onion/
	torsocks git clone http://ou63pmih66umazou.onion/unicorn.git/
	torsocks w3m http://ou63pmih66umazou.onion/unicorn-public/

While we're at it, `s/news.gmane.org/news.gmane.io/g', too.
(but I suspect that'll need to be resynched since our mail
"List-Id:" header is changing).
---
 .olddoc.yml                      | 19 ++++++++++++-------
 Documentation/unicorn.1          |  8 ++++----
 Documentation/unicorn_rails.1    |  8 ++++----
 FAQ                              |  2 +-
 GNUmakefile                      |  4 ++--
 HACKING                          |  2 +-
 ISSUES                           | 24 ++++++++++++------------
 KNOWN_ISSUES                     |  4 ++--
 Links                            | 10 +++++-----
 README                           | 12 ++++++------
 SIGNALS                          |  2 +-
 Sandbox                          |  4 ++--
 archive/slrnpull.conf            |  2 +-
 examples/big_app_gc.rb           |  2 +-
 examples/logrotate.conf          |  4 ++--
 examples/nginx.conf              |  2 +-
 examples/unicorn.conf.minimal.rb |  4 ++--
 examples/unicorn.conf.rb         |  4 ++--
 ext/unicorn_http/unicorn_http.rl |  2 +-
 lib/unicorn.rb                   |  2 +-
 lib/unicorn/configurator.rb      |  6 +++---
 lib/unicorn/http_server.rb       |  2 +-
 lib/unicorn/oob_gc.rb            |  4 ++--
 unicorn.gemspec                  |  4 ++--
 24 files changed, 71 insertions(+), 66 deletions(-)

diff --git a/.olddoc.yml b/.olddoc.yml
index d2d340f..0609bdb 100644
--- a/.olddoc.yml
+++ b/.olddoc.yml
@@ -1,8 +1,9 @@
 ---
-cgit_url: https://bogomips.org/unicorn.git
-git_url: https://bogomips.org/unicorn.git
-rdoc_url: https://bogomips.org/unicorn/
-ml_url: https://bogomips.org/unicorn-public/
+cgit_url: https://yhbt.net/unicorn.git
+rdoc_url: https://yhbt.net/unicorn/
+ml_url:
+- https://yhbt.net/unicorn-public/
+- http://ou63pmih66umazou.onion/unicorn-public/
 merge_html:
   unicorn_1: Documentation/unicorn.1.html
   unicorn_rails_1: Documentation/unicorn_rails.1.html
@@ -11,7 +12,11 @@ noindex:
 - LATEST
 - TODO
 - unicorn_rails_1
-public_email: unicorn-public@bogomips.org
+public_email: unicorn-public@yhbt.net
 nntp_url:
-  - nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-  - nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+- nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
+- nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.unicorn
+- nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
+source_code:
+- git clone https://yhbt.net/unicorn.git
+- torsocks git clone http://ou63pmih66umazou.onion/unicorn.git
diff --git a/Documentation/unicorn.1 b/Documentation/unicorn.1
index 3f8cb96..d76d40f 100644
--- a/Documentation/unicorn.1
+++ b/Documentation/unicorn.1
@@ -154,7 +154,7 @@ TTIN \- increment the number of worker processes by one
 .IP \[bu] 2
 TTOU \- decrement the number of worker processes by one
 .PP
-See the SIGNALS (https://bogomips.org/unicorn/SIGNALS.html) document for
+See the SIGNALS (https://yhbt.net/unicorn/SIGNALS.html) document for
 full description of all signals used by Unicorn.
 .SH RACK ENVIRONMENT
 .PP
@@ -204,11 +204,11 @@ the unicorn config file.
 \f[I]Rack::Builder\f[] ri/RDoc
 .IP \[bu] 2
 \f[I]Unicorn::Configurator\f[] ri/RDoc
-.UR https://bogomips.org/unicorn/Unicorn/Configurator.html
+.UR https://yhbt.net/unicorn/Unicorn/Configurator.html
 .UE
 .IP \[bu] 2
 unicorn RDoc
-.UR https://bogomips.org/unicorn/
+.UR https://yhbt.net/unicorn/
 .UE
 .IP \[bu] 2
 Rack RDoc
@@ -219,4 +219,4 @@ Rackup HowTo
 .UR https://github.com/rack/rack/wiki/(tutorial)-rackup-howto
 .UE
 .SH AUTHORS
-The Unicorn Community <unicorn-public@bogomips.org>.
+The Unicorn Community <unicorn-public@yhbt.net>.
diff --git a/Documentation/unicorn_rails.1 b/Documentation/unicorn_rails.1
index 71c80be..fec0a2a 100644
--- a/Documentation/unicorn_rails.1
+++ b/Documentation/unicorn_rails.1
@@ -180,7 +180,7 @@ TTIN \- increment the number of worker processes by one
 .IP \[bu] 2
 TTOU \- decrement the number of worker processes by one
 .PP
-See the SIGNALS (https://bogomips.org/unicorn/SIGNALS.html) document for
+See the SIGNALS (https://yhbt.net/unicorn/SIGNALS.html) document for
 full description of all signals used by Unicorn.
 .SH SEE ALSO
 .IP \[bu] 2
@@ -189,11 +189,11 @@ unicorn(1)
 \f[I]Rack::Builder\f[] ri/RDoc
 .IP \[bu] 2
 \f[I]Unicorn::Configurator\f[] ri/RDoc
-.UR https://bogomips.org/unicorn/Unicorn/Configurator.html
+.UR https://yhbt.net/unicorn/Unicorn/Configurator.html
 .UE
 .IP \[bu] 2
 unicorn RDoc
-.UR https://bogomips.org/unicorn/
+.UR https://yhbt.net/unicorn/
 .UE
 .IP \[bu] 2
 Rack RDoc
@@ -204,4 +204,4 @@ Rackup HowTo
 .UR https://github.com/rack/rack/wiki/(tutorial)-rackup-howto
 .UE
 .SH AUTHORS
-The Unicorn Community <unicorn-public@bogomips.org>.
+The Unicorn Community <unicorn-public@yhbt.net>.
diff --git a/FAQ b/FAQ
index 4ae2034..018ca92 100644
--- a/FAQ
+++ b/FAQ
@@ -7,7 +7,7 @@ drained entirely by the application.  This may happen when request
 bodies are gzipped, as unicorn reads request body data lazily to avoid
 overhead from bad requests.
 
-Ref: https://bogomips.org/unicorn-public/FC91211E-FD32-432C-92FC-0318714C2170@zendesk.com/
+Ref: https://yhbt.net/unicorn-public/FC91211E-FD32-432C-92FC-0318714C2170@zendesk.com/
 
 === Why aren't my Rails log files rotated when I use SIGUSR1?
 
diff --git a/GNUmakefile b/GNUmakefile
index 94c46ee..eac3473 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -193,13 +193,13 @@ doc: .document $(ext)/unicorn_http.c man html .olddoc.yml $(PLACEHOLDERS)
 	install -m644 $(man1_paths) doc/
 	tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
 
-# publishes docs to https://bogomips.org/unicorn/
+# publishes docs to https://yhbt.net/unicorn/
 publish_doc:
 	-git set-file-times
 	$(MAKE) doc
 	$(MAKE) doc_gz
 	chmod 644 $$(find doc -type f)
-	$(RSYNC) -av doc/ bogomips.org:/srv/bogomips/unicorn/
+	$(RSYNC) -av doc/ yhbt.net:/srv/yhbt/unicorn/
 	git ls-files | xargs touch
 
 # Create gzip variants of the same timestamp as the original so nginx
diff --git a/HACKING b/HACKING
index be1bb85..976bf92 100644
--- a/HACKING
+++ b/HACKING
@@ -57,7 +57,7 @@ Please wrap documentation at 72 characters-per-line or less (long URLs
 are exempt) so it is comfortably readable from terminals.
 
 When referencing mailing list posts, use
-<tt>https://bogomips.org/unicorn-public/$MESSAGE_ID/</tt> if possible
+<tt>https://yhbt.net/unicorn-public/$MESSAGE_ID/</tt> if possible
 since the Message-ID remains searchable even if a particular site
 becomes unavailable.
 
diff --git a/ISSUES b/ISSUES
index 473da2f..d11dc56 100644
--- a/ISSUES
+++ b/ISSUES
@@ -1,9 +1,9 @@
 = Issues
 
-mailto:unicorn-public@bogomips.org is the best place to report bugs,
+mailto:unicorn-public@yhbt.net is the best place to report bugs,
 submit patches and/or obtain support after you have searched the
-{email archives}[https://bogomips.org/unicorn-public/] and
-{documentation}[https://bogomips.org/unicorn/].
+{email archives}[https://yhbt.net/unicorn-public/] and
+{documentation}[https://yhbt.net/unicorn/].
 
 * No subscription will ever be required to email us
 * Cc: all participants in a thread or commit, as subscription is optional
@@ -12,12 +12,12 @@ submit patches and/or obtain support after you have searched the
 * Do not send HTML mail or images,
   they hurt reader privacy and will be flagged as spam
 * Anonymous and pseudonymous messages will ALWAYS be welcome
-* The email submission port (587) is enabled on the bogomips.org MX:
-  https://bogomips.org/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
+* The email submission port (587) is enabled on the yhbt.net MX:
+  https://yhbt.net/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
 
 We will never have a centralized or formal bug tracker.  Instead we
 can interoperate with any bug tracker which can Cc: us plain-text to
-mailto:unicorn-public@bogomips.org   This includes the Debian BTS
+mailto:unicorn-public@yhbt.net   This includes the Debian BTS
 at https://bugs.debian.org/unicorn and possibly others.
 
 If your issue is of a sensitive nature or you're just shy in public,
@@ -73,10 +73,10 @@ document distributed with git) on guidelines for patch submission.
 
 == Contact Info
 
-* public: mailto:unicorn-public@bogomips.org
-* nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+* public: mailto:unicorn-public@yhbt.net
+* nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
 * nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-* https://bogomips.org/unicorn-public/
+* https://yhbt.net/unicorn-public/
 * http://ou63pmih66umazou.onion/unicorn-public/
 
 Mailing list subscription is optional, so Cc: all participants.
@@ -84,13 +84,13 @@ Mailing list subscription is optional, so Cc: all participants.
 You can follow along via NNTP (read-only):
 
 	nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-	nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+	nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
 
 Or Atom feeds:
 
-	https://bogomips.org/unicorn-public/new.atom
+	https://yhbt.net/unicorn-public/new.atom
 	http://ou63pmih66umazou.onion/unicorn-public/new.atom
 
-	The HTML archives at https://bogomips.org/unicorn-public/
+	The HTML archives at https://yhbt.net/unicorn-public/
 	also has links to per-thread Atom feeds and downloadable
 	mboxes.
diff --git a/KNOWN_ISSUES b/KNOWN_ISSUES
index ebd4822..0017f20 100644
--- a/KNOWN_ISSUES
+++ b/KNOWN_ISSUES
@@ -9,7 +9,7 @@ acceptable solution.  Those issues are documented here.
   handlers.
 
 * Issues with FreeBSD jails can be worked around as documented by Tatsuya Ono:
-  https://bogomips.org/unicorn-public/CAHBuKRj09FdxAgzsefJWotexw-7JYZGJMtgUp_dhjPz9VbKD6Q@mail.gmail.com/
+  https://yhbt.net/unicorn-public/CAHBuKRj09FdxAgzsefJWotexw-7JYZGJMtgUp_dhjPz9VbKD6Q@mail.gmail.com/
 
 * PRNGs (pseudo-random number generators) loaded before forking
   (e.g. "preload_app true") may need to have their internal state
@@ -60,7 +60,7 @@ acceptable solution.  Those issues are documented here.
   application to use Rails 2.3.2 and you have no other choice, then
   you may edit your unicorn gemspec and remove the Rack dependency.
 
-  ref: https://bogomips.org/unicorn-public/20091014221552.GA30624@dcvr.yhbt.net/
+  ref: https://yhbt.net/unicorn-public/20091014221552.GA30624@dcvr.yhbt.net/
   Note: the workaround described in the article above only made
   the issue more subtle and we didn't notice them immediately.
 
diff --git a/Links b/Links
index 10551a6..f81142d 100644
--- a/Links
+++ b/Links
@@ -2,7 +2,7 @@
 
 If you're interested in unicorn, you may be interested in some of the projects
 listed below.  If you have any links to add/change/remove, please tell us at
-mailto:unicorn-public@bogomips.org!
+mailto:unicorn-public@yhbt.net!
 
 == Disclaimer
 
@@ -23,10 +23,10 @@ or services behind them.
 * {golden_brindle}[https://github.com/simonoff/golden_brindle] - tool to
   manage multiple unicorn instances/applications on a single server
 
-* {raindrops}[https://bogomips.org/raindrops/] - real-time stats for
+* {raindrops}[https://yhbt.net/raindrops/] - real-time stats for
   preforking Rack servers
 
-* {UnXF}[https://bogomips.org/unxf/]  Un-X-Forward* the Rack environment,
+* {UnXF}[https://yhbt.net/unxf/]  Un-X-Forward* the Rack environment,
   useful since unicorn is designed to be deployed behind a reverse proxy.
 
 === unicorn is written to work with
@@ -52,7 +52,7 @@ or services behind them.
 * {Mongrel}[https://rubygems.org/gems/mongrel] - the awesome webserver
   unicorn is based on.  A historical archive of the mongrel dev list
   featuring early discussions of unicorn is available at:
-  https://bogomips.org/mongrel-devel/
+  https://yhbt.net/mongrel-devel/
 
-* {david}[https://bogomips.org/david.git] - a tool to explain why you need
+* {david}[https://yhbt.net/david.git] - a tool to explain why you need
   nginx in front of unicorn
diff --git a/README b/README
index 89467fc..0e95f48 100644
--- a/README
+++ b/README
@@ -80,12 +80,12 @@ You may install it via RubyGems on RubyGems.org:
 You can get the latest source via git from the following locations
 (these versions may not be stable):
 
-  https://bogomips.org/unicorn.git
+  https://yhbt.net/unicorn.git
   https://repo.or.cz/unicorn.git (mirror)
 
 You may browse the code from the web:
 
-* https://bogomips.org/unicorn.git
+* https://yhbt.net/unicorn.git
 * https://repo.or.cz/w/unicorn.git (gitweb)
 
 See the HACKING guide on how to contribute and build prerelease gems
@@ -133,13 +133,13 @@ and libraries which run on top of it.
 
 All feedback (bug reports, user/development dicussion, patches, pull
 requests) go to the mailing list/newsgroup.  See the ISSUES document for
-information on the {mailing list}[mailto:unicorn-public@bogomips.org].
+information on the {mailing list}[mailto:unicorn-public@yhbt.net].
 
-The mailing list is archived at https://bogomips.org/unicorn-public/
+The mailing list is archived at https://yhbt.net/unicorn-public/
 Read-only NNTP access is available at:
 nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
-nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
 
 For the latest on unicorn releases, you may also finger us at
-unicorn@bogomips.org or check our NEWS page (and subscribe to our Atom
+unicorn@yhbt.net or check our NEWS page (and subscribe to our Atom
 feed).
diff --git a/SIGNALS b/SIGNALS
index 1af851d..7321f2b 100644
--- a/SIGNALS
+++ b/SIGNALS
@@ -8,7 +8,7 @@ should be possible to easily share process management scripts between
 Unicorn and nginx.
 
 One example init script is distributed with unicorn:
-https://bogomips.org/unicorn/examples/init.sh
+https://yhbt.net/unicorn/examples/init.sh
 
 === Master Process
 
diff --git a/Sandbox b/Sandbox
index d0f915e..651e5cd 100644
--- a/Sandbox
+++ b/Sandbox
@@ -34,7 +34,7 @@ is the primary issue with sandboxing tools such as Bundler and Isolate.
 If you're bundling unicorn, use "bundle exec unicorn" (or "bundle exec
 unicorn_rails") to start unicorn with the correct environment variables
 
-ref: https://bogomips.org/unicorn-public/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us/
+ref: https://yhbt.net/unicorn-public/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us/
 
 Otherwise (if you choose to not sandbox your unicorn installation), we
 expect the tips for Isolate (below) apply, too.
@@ -44,7 +44,7 @@ expect the tips for Isolate (below) apply, too.
 This is no longer be an issue as of bundler 0.9.17
 
 ref:
-https://bogomips.org/unicorn-public/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com/
+https://yhbt.net/unicorn-public/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com/
 
 === BUNDLE_GEMFILE for Capistrano users
 
diff --git a/archive/slrnpull.conf b/archive/slrnpull.conf
index fcfcafe..fd04f97 100644
--- a/archive/slrnpull.conf
+++ b/archive/slrnpull.conf
@@ -1,4 +1,4 @@
 # group_name                         max        expire     headers_only
 gmane.comp.lang.ruby.unicorn.general 1000000000 1000000000 0
 
-# usage: slrnpull -d $PWD -h news.gmane.org --no-post
+# usage: slrnpull -d $PWD -h news.gmane.io --no-post
diff --git a/examples/big_app_gc.rb b/examples/big_app_gc.rb
index 9d05719..c1bae10 100644
--- a/examples/big_app_gc.rb
+++ b/examples/big_app_gc.rb
@@ -1,2 +1,2 @@
-# see {Unicorn::OobGC}[https://bogomips.org/unicorn/Unicorn/OobGC.html]
+# see {Unicorn::OobGC}[https://yhbt.net/unicorn/Unicorn/OobGC.html]
 # Unicorn::OobGC was broken in Unicorn v3.3.1 - v3.6.1 and fixed in v3.6.2
diff --git a/examples/logrotate.conf b/examples/logrotate.conf
index 77a01b5..c3aa40d 100644
--- a/examples/logrotate.conf
+++ b/examples/logrotate.conf
@@ -5,7 +5,7 @@
 #    https://linux.die.net/man/8/logrotate
 #
 # public logrotate-related discussion in our archives:
-#    https://bogomips.org/unicorn-public/?q=logrotate
+#    https://yhbt.net/unicorn-public/?q=logrotate
 
 # Modify the following glob to match the logfiles your app writes to:
 /var/log/unicorn_app/*.log {
@@ -33,7 +33,7 @@
 		systemctl kill -s SIGUSR1 unicorn@2.service
 
 		# Examples for other process management systems appreciated
-		# Mail us at unicorn-public@bogomips.org
+		# Mail us at unicorn-public@yhbt.net
 		# (see above for archives)
 
 		# If you use a pid file and assuming your pid file
diff --git a/examples/nginx.conf b/examples/nginx.conf
index b6b69c1..c5026f9 100644
--- a/examples/nginx.conf
+++ b/examples/nginx.conf
@@ -113,7 +113,7 @@ http {
     # try_files directive appeared in in nginx 0.7.27 and has stabilized
     # over time.  Older versions of nginx (e.g. 0.6.x) requires
     # "if (!-f $request_filename)" which was less efficient:
-    # https://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
+    # https://yhbt.net/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
     try_files $uri/index.html $uri.html $uri @app;
 
     location @app {
diff --git a/examples/unicorn.conf.minimal.rb b/examples/unicorn.conf.minimal.rb
index 2d1bf0a..46fd634 100644
--- a/examples/unicorn.conf.minimal.rb
+++ b/examples/unicorn.conf.minimal.rb
@@ -1,9 +1,9 @@
 # Minimal sample configuration file for Unicorn (not Rack) when used
 # with daemonization (unicorn -D) started in your working directory.
 #
-# See https://bogomips.org/unicorn/Unicorn/Configurator.html for complete
+# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
 # documentation.
-# See also https://bogomips.org/unicorn/examples/unicorn.conf.rb for
+# See also https://yhbt.net/unicorn/examples/unicorn.conf.rb for
 # a more verbose configuration using more features.
 
 listen 2007 # by default Unicorn listens on port 8080
diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index d2897ef..d90bdc4 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -2,10 +2,10 @@
 #
 # This configuration file documents many features of Unicorn
 # that may not be needed for some applications. See
-# https://bogomips.org/unicorn/examples/unicorn.conf.minimal.rb
+# https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
 # for a much simpler configuration file.
 #
-# See https://bogomips.org/unicorn/Unicorn/Configurator.html for complete
+# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
 # documentation.
 
 # Use at least one worker per core if you're on a dedicated server,
diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
index 8ef23bc..dfe3a63 100644
--- a/ext/unicorn_http/unicorn_http.rl
+++ b/ext/unicorn_http/unicorn_http.rl
@@ -487,7 +487,7 @@ static void set_url_scheme(VALUE env, VALUE *server_port)
      * and X-Forwarded-Proto handling from this parser?  We've had it
      * forever and nobody has said anything against it, either.
      * Anyways, please send comments to our public mailing list:
-     * unicorn-public@bogomips.org (no HTML mail, no subscription necessary)
+     * unicorn-public@yhbt.net (no HTML mail, no subscription necessary)
      */
     scheme = rb_hash_aref(env, g_http_x_forwarded_ssl);
     if (!NIL_P(scheme) && STR_CSTR_EQ(scheme, "on")) {
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index dd5dff4..d5991fe 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -96,7 +96,7 @@ def self.builder(ru, op)
 
   # returns an array of strings representing TCP listen socket addresses
   # and Unix domain socket paths.  This is useful for use with
-  # Raindrops::Middleware under Linux: https://bogomips.org/raindrops/
+  # Raindrops::Middleware under Linux: https://yhbt.net/raindrops/
   def self.listener_names
     Unicorn::HttpServer::LISTENERS.map do |io|
       Unicorn::SocketHelper.sock_name(io)
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index e8b76f5..c3a4f2d 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -3,11 +3,11 @@
 
 # Implements a simple DSL for configuring a unicorn server.
 #
-# See https://bogomips.org/unicorn/examples/unicorn.conf.rb and
-# https://bogomips.org/unicorn/examples/unicorn.conf.minimal.rb
+# See https://yhbt.net/unicorn/examples/unicorn.conf.rb and
+# https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
 # example configuration files.  An example config file for use with
 # nginx is also available at
-# https://bogomips.org/unicorn/examples/nginx.conf
+# https://yhbt.net/unicorn/examples/nginx.conf
 #
 # See the link:/TUNING.html document for more information on tuning unicorn.
 class Unicorn::Configurator
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 5334fa0..a52931a 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -6,7 +6,7 @@
 # forked worker children.
 #
 # Users do not need to know the internals of this class, but reading the
-# {source}[https://bogomips.org/unicorn.git/tree/lib/unicorn/http_server.rb]
+# {source}[https://yhbt.net/unicorn.git/tree/lib/unicorn/http_server.rb]
 # is education for programmers wishing to learn how unicorn works.
 # See Unicorn::Configurator for information on how to configure unicorn.
 class Unicorn::HttpServer
diff --git a/lib/unicorn/oob_gc.rb b/lib/unicorn/oob_gc.rb
index c4741a0..3b2f488 100644
--- a/lib/unicorn/oob_gc.rb
+++ b/lib/unicorn/oob_gc.rb
@@ -43,8 +43,8 @@
 #     use Unicorn::OobGC, 2, %r{\A/(?:expensive/foo|more_expensive/foo)}
 #
 # Feedback from users of early implementations of this module:
-# * https://bogomips.org/unicorn-public/0BFC98E9-072B-47EE-9A70-05478C20141B@lukemelia.com/
-# * https://bogomips.org/unicorn-public/AANLkTilUbgdyDv9W1bi-s_W6kq9sOhWfmuYkKLoKGOLj@mail.gmail.com/
+# * https://yhbt.net/unicorn-public/0BFC98E9-072B-47EE-9A70-05478C20141B@lukemelia.com/
+# * https://yhbt.net/unicorn-public/AANLkTilUbgdyDv9W1bi-s_W6kq9sOhWfmuYkKLoKGOLj@mail.gmail.com/
 
 module Unicorn::OobGC
 
diff --git a/unicorn.gemspec b/unicorn.gemspec
index ceea831..a189f8d 100644
--- a/unicorn.gemspec
+++ b/unicorn.gemspec
@@ -15,14 +15,14 @@
   s.authors = ['unicorn hackers']
   s.summary = 'Rack HTTP server for fast clients and Unix'
   s.description = File.read('README').split("\n\n")[1]
-  s.email = %q{unicorn-public@bogomips.org}
+  s.email = %q{unicorn-public@yhbt.net}
   s.executables = %w(unicorn unicorn_rails)
   s.extensions = %w(ext/unicorn_http/extconf.rb)
   s.extra_rdoc_files = IO.readlines('.document').map!(&:chomp!).keep_if do |f|
     File.exist?(f)
   end
   s.files = manifest
-  s.homepage = 'https://bogomips.org/unicorn/'
+  s.homepage = 'https://yhbt.net/unicorn/'
   s.test_files = test_files
 
   # technically we need ">= 1.9.3", too, but avoid the array here since

^ permalink raw reply related	[relevance 29%]

* [PATCH] doc: s/bogomips.org/yhbt.net/g
@ 2020-01-14  7:46 23% Eric Wong
  2020-01-14  7:46 29% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2020-01-14  7:46 UTC (permalink / raw)
  To: unicorn-public

bogomips.org is due to expire, soon, and I'm not willing to pay
extortionist fees to Ethos Capital/PIR/ICANN to keep a .org.  So
it's at yhbt.net, for now, but it will change again to
whatever's affordable...  Identity is overrated.

Tor users can use .onions and kick ICANN to the curb:

	torsocks w3m http://unicorn.ou63pmih66umazou.onion/
	torsocks git clone http://ou63pmih66umazou.onion/unicorn.git/
	torsocks w3m http://ou63pmih66umazou.onion/unicorn-public/

While we're at it, `s/news.gmane.org/news.gmane.io/g', too.
(but I suspect that'll need to be resynched since our mail
"List-Id:" header is changing).
---
 .olddoc.yml                      | 19 ++++++++++++-------
 Documentation/unicorn.1          |  8 ++++----
 Documentation/unicorn_rails.1    |  8 ++++----
 FAQ                              |  2 +-
 GNUmakefile                      |  4 ++--
 HACKING                          |  2 +-
 ISSUES                           | 24 ++++++++++++------------
 KNOWN_ISSUES                     |  4 ++--
 Links                            | 10 +++++-----
 README                           | 12 ++++++------
 SIGNALS                          |  2 +-
 Sandbox                          |  4 ++--
 archive/slrnpull.conf            |  2 +-
 examples/big_app_gc.rb           |  2 +-
 examples/logrotate.conf          |  4 ++--
 examples/nginx.conf              |  2 +-
 examples/unicorn.conf.minimal.rb |  4 ++--
 examples/unicorn.conf.rb         |  4 ++--
 ext/unicorn_http/unicorn_http.rl |  2 +-
 lib/unicorn.rb                   |  2 +-
 lib/unicorn/configurator.rb      |  6 +++---
 lib/unicorn/http_server.rb       |  2 +-
 lib/unicorn/oob_gc.rb            |  4 ++--
 unicorn.gemspec                  |  4 ++--
 24 files changed, 71 insertions(+), 66 deletions(-)

diff --git a/.olddoc.yml b/.olddoc.yml
index d2d340f..0609bdb 100644
--- a/.olddoc.yml
+++ b/.olddoc.yml
@@ -2,4 +2,5 @@
-cgit_url: https://bogomips.org/unicorn.git
-git_url: https://bogomips.org/unicorn.git
-rdoc_url: https://bogomips.org/unicorn/
-ml_url: https://bogomips.org/unicorn-public/
+cgit_url: https://yhbt.net/unicorn.git
+rdoc_url: https://yhbt.net/unicorn/
+ml_url:
+- https://yhbt.net/unicorn-public/
+- http://ou63pmih66umazou.onion/unicorn-public/
@@ -14 +15 @@ noindex:
-public_email: unicorn-public@bogomips.org
+public_email: unicorn-public@yhbt.net
@@ -16,2 +17,6 @@ nntp_url:
-  - nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-  - nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+- nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
+- nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.unicorn
+- nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
+source_code:
+- git clone https://yhbt.net/unicorn.git
+- torsocks git clone http://ou63pmih66umazou.onion/unicorn.git
diff --git a/Documentation/unicorn.1 b/Documentation/unicorn.1
index 3f8cb96..d76d40f 100644
--- a/Documentation/unicorn.1
+++ b/Documentation/unicorn.1
@@ -157 +157 @@ TTOU \- decrement the number of worker processes by one
-See the SIGNALS (https://bogomips.org/unicorn/SIGNALS.html) document for
+See the SIGNALS (https://yhbt.net/unicorn/SIGNALS.html) document for
@@ -207 +207 @@ the unicorn config file.
-.UR https://bogomips.org/unicorn/Unicorn/Configurator.html
+.UR https://yhbt.net/unicorn/Unicorn/Configurator.html
@@ -211 +211 @@ unicorn RDoc
-.UR https://bogomips.org/unicorn/
+.UR https://yhbt.net/unicorn/
@@ -222 +222 @@ Rackup HowTo
-The Unicorn Community <unicorn-public@bogomips.org>.
+The Unicorn Community <unicorn-public@yhbt.net>.
diff --git a/Documentation/unicorn_rails.1 b/Documentation/unicorn_rails.1
index 71c80be..fec0a2a 100644
--- a/Documentation/unicorn_rails.1
+++ b/Documentation/unicorn_rails.1
@@ -183 +183 @@ TTOU \- decrement the number of worker processes by one
-See the SIGNALS (https://bogomips.org/unicorn/SIGNALS.html) document for
+See the SIGNALS (https://yhbt.net/unicorn/SIGNALS.html) document for
@@ -192 +192 @@ unicorn(1)
-.UR https://bogomips.org/unicorn/Unicorn/Configurator.html
+.UR https://yhbt.net/unicorn/Unicorn/Configurator.html
@@ -196 +196 @@ unicorn RDoc
-.UR https://bogomips.org/unicorn/
+.UR https://yhbt.net/unicorn/
@@ -207 +207 @@ Rackup HowTo
-The Unicorn Community <unicorn-public@bogomips.org>.
+The Unicorn Community <unicorn-public@yhbt.net>.
diff --git a/FAQ b/FAQ
index 4ae2034..018ca92 100644
--- a/FAQ
+++ b/FAQ
@@ -10 +10 @@ overhead from bad requests.
-Ref: https://bogomips.org/unicorn-public/FC91211E-FD32-432C-92FC-0318714C2170@zendesk.com/
+Ref: https://yhbt.net/unicorn-public/FC91211E-FD32-432C-92FC-0318714C2170@zendesk.com/
diff --git a/GNUmakefile b/GNUmakefile
index 94c46ee..eac3473 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -196 +196 @@ doc: .document $(ext)/unicorn_http.c man html .olddoc.yml $(PLACEHOLDERS)
-# publishes docs to https://bogomips.org/unicorn/
+# publishes docs to https://yhbt.net/unicorn/
@@ -202 +202 @@ publish_doc:
-	$(RSYNC) -av doc/ bogomips.org:/srv/bogomips/unicorn/
+	$(RSYNC) -av doc/ yhbt.net:/srv/yhbt/unicorn/
diff --git a/HACKING b/HACKING
index be1bb85..976bf92 100644
--- a/HACKING
+++ b/HACKING
@@ -60 +60 @@ When referencing mailing list posts, use
-<tt>https://bogomips.org/unicorn-public/$MESSAGE_ID/</tt> if possible
+<tt>https://yhbt.net/unicorn-public/$MESSAGE_ID/</tt> if possible
diff --git a/ISSUES b/ISSUES
index 473da2f..d11dc56 100644
--- a/ISSUES
+++ b/ISSUES
@@ -3 +3 @@
-mailto:unicorn-public@bogomips.org is the best place to report bugs,
+mailto:unicorn-public@yhbt.net is the best place to report bugs,
@@ -5,2 +5,2 @@ submit patches and/or obtain support after you have searched the
-{email archives}[https://bogomips.org/unicorn-public/] and
-{documentation}[https://bogomips.org/unicorn/].
+{email archives}[https://yhbt.net/unicorn-public/] and
+{documentation}[https://yhbt.net/unicorn/].
@@ -15,2 +15,2 @@ submit patches and/or obtain support after you have searched the
-* The email submission port (587) is enabled on the bogomips.org MX:
-  https://bogomips.org/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
+* The email submission port (587) is enabled on the yhbt.net MX:
+  https://yhbt.net/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
@@ -20 +20 @@ can interoperate with any bug tracker which can Cc: us plain-text to
-mailto:unicorn-public@bogomips.org   This includes the Debian BTS
+mailto:unicorn-public@yhbt.net   This includes the Debian BTS
@@ -76,2 +76,2 @@ document distributed with git) on guidelines for patch submission.
-* public: mailto:unicorn-public@bogomips.org
-* nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+* public: mailto:unicorn-public@yhbt.net
+* nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
@@ -79 +79 @@ document distributed with git) on guidelines for patch submission.
-* https://bogomips.org/unicorn-public/
+* https://yhbt.net/unicorn-public/
@@ -87 +87 @@ You can follow along via NNTP (read-only):
-	nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+	nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
@@ -91 +91 @@ Or Atom feeds:
-	https://bogomips.org/unicorn-public/new.atom
+	https://yhbt.net/unicorn-public/new.atom
@@ -94 +94 @@ Or Atom feeds:
-	The HTML archives at https://bogomips.org/unicorn-public/
+	The HTML archives at https://yhbt.net/unicorn-public/
diff --git a/KNOWN_ISSUES b/KNOWN_ISSUES
index ebd4822..0017f20 100644
--- a/KNOWN_ISSUES
+++ b/KNOWN_ISSUES
@@ -12 +12 @@ acceptable solution.  Those issues are documented here.
-  https://bogomips.org/unicorn-public/CAHBuKRj09FdxAgzsefJWotexw-7JYZGJMtgUp_dhjPz9VbKD6Q@mail.gmail.com/
+  https://yhbt.net/unicorn-public/CAHBuKRj09FdxAgzsefJWotexw-7JYZGJMtgUp_dhjPz9VbKD6Q@mail.gmail.com/
@@ -63 +63 @@ acceptable solution.  Those issues are documented here.
-  ref: https://bogomips.org/unicorn-public/20091014221552.GA30624@dcvr.yhbt.net/
+  ref: https://yhbt.net/unicorn-public/20091014221552.GA30624@dcvr.yhbt.net/
diff --git a/Links b/Links
index 10551a6..f81142d 100644
--- a/Links
+++ b/Links
@@ -5 +5 @@ listed below.  If you have any links to add/change/remove, please tell us at
-mailto:unicorn-public@bogomips.org!
+mailto:unicorn-public@yhbt.net!
@@ -26 +26 @@ or services behind them.
-* {raindrops}[https://bogomips.org/raindrops/] - real-time stats for
+* {raindrops}[https://yhbt.net/raindrops/] - real-time stats for
@@ -29 +29 @@ or services behind them.
-* {UnXF}[https://bogomips.org/unxf/]  Un-X-Forward* the Rack environment,
+* {UnXF}[https://yhbt.net/unxf/]  Un-X-Forward* the Rack environment,
@@ -55 +55 @@ or services behind them.
-  https://bogomips.org/mongrel-devel/
+  https://yhbt.net/mongrel-devel/
@@ -57 +57 @@ or services behind them.
-* {david}[https://bogomips.org/david.git] - a tool to explain why you need
+* {david}[https://yhbt.net/david.git] - a tool to explain why you need
diff --git a/README b/README
index 89467fc..0e95f48 100644
--- a/README
+++ b/README
@@ -83 +83 @@ You can get the latest source via git from the following locations
-  https://bogomips.org/unicorn.git
+  https://yhbt.net/unicorn.git
@@ -88 +88 @@ You may browse the code from the web:
-* https://bogomips.org/unicorn.git
+* https://yhbt.net/unicorn.git
@@ -136 +136 @@ requests) go to the mailing list/newsgroup.  See the ISSUES document for
-information on the {mailing list}[mailto:unicorn-public@bogomips.org].
+information on the {mailing list}[mailto:unicorn-public@yhbt.net].
@@ -138 +138 @@ information on the {mailing list}[mailto:unicorn-public@bogomips.org].
-The mailing list is archived at https://bogomips.org/unicorn-public/
+The mailing list is archived at https://yhbt.net/unicorn-public/
@@ -141 +141 @@ nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
-nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
@@ -144 +144 @@ For the latest on unicorn releases, you may also finger us at
-unicorn@bogomips.org or check our NEWS page (and subscribe to our Atom
+unicorn@yhbt.net or check our NEWS page (and subscribe to our Atom
diff --git a/SIGNALS b/SIGNALS
index 1af851d..7321f2b 100644
--- a/SIGNALS
+++ b/SIGNALS
@@ -11 +11 @@ One example init script is distributed with unicorn:
-https://bogomips.org/unicorn/examples/init.sh
+https://yhbt.net/unicorn/examples/init.sh
diff --git a/Sandbox b/Sandbox
index d0f915e..651e5cd 100644
--- a/Sandbox
+++ b/Sandbox
@@ -37 +37 @@ unicorn_rails") to start unicorn with the correct environment variables
-ref: https://bogomips.org/unicorn-public/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us/
+ref: https://yhbt.net/unicorn-public/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us/
@@ -47 +47 @@ ref:
-https://bogomips.org/unicorn-public/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com/
+https://yhbt.net/unicorn-public/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com/
diff --git a/archive/slrnpull.conf b/archive/slrnpull.conf
index fcfcafe..fd04f97 100644
--- a/archive/slrnpull.conf
+++ b/archive/slrnpull.conf
@@ -4 +4 @@ gmane.comp.lang.ruby.unicorn.general 1000000000 1000000000 0
-# usage: slrnpull -d $PWD -h news.gmane.org --no-post
+# usage: slrnpull -d $PWD -h news.gmane.io --no-post
diff --git a/examples/big_app_gc.rb b/examples/big_app_gc.rb
index 9d05719..c1bae10 100644
--- a/examples/big_app_gc.rb
+++ b/examples/big_app_gc.rb
@@ -1 +1 @@
-# see {Unicorn::OobGC}[https://bogomips.org/unicorn/Unicorn/OobGC.html]
+# see {Unicorn::OobGC}[https://yhbt.net/unicorn/Unicorn/OobGC.html]
diff --git a/examples/logrotate.conf b/examples/logrotate.conf
index 77a01b5..c3aa40d 100644
--- a/examples/logrotate.conf
+++ b/examples/logrotate.conf
@@ -8 +8 @@
-#    https://bogomips.org/unicorn-public/?q=logrotate
+#    https://yhbt.net/unicorn-public/?q=logrotate
@@ -36 +36 @@
-		# Mail us at unicorn-public@bogomips.org
+		# Mail us at unicorn-public@yhbt.net
diff --git a/examples/nginx.conf b/examples/nginx.conf
index b6b69c1..c5026f9 100644
--- a/examples/nginx.conf
+++ b/examples/nginx.conf
@@ -116 +116 @@ http {
-    # https://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
+    # https://yhbt.net/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
diff --git a/examples/unicorn.conf.minimal.rb b/examples/unicorn.conf.minimal.rb
index 2d1bf0a..46fd634 100644
--- a/examples/unicorn.conf.minimal.rb
+++ b/examples/unicorn.conf.minimal.rb
@@ -4 +4 @@
-# See https://bogomips.org/unicorn/Unicorn/Configurator.html for complete
+# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
@@ -6 +6 @@
-# See also https://bogomips.org/unicorn/examples/unicorn.conf.rb for
+# See also https://yhbt.net/unicorn/examples/unicorn.conf.rb for
diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index d2897ef..d90bdc4 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -5 +5 @@
-# https://bogomips.org/unicorn/examples/unicorn.conf.minimal.rb
+# https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
@@ -8 +8 @@
-# See https://bogomips.org/unicorn/Unicorn/Configurator.html for complete
+# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
index 8ef23bc..dfe3a63 100644
--- a/ext/unicorn_http/unicorn_http.rl
+++ b/ext/unicorn_http/unicorn_http.rl
@@ -490 +490 @@ static void set_url_scheme(VALUE env, VALUE *server_port)
-     * unicorn-public@bogomips.org (no HTML mail, no subscription necessary)
+     * unicorn-public@yhbt.net (no HTML mail, no subscription necessary)
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index dd5dff4..d5991fe 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -99 +99 @@ def self.builder(ru, op)
-  # Raindrops::Middleware under Linux: https://bogomips.org/raindrops/
+  # Raindrops::Middleware under Linux: https://yhbt.net/raindrops/
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index e8b76f5..c3a4f2d 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -6,2 +6,2 @@
-# See https://bogomips.org/unicorn/examples/unicorn.conf.rb and
-# https://bogomips.org/unicorn/examples/unicorn.conf.minimal.rb
+# See https://yhbt.net/unicorn/examples/unicorn.conf.rb and
+# https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
@@ -10 +10 @@
-# https://bogomips.org/unicorn/examples/nginx.conf
+# https://yhbt.net/unicorn/examples/nginx.conf
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 5334fa0..a52931a 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -9 +9 @@
-# {source}[https://bogomips.org/unicorn.git/tree/lib/unicorn/http_server.rb]
+# {source}[https://yhbt.net/unicorn.git/tree/lib/unicorn/http_server.rb]
diff --git a/lib/unicorn/oob_gc.rb b/lib/unicorn/oob_gc.rb
index c4741a0..3b2f488 100644
--- a/lib/unicorn/oob_gc.rb
+++ b/lib/unicorn/oob_gc.rb
@@ -46,2 +46,2 @@
-# * https://bogomips.org/unicorn-public/0BFC98E9-072B-47EE-9A70-05478C20141B@lukemelia.com/
-# * https://bogomips.org/unicorn-public/AANLkTilUbgdyDv9W1bi-s_W6kq9sOhWfmuYkKLoKGOLj@mail.gmail.com/
+# * https://yhbt.net/unicorn-public/0BFC98E9-072B-47EE-9A70-05478C20141B@lukemelia.com/
+# * https://yhbt.net/unicorn-public/AANLkTilUbgdyDv9W1bi-s_W6kq9sOhWfmuYkKLoKGOLj@mail.gmail.com/
diff --git a/unicorn.gemspec b/unicorn.gemspec
index ceea831..a189f8d 100644
--- a/unicorn.gemspec
+++ b/unicorn.gemspec
@@ -18 +18 @@
-  s.email = %q{unicorn-public@bogomips.org}
+  s.email = %q{unicorn-public@yhbt.net}
@@ -25 +25 @@
-  s.homepage = 'https://bogomips.org/unicorn/'
+  s.homepage = 'https://yhbt.net/unicorn/'

^ permalink raw reply related	[relevance 23%]

* [ANN] unicorn 5.5.2 - Rack HTTP server for fast clients and *nix
@ 2019-12-20  2:15  5% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2019-12-20  2:15 UTC (permalink / raw)
  To: ruby-talk, unicorn-public; +Cc: Terry Scheingeld

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

Disclaimer:

Due to its ability to tolerate crashes and isolate clients, unicorn
is unfortunately known to prolong the existence of bugs in applications
and libraries which run on top of it.

Consider this just an announcement to inform existing users of a
new version, not something to convince you to switch to something
that set the entire Ruby back decades in terms of concurrency.

* https://bogomips.org/unicorn/
* public list: unicorn-public@bogomips.org
* mail archives: https://bogomips.org/unicorn-public/
* git clone https://bogomips.org/unicorn.git
* https://bogomips.org/unicorn/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

Changes:

Thanks to Terry Scheingeld, we now workaround a Ruby bug
and can now run with taint checks enabled:
<https://bugs.ruby-lang.org/issues/14485>
<https://bogomips.org/unicorn-public/CABg1sXrvGv9G6CDQxePDUqTe6N-5UpLXm7eG3YQO=dda-Cgg7A@mail.gmail.com/>

There's also a few documentation updates and building packages
from source is easier since pandoc is no longer a dependency
(and I can no longer afford the bandwidth or space to install
it).

Eric Wong (7):
      test/benchmark/ddstream: demo for slowly reading clients
      test/benchmark/readinput: demo for slowly uploading clients
      test/benchmark/uconnect: test for accept loop speed
      examples/unicorn@.service: note the NonBlocking flag
      Merge remote-tracking branch 'origin/ts/tmpio'
      test_util: get rid of some unused variables in tests
      doc: replace pandoc-"Markdown" with real manpages

Terry Scheingeld (1):
      tmpio: workaround File#path being tainted on unlink

havpbea: orngvat n qrnq ubefr hagvy gur fgvpx trgf fghpx va vg'f fxhyy

^ permalink raw reply	[relevance 5%]

* [PATCH 2/3] http: use gperf for common fields optimization
  @ 2019-07-04 22:01  5% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2019-07-04 22:01 UTC (permalink / raw)
  To: unicorn-public

GNU gperf is a commonly-used tool for generating perfect hashes
and available on every platform unicorn runs on.  C Ruby, gcc,
glibc all already use it.

Using a hash lookup instead of a linear scan already shows
measurable improvements when memoized header keys are all
used:

* test/benchmark/http_parser.rb (no options):

   100000 iterations
         user     system      total        real
  -  0.411857   0.000200   0.412057 (  0.412070)
  +  0.397960   0.000181   0.398141 (  0.398149)

Results which require generating a new string from an unmemoized
header is less significant, but still consistent measurable:

* test/benchmark/http_parser.rb -H 'DNT: 1'

   100000 iterations
         user     system      total        real
  -  0.461416   0.000000   0.461416 (  0.461417)
  +  0.461329   0.000000   0.461329 (  0.461363)

Most importantly, this change allows us to memoize more keys
without worrying too much about the overhead of a O(n) scan.
---
 .gitignore                                   |  1 +
 GNUmakefile                                  | 18 ++++-
 ext/unicorn_http/common_field_optimization.h | 79 +++++---------------
 ext/unicorn_http/common_fields.gperf         | 56 ++++++++++++++
 ext/unicorn_http/gperf.rb                    | 27 +++++++
 5 files changed, 117 insertions(+), 64 deletions(-)
 create mode 100644 ext/unicorn_http/common_fields.gperf
 create mode 100644 ext/unicorn_http/gperf.rb

diff --git a/.gitignore b/.gitignore
index ad92808..05e5e45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
 /test/ruby-*
 ext/unicorn_http/Makefile
 ext/unicorn_http/unicorn_http.c
+ext/unicorn_http/common_fields.h
 log/
 pkg/
 /vendor
diff --git a/GNUmakefile b/GNUmakefile
index a7e4102..3dbad2c 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -10,6 +10,7 @@ RAGEL = ragel
 RSYNC = rsync
 OLDDOC = olddoc
 RDOC = rdoc
+GPERF = gperf
 
 GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
 	@./GIT-VERSION-GEN
@@ -40,7 +41,9 @@ T_n_log := $(subst .n,$(log_suffix),$(T_n))
 test_prefix = $(CURDIR)/test/$(RUBY_ENGINE)-$(RUBY_VERSION)
 
 ext := ext/unicorn_http
-c_files := $(ext)/unicorn_http.c $(ext)/httpdate.c $(wildcard $(ext)/*.h)
+c_files := $(addprefix $(ext)/, unicorn_http.c common_fields.h \
+	httpdate.c common_field_optimization.h ext_help.h \
+	global_variables.h)
 rl_files := $(wildcard $(ext)/*.rl)
 base_bins := unicorn unicorn_rails
 bins := $(addprefix bin/, $(base_bins))
@@ -48,7 +51,14 @@ man1_rdoc := $(addsuffix _1, $(base_bins))
 man1_bins := $(addsuffix .1, $(base_bins))
 man1_paths := $(addprefix man/man1/, $(man1_bins))
 rb_files := $(bins) $(shell find lib ext -type f -name '*.rb')
-inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb
+inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb \
+		$(ext)/common_fields.gperf
+
+gperf :: $(ext)/common_fields.h
+$(ext)/common_fields.h : $(ext)/common_fields.gperf $(ext)/gperf.rb
+	$(GPERF) $< >$@-
+	$(MRI) --disable-gems $(ext)/gperf.rb <$@- >$@+
+	test -s $@+ && mv $@+ $@ && $(RM) $@-
 
 ragel: $(ext)/unicorn_http.c
 $(ext)/unicorn_http.c: $(rl_files)
@@ -159,12 +169,12 @@ man html:
 	$(MAKE) -C Documentation install-$@
 
 pkg_extra := GIT-VERSION-FILE lib/unicorn/version.rb LATEST NEWS \
-             $(ext)/unicorn_http.c $(man1_paths)
+             $(ext)/unicorn_http.c $(ext)/common_fields.h $(man1_paths)
 
 NEWS:
 	$(OLDDOC) prepare
 
-.manifest: $(ext)/unicorn_http.c man NEWS
+.manifest: $(ext)/unicorn_http.c $(ext)/common_fields.h man NEWS
 	(git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
 	  LC_ALL=C sort > $@+
 	cmp $@+ $@ || mv $@+ $@
diff --git a/ext/unicorn_http/common_field_optimization.h b/ext/unicorn_http/common_field_optimization.h
index 0659fc7..f69b618 100644
--- a/ext/unicorn_http/common_field_optimization.h
+++ b/ext/unicorn_http/common_field_optimization.h
@@ -3,58 +3,12 @@
 #include "ruby.h"
 #include "c_util.h"
 
-struct common_field {
-  const signed long len;
-  const char *name;
-  VALUE value;
-};
-
 /*
  * A list of common HTTP headers we expect to receive.
  * This allows us to avoid repeatedly creating identical string
  * objects to be used with rb_hash_aset().
  */
-static struct common_field common_http_fields[] = {
-# define f(N) { (sizeof(N) - 1), N, Qnil }
-  f("ACCEPT"),
-  f("ACCEPT_CHARSET"),
-  f("ACCEPT_ENCODING"),
-  f("ACCEPT_LANGUAGE"),
-  f("ALLOW"),
-  f("AUTHORIZATION"),
-  f("CACHE_CONTROL"),
-  f("CONNECTION"),
-  f("CONTENT_ENCODING"),
-  f("CONTENT_LENGTH"),
-  f("CONTENT_TYPE"),
-  f("COOKIE"),
-  f("DATE"),
-  f("EXPECT"),
-  f("FROM"),
-  f("HOST"),
-  f("IF_MATCH"),
-  f("IF_MODIFIED_SINCE"),
-  f("IF_NONE_MATCH"),
-  f("IF_RANGE"),
-  f("IF_UNMODIFIED_SINCE"),
-  f("KEEP_ALIVE"), /* Firefox sends this */
-  f("MAX_FORWARDS"),
-  f("PRAGMA"),
-  f("PROXY_AUTHORIZATION"),
-  f("RANGE"),
-  f("REFERER"),
-  f("TE"),
-  f("TRAILER"),
-  f("TRANSFER_ENCODING"),
-  f("UPGRADE"),
-  f("USER_AGENT"),
-  f("VIA"),
-  f("X_FORWARDED_FOR"), /* common for proxies */
-  f("X_FORWARDED_PROTO"), /* common for proxies */
-  f("X_REAL_IP"), /* common for proxies */
-  f("WARNING")
-# undef f
-};
+#include "common_fields.h"
 
 #define HTTP_PREFIX "HTTP_"
 #define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1)
@@ -79,21 +33,27 @@ static VALUE str_new_dd_freeze(const char *ptr, long len)
 /* this function is not performance-critical, called only at load time */
 static void init_common_fields(void)
 {
-  int i;
-  struct common_field *cf = common_http_fields;
+  size_t i;
   char tmp[64];
 
   id_uminus = rb_intern("-@");
   memcpy(tmp, HTTP_PREFIX, HTTP_PREFIX_LEN);
 
-  for(i = ARRAY_SIZE(common_http_fields); --i >= 0; cf++) {
+  for (i = 0; i < ARRAY_SIZE(cf_wordlist); i++) {
+    long len = (long)cf_lengthtable[i];
+    struct common_field *cf = &cf_wordlist[i];
+    const char *s;
+
+    if (!len)
+      continue;
+
+    s = cf->name + cf_stringpool;
     /* Rack doesn't like certain headers prefixed with "HTTP_" */
-    if (!strcmp("CONTENT_LENGTH", cf->name) ||
-        !strcmp("CONTENT_TYPE", cf->name)) {
-      cf->value = str_new_dd_freeze(cf->name, cf->len);
+    if (!strcmp("CONTENT_LENGTH", s) || !strcmp("CONTENT_TYPE", s)) {
+      cf->value = str_new_dd_freeze(s, len);
     } else {
-      memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1);
-      cf->value = str_new_dd_freeze(tmp, HTTP_PREFIX_LEN + cf->len);
+      memcpy(tmp + HTTP_PREFIX_LEN, s, len + 1);
+      cf->value = str_new_dd_freeze(tmp, HTTP_PREFIX_LEN + len);
     }
     rb_gc_register_mark_object(cf->value);
   }
@@ -102,12 +62,11 @@ static void init_common_fields(void)
 /* this function is called for every header set */
 static VALUE find_common_field(const char *field, size_t flen)
 {
-  int i;
-  struct common_field *cf = common_http_fields;
+  struct common_field *cf = cf_lookup(field, flen);
 
-  for(i = ARRAY_SIZE(common_http_fields); --i >= 0; cf++) {
-    if (cf->len == (long)flen && !memcmp(cf->name, field, flen))
-      return cf->value;
+  if (cf) {
+    assert(cf->value);
+    return cf->value;
   }
   return Qnil;
 }
diff --git a/ext/unicorn_http/common_fields.gperf b/ext/unicorn_http/common_fields.gperf
new file mode 100644
index 0000000..179afe5
--- /dev/null
+++ b/ext/unicorn_http/common_fields.gperf
@@ -0,0 +1,56 @@
+%{
+#include <ruby.h>
+%}
+%compare-lengths
+%enum
+%global-table
+%language=ANSI-C
+%pic
+%struct-type
+%define hash-function-name cf_hash
+%define length-table-name cf_lengthtable
+%define lookup-function-name cf_lookup
+%define string-pool-name cf_stringpool
+%define word-array-name cf_wordlist
+
+struct common_field { size_t name; VALUE value; };
+%%
+ACCEPT
+ACCEPT_CHARSET
+ACCEPT_ENCODING
+ACCEPT_LANGUAGE
+ALLOW
+AUTHORIZATION
+CACHE_CONTROL
+CONNECTION
+CONTENT_ENCODING
+CONTENT_LENGTH
+CONTENT_TYPE
+COOKIE
+DATE
+EXPECT
+FROM
+HOST
+IF_MATCH
+IF_MODIFIED_SINCE
+IF_NONE_MATCH
+IF_RANGE
+IF_UNMODIFIED_SINCE
+# Firefox sends Keep-Alive (or maybe only old versions?)
+KEEP_ALIVE
+MAX_FORWARDS
+PRAGMA
+PROXY_AUTHORIZATION
+RANGE
+REFERER
+TE
+TRAILER
+TRANSFER_ENCODING
+UPGRADE
+USER_AGENT
+VIA
+# common proxies set some of these X- headers
+X_FORWARDED_FOR
+X_FORWARDED_PROTO
+X_REAL_IP
+WARNING
diff --git a/ext/unicorn_http/gperf.rb b/ext/unicorn_http/gperf.rb
new file mode 100644
index 0000000..9765f86
--- /dev/null
+++ b/ext/unicorn_http/gperf.rb
@@ -0,0 +1,27 @@
+#!/usr/bin/ruby -w
+buf = STDIN.read # output of: gperf ext/unicorn_http/common_fields.gperf
+
+# this is supposed to fail if it doesn't subsitute anything:
+print buf.sub!(
+
+# make sure all functions are static
+/\nstruct \w+ \*\n(\w+_)?lookup/) {
+  "\nstatic#$&"
+}.
+
+gsub!(
+# gperf 3.0.x used "(int)(long)", 3.1 uses "(int)(size_t)",
+#  input: {(int)(size_t)&((struct cf_pool_t *)0)->cf_pool_str3},
+# output: {offsetof(struct cf_pool_t, cf_pool_str3)},
+/{\(int\)\(\w+\)\&\(\((struct \w+) *\*\)0\)->(\w+)}/) {
+  "{offsetof(#$1, #$2)}"
+}.
+
+# make sure everything is 64-bit safe and compilers don't truncate
+gsub!(/\b(?:unsigned )?int\b/, 'size_t').
+
+# This isn't need for %switch%, but we'll experiment with to see
+# if it's necessary, or not.
+# don't give compilers a reason to complain, (struct foo *)->name
+# is size_t, so unused slots should be size_t:
+gsub(/\{-1\}/, '{(size_t)-1}')
-- 
EW


^ permalink raw reply related	[relevance 5%]

* [PATCH 2/3] test/benchmark/readinput: demo for slowly uploading clients
    2019-05-12 22:25 10% ` [PATCH 1/3] test/benchmark/ddstream: demo for slowly reading clients Eric Wong
@ 2019-05-12 22:25 10% ` Eric Wong
  1 sibling, 0 replies; 200+ results
From: Eric Wong @ 2019-05-12 22:25 UTC (permalink / raw)
  To: unicorn-public

This is intended to demonstrate how badly we suck at dealing
with slow clients making uploads.  It can help users evaluate
alternative fully-buffering reverse proxies, because nginx
should not be the only option.
---
 test/benchmark/README       |  5 +++++
 test/benchmark/readinput.ru | 40 +++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 test/benchmark/readinput.ru

diff --git a/test/benchmark/README b/test/benchmark/README
index e9b7a41..cd929f3 100644
--- a/test/benchmark/README
+++ b/test/benchmark/README
@@ -47,6 +47,11 @@ is NOT our problem.  That is the job of nginx (or similar).
 Standalone Rack app intended to show how BAD we are at slow clients.
 See usage in comments.
 
+== readinput.ru
+
+Standalone Rack app intended to show how bad we are with slow uploaders.
+See usage in comments.
+
 == Contributors
 
 This directory is intended to remain stable.  Do not make changes
diff --git a/test/benchmark/readinput.ru b/test/benchmark/readinput.ru
new file mode 100644
index 0000000..c91bec3
--- /dev/null
+++ b/test/benchmark/readinput.ru
@@ -0,0 +1,40 @@
+# This app is intended to test large HTTP requests with or without
+# a fully-buffering reverse proxy such as nginx. Without a fully-buffering
+# reverse proxy, unicorn will be unresponsive when client count exceeds
+# worker_processes.
+
+DOC = <<DOC
+To demonstrate how bad unicorn is at slowly uploading clients:
+
+  # in one terminal, start unicorn with one worker:
+  unicorn -E none -l 127.0.0.1:8080 test/benchmark/readinput.ru
+
+  # in a different terminal, upload 45M from multiple curl processes:
+  dd if=/dev/zero bs=45M count=1 | curl -T- -HExpect: --limit-rate 1M \
+     --trace-time -v http://127.0.0.1:8080/ &
+  dd if=/dev/zero bs=45M count=1 | curl -T- -HExpect: --limit-rate 1M \
+     --trace-time -v http://127.0.0.1:8080/ &
+  wait
+
+# The last client won't see a response until the first one is done uploading
+# You also won't be able to make GET requests to view this documentation
+# while clients are uploading.  You can also view the stderr debug output
+# of unicorn (see logging code in #{__FILE__}).
+DOC
+
+run(lambda do |env|
+  input = env['rack.input']
+  buf = ''.b
+
+  # default logger contains timestamps, rely on that so users can
+  # see what the server is doing
+  l = env['rack.logger']
+
+  l.debug('BEGIN reading input ...') if l
+  :nop while input.read(16384, buf)
+  l.debug('DONE reading input ...') if l
+
+  buf.clear
+  [ 200, [ %W(Content-Length #{DOC.size}), %w(Content-Type text/plain) ],
+    [ DOC ] ]
+end)
-- 
EW


^ permalink raw reply related	[relevance 10%]

* [PATCH 1/3] test/benchmark/ddstream: demo for slowly reading clients
  @ 2019-05-12 22:25 10% ` Eric Wong
  2019-05-12 22:25 10% ` [PATCH 2/3] test/benchmark/readinput: demo for slowly uploading clients Eric Wong
  1 sibling, 0 replies; 200+ results
From: Eric Wong @ 2019-05-12 22:25 UTC (permalink / raw)
  To: unicorn-public

This is intended to demonstrate how badly we suck at dealing
with slow clients.  It can help users evaluate alternative
fully-buffering reverse proxies, because nginx should not
be the only option.

Update the benchmark README while we're at it
---
 test/benchmark/README      | 13 +++++++---
 test/benchmark/ddstream.ru | 50 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 test/benchmark/ddstream.ru

diff --git a/test/benchmark/README b/test/benchmark/README
index 1d3cdd0..e9b7a41 100644
--- a/test/benchmark/README
+++ b/test/benchmark/README
@@ -42,9 +42,14 @@ The benchmark client is usually httperf.
 Another gentle reminder: performance with slow networks/clients
 is NOT our problem.  That is the job of nginx (or similar).
 
+== ddstream.ru
+
+Standalone Rack app intended to show how BAD we are at slow clients.
+See usage in comments.
+
 == Contributors
 
-This directory is maintained independently in the "benchmark" branch
-based against v0.1.0.  Only changes to this directory (test/benchmarks)
-are committed to this branch although the master branch may merge this
-branch occassionaly.
+This directory is intended to remain stable.  Do not make changes
+to benchmarking code which can change performance and invalidate
+results across revisions.  Instead, write new benchmarks and update
+coments/documentation as necessary.
diff --git a/test/benchmark/ddstream.ru b/test/benchmark/ddstream.ru
new file mode 100644
index 0000000..b14c973
--- /dev/null
+++ b/test/benchmark/ddstream.ru
@@ -0,0 +1,50 @@
+# This app is intended to test large HTTP responses with or without
+# a fully-buffering reverse proxy such as nginx. Without a fully-buffering
+# reverse proxy, unicorn will be unresponsive when client count exceeds
+# worker_processes.
+#
+# To demonstrate how bad unicorn is at slowly reading clients:
+#
+#   # in one terminal, start unicorn with one worker:
+#   unicorn -E none -l 127.0.0.1:8080 test/benchmark/ddstream.ru
+#
+#   # in a different terminal, start more slow curl processes than
+#   # unicorn workers and watch time outputs
+#   curl --limit-rate 8K --trace-time -vsN http://127.0.0.1:8080/ >/dev/null &
+#   curl --limit-rate 8K --trace-time -vsN http://127.0.0.1:8080/ >/dev/null &
+#   wait
+#
+# The last client won't see a response until the first one is done reading
+#
+# nginx note: do not change the default "proxy_buffering" behavior.
+# Setting "proxy_buffering off" prevents nginx from protecting unicorn.
+
+# totally standalone rack app to stream a giant response
+class BigResponse
+  def initialize(bs, count)
+    @buf = "#{bs.to_s(16)}\r\n#{' ' * bs}\r\n"
+    @count = count
+    @res = [ 200,
+      { 'Transfer-Encoding' => -'chunked', 'Content-Type' => 'text/plain' },
+      self
+    ]
+  end
+
+  # rack response body iterator
+  def each
+    (1..@count).each { yield @buf }
+    yield -"0\r\n\r\n"
+  end
+
+  # rack app entry endpoint
+  def call(_env)
+    @res
+  end
+end
+
+# default to a giant (128M) response because kernel socket buffers
+# can be ridiculously large on some systems
+bs = ENV['bs'] ? ENV['bs'].to_i : 65536
+count = ENV['count'] ? ENV['count'].to_i : 2048
+warn "serving response with bs=#{bs} count=#{count} (#{bs*count} bytes)"
+run BigResponse.new(bs, count)
-- 
EW


^ permalink raw reply related	[relevance 10%]

* Re: [PATCH] Rescue failed pipe resizes due to permissions
  @ 2019-05-03 22:53  7% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2019-05-03 22:53 UTC (permalink / raw)
  To: Stephen Demjanenko; +Cc: unicorn-public

sdemjanenko@gmail.com wrote:

Thanks, patch looks good; though I'd like to confirm
some things below for the sake of documentation.

> The `EPERM` error gets raised by the Linux kernel if:
> ```
> (too_many_pipe_buffers_hard(pipe->user) ||
> too_many_pipe_buffers_soft(pipe->user)) &&
> !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)
> ```

Which kernel are you running?
Modern kernels prefix that condition with:

	if (nr_pages > pipe->buffers &&

Scanning kernel changes with `git log -p -L:pipe_set_size:fs/pipe.c',
I see that check was added in b0b91d18e2e97b741b294af9333824ecc3fadfd8
("pipe: fix limit checking in pipe_set_size()")
which was fixed in Linux v4.9+ and v3.16.57+

https://80x24.org/mirrors/linux.git/commit?id=b0b91d18e2e97b741b294af9333824ecc3fadfd8
https://lore.kernel.org/lkml/?q=s%3A%22fix+limit+checking+in+pipe_set_size%22

> Given that the resize is not strictly necessary Unicorn should
> rescue the error and continue booting.

Agreed.  Applied, tested and pushed to master as
commit 5c613c6ea98541df587193e861364c858a8a0abd
Thanks!

Will tag and release v5.5.1 in a day or two.

^ permalink raw reply	[relevance 7%]

* [RFC] doc: unicorn_rails: clarify that it is intended for rails <= 2.x
@ 2019-04-15  6:52 20% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2019-04-15  6:52 UTC (permalink / raw)
  To: unicorn-public

Hopefully the wording is a little more explicit and clearer
by stating its purpose in the first line of the description.
---
 Grammar/wording awkwardness review/comments greatly appreciated,
 haven't used English or Ruby much, lately.

 Documentation/unicorn_rails.1.txt | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt
index fb0e60f..0ce9bcf 100644
--- a/Documentation/unicorn_rails.1.txt
+++ b/Documentation/unicorn_rails.1.txt
@@ -12,14 +12,12 @@ unicorn_rails [-c CONFIG_FILE] [-E RAILS_ENV] [-D] [RACKUP_FILE]
 
 # DESCRIPTION
 
-A rackup(1)-like command to launch Rails applications using Unicorn.  It
-is expected to be started in your Rails application root (RAILS_ROOT),
-but the "working_directory" directive may be used in the CONFIG_FILE.
+A rackup(1)-like command to launch ancient Rails (2.x and earlier)
+applications using Unicorn.  Rails 3 (and later) support Rack natively,
+so users are encouraged to use unicorn(1) instead of unicorn_rails(1).
 
-It is designed to help Rails 1.x and 2.y users transition to Rack, but
-it is NOT needed for Rails 3 applications.  Rails 3 users are encouraged
-to use unicorn(1) instead of unicorn_rails(1).  Users of Rails 1.x/2.y
-may also use unicorn(1) instead of unicorn_rails(1).
+It is expected to be started in your Rails application root (RAILS_ROOT),
+but the "working_directory" directive may be used in the CONFIG_FILE.
 
 The outward interface resembles rackup(1), the internals and default
 middleware loading is designed like the `script/server` command
-- 
EW

^ permalink raw reply related	[relevance 20%]

* [ANN] unicorn 5.5.0 - Rack HTTP server for fast clients and
@ 2019-03-04  1:15  0% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2019-03-04  1:15 UTC (permalink / raw)
  To: ruby-talk, unicorn-public; +Cc: Jeremy Evans

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

Disclaimer:

Due to its ability to tolerate crashes and isolate clients, unicorn
is unfortunately known to prolong the existence of bugs in applications
and libraries which run on top of it.

* https://bogomips.org/unicorn/
* public list: unicorn-public@bogomips.org
* mail archives: https://bogomips.org/unicorn-public/
* git clone https://bogomips.org/unicorn.git
* https://bogomips.org/unicorn/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

unicorn 5.5.0

Mostly identical to 5.5.0.pre1, which I didn't hear any feedback
from:

  https://bogomips.org/unicorn-public/20181220222842.GA27382@dcvr/

> Jeremy Evans contributed the "default_middleware" configuration option:
>
>   https://bogomips.org/unicorn-public/20180913192055.GD48926@jeremyevans.local/
>
> Jeremy also contributed the ability to use separate groups for the process
> and log files:
>
>   https://bogomips.org/unicorn-public/20180913192449.GE48926@jeremyevans.local/
>
> There's also a couple of uninteresting minor optimizations and
> documentation additions.

Otherwise, there's one extra change to use
rb_gc_register_mark_object which is finally a documented part of
the Ruby C-API, but has existed since the 1.9 days.

^ permalink raw reply	[relevance 0%]

* [ANN] unicorn 5.5.0.pre1 - Rack HTTP server for fast clients and Unix
@ 2018-12-20 22:28  5% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2018-12-20 22:28 UTC (permalink / raw)
  To: ruby-talk, unicorn-public; +Cc: Jeremy Evans

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

Disclaimer:

Due to its ability to tolerate crashes and isolate clients, unicorn
is unfortunately known to prolong the existence of bugs in applications
and libraries which run on top of it.

* https://bogomips.org/unicorn/
* public list: unicorn-public@bogomips.org
* mail archives: https://bogomips.org/unicorn-public/
* git clone https://bogomips.org/unicorn.git
* https://bogomips.org/unicorn/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

This is a pre-release RubyGem intended for testing.

Changes:

unicorn 5.5.0.pre1

Jeremy Evans contributed the "default_middleware" configuration option:

  https://bogomips.org/unicorn-public/20180913192055.GD48926@jeremyevans.local/

Jeremy also contributed the ability to use separate groups for the process
and log files:

  https://bogomips.org/unicorn-public/20180913192449.GE48926@jeremyevans.local/

There's also a couple of uninteresting minor optimizations and
documentation additions.

Eric Wong (10):
      remove random seed reset atfork
      use IO#wait instead of kgio_wait_readable
      Merge branch '5.4-stable'
      shrink pipes under Linux
      socket_helper: add hint for FreeBSD users for accf_http(9)
      tests: ensure -N/--no-default-middleware not supported in config.ru
      doc: update more URLs to use HTTPS and avoid redirects
      deduplicate strings VM-wide in Ruby 2.5+
      doc/ISSUES: add links to git clone-able mail archives of our dependencies
      README: minor updates and additional disclaimer

Jeremy Evans (2):
      Make Worker#user support different process primary group and log file group
      Support default_middleware configuration option
-- 

^ permalink raw reply	[relevance 5%]

* [PATCH] doc: update more URLs to use HTTPS and avoid redirects
@ 2018-11-07 23:38 20% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2018-11-07 23:38 UTC (permalink / raw)
  To: unicorn-public

Latency from redirects is painful, and HTTPS can protect privacy
in some cases.
---
 .olddoc.yml                       |  2 +-
 Application_Timeouts              |  8 ++++----
 Documentation/unicorn.1.txt       |  2 +-
 Documentation/unicorn_rails.1.txt |  2 +-
 LICENSE                           |  4 ++--
 Links                             | 12 ++++++------
 README                            |  8 ++++----
 Sandbox                           |  4 ++--
 examples/logrotate.conf           |  2 +-
 examples/nginx.conf               |  5 +++--
 lib/unicorn/configurator.rb       |  2 +-
 lib/unicorn/http_request.rb       |  2 +-
 lib/unicorn/http_server.rb        |  2 +-
 lib/unicorn/util.rb               |  2 +-
 t/README                          |  8 ++++----
 15 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/.olddoc.yml b/.olddoc.yml
index cacc0ab..d2d340f 100644
--- a/.olddoc.yml
+++ b/.olddoc.yml
@@ -1,6 +1,6 @@
 ---
 cgit_url: https://bogomips.org/unicorn.git
-git_url: git://bogomips.org/unicorn.git
+git_url: https://bogomips.org/unicorn.git
 rdoc_url: https://bogomips.org/unicorn/
 ml_url: https://bogomips.org/unicorn-public/
 merge_html:
diff --git a/Application_Timeouts b/Application_Timeouts
index 561a1cc..4dcd954 100644
--- a/Application_Timeouts
+++ b/Application_Timeouts
@@ -23,10 +23,10 @@ Most database adapters allow configurable timeouts.
 Net::HTTP and Net::SMTP in the Ruby standard library allow
 configurable timeouts.
 
-Even for things as fast as {memcached}[http://memcached.org/],
-{dalli}[http://rubygems.org/gems/dalli],
-{memcached}[http://rubygems.org/gems/memcached] and
-{memcache-client}[http://rubygems.org/gems/memcache-client] RubyGems all
+Even for things as fast as {memcached}[https://memcached.org/],
+{dalli}[https://rubygems.org/gems/dalli],
+{memcached}[https://rubygems.org/gems/memcached] and
+{memcache-client}[https://rubygems.org/gems/memcache-client] RubyGems all
 offer configurable timeouts.
 
 Consult the relevant documentation for the libraries you use on
diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index e692078..da7281d 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
@@ -182,6 +182,6 @@ the unicorn config file.
 * [Rackup HowTo][3]
 
 [1]: https://bogomips.org/unicorn/
-[2]: http://www.rubydoc.info/github/rack/rack/
+[2]: https://www.rubydoc.info/github/rack/rack/
 [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
 [4]: https://bogomips.org/unicorn/SIGNALS.html
diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt
index 088e2ff..fb0e60f 100644
--- a/Documentation/unicorn_rails.1.txt
+++ b/Documentation/unicorn_rails.1.txt
@@ -170,6 +170,6 @@ used by Unicorn.
 * [Rackup HowTo][3]
 
 [1]: https://bogomips.org/unicorn/
-[2]: http://www.rubydoc.info/github/rack/rack/
+[2]: https://www.rubydoc.info/github/rack/rack/
 [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
 [4]: https://bogomips.org/unicorn/SIGNALS.html
diff --git a/LICENSE b/LICENSE
index 5b6458e..e986865 100644
--- a/LICENSE
+++ b/LICENSE
@@ -8,8 +8,8 @@ any later version.  We currently prefer the GPLv3 or later for
 derivative works, but the GPLv2 is fine.
 
 The complete texts of the GPLv2 and GPLv3 are below:
-GPLv2 - http://www.gnu.org/licenses/gpl-2.0.txt
-GPLv3 - http://www.gnu.org/licenses/gpl-3.0.txt
+GPLv2 - https://www.gnu.org/licenses/gpl-2.0.txt
+GPLv3 - https://www.gnu.org/licenses/gpl-3.0.txt
 
 You may (against our _preference_) also use the Ruby 1.8 license terms
 which we inherited from the original Mongrel project when we forked it:
diff --git a/Links b/Links
index 475a6c0..baba9c7 100644
--- a/Links
+++ b/Links
@@ -10,7 +10,7 @@ The unicorn project is not responsible for the content in these links.
 Furthermore, the unicorn project has never, does not and will never endorse:
 
 * any for-profit entities or services
-* any non-{Free Software}[http://www.gnu.org/philosophy/free-sw.html]
+* any non-{Free Software}[https://www.gnu.org/philosophy/free-sw.html]
 
 The existence of these links does not imply endorsement of any entities
 or services behind them.
@@ -31,25 +31,25 @@ or services behind them.
 
 === unicorn is written to work with
 
-* {Rack}[http://rack.github.io/] - a minimal interface between webservers
+* {Rack}[https://rack.github.io/] - a minimal interface between webservers
   supporting Ruby and Ruby frameworks
 
 * {Ruby}[https://www.ruby-lang.org/en/] - the programming language of
   Rack and unicorn
 
-* {nginx}[http://nginx.org/] (Free versions) -
+* {nginx}[https://nginx.org/] (Free versions) -
   the reverse proxy for use with unicorn
 
 === Derivatives
 
-* {Green Unicorn}[http://gunicorn.org/] - a Python version of unicorn
+* {Green Unicorn}[https://gunicorn.org/] - a Python version of unicorn
 
-* {Starman}[http://search.cpan.org/dist/Starman/] - Plack/PSGI version
+* {Starman}[https://metacpan.org/release/Starman/] - Plack/PSGI version
   of unicorn
 
 === Prior Work
 
-* {Mongrel}[http://rubygems.org/gems/mongrel] - the awesome webserver
+* {Mongrel}[https://rubygems.org/gems/mongrel] - the awesome webserver
   unicorn is based on
 
 * {david}[https://bogomips.org/david.git] - a tool to explain why you need
diff --git a/README b/README
index 29e04b4..5e5ccf7 100644
--- a/README
+++ b/README
@@ -10,7 +10,7 @@ both the the request and response in between unicorn and slow clients.
 
 * Designed for Rack, Unix, fast clients, and ease-of-debugging.  We
   cut out everything that is better supported by the operating system,
-  {nginx}[http://nginx.org/] or {Rack}[http://rack.github.io/].
+  {nginx}[https://nginx.org/] or {Rack}[https://rack.github.io/].
 
 * Compatible with Ruby 1.9.3 and later.
   unicorn 4.x remains supported for Ruby 1.8 users.
@@ -77,13 +77,13 @@ You may install it via RubyGems on RubyGems.org:
 You can get the latest source via git from the following locations
 (these versions may not be stable):
 
-  git://bogomips.org/unicorn.git
-  git://repo.or.cz/unicorn.git (mirror)
+  https://bogomips.org/unicorn.git
+  https://repo.or.cz/unicorn.git (mirror)
 
 You may browse the code from the web:
 
 * https://bogomips.org/unicorn.git
-* http://repo.or.cz/w/unicorn.git (gitweb)
+* https://repo.or.cz/w/unicorn.git (gitweb)
 
 See the HACKING guide on how to contribute and build prerelease gems
 from git.
diff --git a/Sandbox b/Sandbox
index e10b36d..d0f915e 100644
--- a/Sandbox
+++ b/Sandbox
@@ -3,7 +3,7 @@
 Since unicorn includes executables and is usually used to start a Ruby
 process, there are certain caveats to using it with tools that sandbox
 RubyGems installations such as
-{Bundler}[http://bundler.io/] or
+{Bundler}[https://bundler.io/] or
 {Isolate}[https://github.com/jbarnette/isolate].
 
 == General deployment
@@ -66,7 +66,7 @@ before_exec hook as illustrated by https://gist.github.com/534668
 Ruby 2.0.0 enforces FD_CLOEXEC on file descriptors by default.  unicorn
 has been prepared for this behavior since unicorn 4.1.0, and bundler
 needs the "--keep-file-descriptors" option for "bundle exec":
-http://bundler.io/man/bundle-exec.1.html
+https://bundler.io/man/bundle-exec.1.html
 
 == Isolate
 
diff --git a/examples/logrotate.conf b/examples/logrotate.conf
index 437f6c6..77a01b5 100644
--- a/examples/logrotate.conf
+++ b/examples/logrotate.conf
@@ -2,7 +2,7 @@
 # /etc/logrotate.d/unicorn_app on my Debian systems
 #
 # See the logrotate(8) manpage for more information:
-#    http://linux.die.net/man/8/logrotate
+#    https://linux.die.net/man/8/logrotate
 #
 # public logrotate-related discussion in our archives:
 #    https://bogomips.org/unicorn-public/?q=logrotate
diff --git a/examples/nginx.conf b/examples/nginx.conf
index e25712f..b6b69c1 100644
--- a/examples/nginx.conf
+++ b/examples/nginx.conf
@@ -56,7 +56,8 @@ http {
   # to configure it all in one place here for static files and also
   # to disable gzip for clients who don't get gzip/deflate right.
   # There are other gzip settings that may be needed used to deal with
-  # bad clients out there, see http://wiki.nginx.org/NginxHttpGzipModule
+  # bad clients out there, see
+  # https://nginx.org/en/docs/http/ngx_http_gzip_module.html
   gzip on;
   gzip_http_version 1.0;
   gzip_proxied any;
@@ -117,7 +118,7 @@ http {
 
     location @app {
       # an HTTP header important enough to have its own Wikipedia entry:
-      #   http://en.wikipedia.org/wiki/X-Forwarded-For
+      #   https://en.wikipedia.org/wiki/X-Forwarded-For
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
       # enable this if you forward HTTPS traffic to unicorn,
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index d426edf..e8b76f5 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -238,7 +238,7 @@ def before_exec(*args, &block)
   #      server 192.168.0.9:8080 fail_timeout=0;
   #    }
   #
-  # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html
+  # See https://nginx.org/en/docs/http/ngx_http_upstream_module.html
   # for more details on nginx upstream configuration.
   def timeout(seconds)
     set_int(:timeout, seconds, 3)
diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb
index 8bb884b..bcc1f2d 100644
--- a/lib/unicorn/http_request.rb
+++ b/lib/unicorn/http_request.rb
@@ -65,7 +65,7 @@ def read(socket)
     clear
     e = env
 
-    # From http://www.ietf.org/rfc/rfc3875:
+    # From https://www.ietf.org/rfc/rfc3875:
     # "Script authors should be aware that the REMOTE_ADDR and
     #  REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
     #  may not identify the ultimate source of the request.  They
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 62f6171..5334fa0 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -84,7 +84,7 @@ def initialize(app, options = {})
     # * The master process never closes or reinitializes this once
     # initialized.  Signal handlers in the master process will write to
     # it to wake up the master from IO.select in exactly the same manner
-    # djb describes in http://cr.yp.to/docs/selfpipe.html
+    # djb describes in https://cr.yp.to/docs/selfpipe.html
     #
     # * The workers immediately close the pipe they inherit.  See the
     # Unicorn::Worker class for the pipe workers use.
diff --git a/lib/unicorn/util.rb b/lib/unicorn/util.rb
index 501930c..b826de4 100644
--- a/lib/unicorn/util.rb
+++ b/lib/unicorn/util.rb
@@ -64,7 +64,7 @@ def self.reopen_logs
           fp.reopen(fp.path, "a")
         else
           # We should not need this workaround, Ruby can be fixed:
-          #    http://bugs.ruby-lang.org/issues/9036
+          #    https://bugs.ruby-lang.org/issues/9036
           # MRI will not call call fclose(3) or freopen(3) here
           # since there's no associated std{in,out,err} FILE * pointer
           # This should atomically use dup3(2) (or dup2(2)) syscall
diff --git a/t/README b/t/README
index bcaf3ce..0d9b697 100644
--- a/t/README
+++ b/t/README
@@ -10,17 +10,17 @@ comfortable writing integration tests with.
 
 == Requirements
 
-* {Ruby 1.9.3+}[https://www.ruby-lang.org/] (duh!)
-* {GNU make}[http://www.gnu.org/software/make/]
+* {Ruby 1.9.3+}[https://www.ruby-lang.org/en/] (duh!)
+* {GNU make}[https://www.gnu.org/software/make/]
 * {socat}[http://www.dest-unreach.org/socat/]
-* {curl}[http://curl.haxx.se/]
+* {curl}[https://curl.haxx.se/]
 * standard UNIX shell utilities (Bourne sh, awk, sed, grep, ...)
 
 We do not use bashisms or any non-portable, non-POSIX constructs
 in our shell code.  We use the "pipefail" option if available and
 mainly test with {ksh}[http://kornshell.com/], but occasionally
 with {dash}[http://gondor.apana.org.au/~herbert/dash/] and
-{bash}[http://www.gnu.org/software/bash/], too.
+{bash}[https://www.gnu.org/software/bash/], too.
 
 == Running Tests
 
-- 
EW


^ permalink raw reply related	[relevance 20%]

* [ANN] unicorn 5.4.0 - Rack HTTP server for fast clients and Unix
@ 2017-12-23 23:42  5% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2017-12-23 23:42 UTC (permalink / raw)
  To: ruby-talk, unicorn-public; +Cc: James P Robinson Jr, Sam Saffron

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

* https://bogomips.org/unicorn/
* public list: unicorn-public@bogomips.org
* mail archives: https://bogomips.org/unicorn-public/
* git clone git://bogomips.org/unicorn.git
* https://bogomips.org/unicorn/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

Changes:

Rack hijack support improves as the app code can capture and use
the Rack `env' privately without copying it (to avoid clobbering
by another client).  Thanks to Sam Saffron for reporting and
testing this new feature:
  https://bogomips.org/unicorn-public/CAAtdryPG3nLuyo0jxfYW1YHu1Q+ZpkLkd4KdWC8vA46B5haZxw@mail.gmail.com/T/

We also now support $DEBUG being set by the Rack app (instead of
relying on the "-d" CLI switch).  Thanks to James P Robinson Jr
for reporting this bug:
  https://bogomips.org/unicorn-public/D6324CB4.7BC3E%25james.robinson3@cigna.com/T/
  (Coincidentally, this fix will be irrelevant for Ruby 2.5
   which requires 'pp' by default)

There's a few minor test cleanups and documentation updates, too.

All commits since v5.3.1 (2017-10-03):

    reduce method calls with String#start_with?
    require 'pp' if $DEBUG is set by Rack app
    avoid reusing env on hijack
    tests: cleanup some unused variable warnings
    ISSUES: add a note about Debian BTS interopability

Roughly all mailing discussions since the last release:

  https://bogomips.org/unicorn-public/?q=d:20171004..20171223

^ permalink raw reply	[relevance 5%]

* [ANN] unicorn 5.3.0 - Rack HTTP server for fast clients and Unix
@ 2017-04-01  8:08  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2017-04-01  8:08 UTC (permalink / raw)
  To: ruby-talk, unicorn-public
  Cc: Jeremy Evans, Simon Eskildsen, Dylan Thacker-Smith

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

* https://bogomips.org/unicorn/
* public list: unicorn-public@bogomips.org
* mail archives: https://bogomips.org/unicorn-public/
* git clone git://bogomips.org/unicorn.git
* https://bogomips.org/unicorn/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

Changes:

unicorn 5.3.0

A couple of portability fixes from Dylan Thacker-Smith and
Jeremy Evans since 5.3.0.pre1 over a week ago, but this looks
ready for a stable release, today.

When I started this over 8 years ago, I wondered if this would
just end up being an April Fools' joke.  Guess not.  I guess I
somehow tricked people into using a terribly marketed web server
that cannot talk directly to untrusted clients :x  Anyways,
unicorn won't be able to handle slow clients 8 years from now,
either, or 80 years from now.  And I vow never to learn to use
new-fangled things like epoll, kqueue, or threads :P

Anyways, this is a largish release with several new features,
and no backwards incompatibilities.

Simon Eskildsen contributed heavily using TCP_INFO under Linux
to implement the (now 5 year old) check_client_connection feature:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-check_client_connection
  https://bogomips.org/unicorn-public/?q=s:check_client_connection&d:..20170401&x=t

This also led to FreeBSD and OpenBSD portability improvements in
one of our dependencies, raindrops:

   https://bogomips.org/raindrops-public/20170323024829.GA5190@dcvr/T/#u

Jeremy Evans contributed several new features.  First he
implemented after_worker_exit to aid debugging:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-after_worker_exit
  https://bogomips.org/unicorn-public/?q=s:after_worker_exit&d:..20170401&x=t#t

And then security-related features to isolate workers.  Workers
may now chroot to drop access to the master filesystem, and the
new after_worker_ready configuration hook now exists to aid with
chroot support in workers:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-after_worker_ready
  https://bogomips.org/unicorn/Unicorn/Worker.html#method-i-user
  https://bogomips.org/unicorn-public/?q=s:after_worker_ready&d:..20170401&x=t#t
  https://bogomips.org/unicorn-public/?q=s:chroot&d:..20170401&x=t#t

Additionally, workers may run in a completely different VM space
(nullifying preload_app and any CoW savings) with the new
worker_exec option:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-worker_exec
  https://bogomips.org/unicorn-public/?q=s:worker_exec&d:..20170401&x=t#t

There are also several improvements to FreeBSD and OpenBSD
support with the addition of these features.

shortlog of changes since v5.2.0 (2016-10-31):

Dylan Thacker-Smith (1):
      Check for Socket::TCP_INFO constant before trying to get TCP_INFO

Eric Wong (30):
      drop rb_str_set_len compatibility replacement
      TUNING: document THP caveat for Linux users
      tee_input: simplify condition for IO#write
      remove response_start_sent
      http_request: freeze constant strings passed IO#write
      Revert "remove response_start_sent"
      t/t0012-reload-empty-config.sh: access ivars directly if needed
      t0011-active-unix-socket.sh: fix race condition in test
      new test for check_client_connection
      revert signature change to HttpServer#process_client
      support "struct tcp_info" on non-Linux and Ruby 2.2+
      unicorn_http: reduce rb_global_variable calls
      oob_gc: rely on opt_aref_with optimization on Ruby 2.2+
      http_request: reduce insn size for check_client_connection
      freebsd: avoid EINVAL when setting accept filter
      test-lib: expr(1) portability fix
      tests: keep disabled tests defined
      test_exec: SO_KEEPALIVE value only needs to be true
      doc: fix links to raindrops project
      http_request: support proposed Raindrops::TCP states on non-Linux
      ISSUES: expand on mail archive info + subscription disclaimer
      test_ccc: use a pipe to synchronize test
      doc: remove private email support address
      input: update documentation and hide internals.
      http_server: initialize @pid ivar
      gemspec: remove olddoc from build dependency
      doc: add version annotations for new features
      unicorn 5.3.0.pre1
      doc: note after_worker_exit is also 5.3.0+
      test_exec: SO_KEEPALIVE value only needs to be true (take #2)

Jeremy Evans (7):
      Add after_worker_exit configuration option
      Fix code example in after_worker_exit documentation
      Add support for chroot to Worker#user
      Add after_worker_ready configuration option
      Add worker_exec configuration option
      Don't pass a block for fork when forking workers
      Check for SocketError on first ccc attempt

Simon Eskildsen (1):
      check_client_connection: use tcp state on linux

-- 
Yes, this release is real despite the date.

^ permalink raw reply	[relevance 6%]

* [ANN] unicorn 5.3.0.pre1 - Rack HTTP server for fast clients and Unix
@ 2017-03-24  0:28  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2017-03-24  0:28 UTC (permalink / raw)
  To: ruby-talk, unicorn-public; +Cc: Jeremy Evans, Simon Eskildsen

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

* https://bogomips.org/unicorn/
* public list: unicorn-public@bogomips.org
* mail archives: https://bogomips.org/unicorn-public/
* git clone git://bogomips.org/unicorn.git
* https://bogomips.org/unicorn/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

This is a pre-release RubyGem intended for testing.

Changes:

unicorn 5.3.0.pre1

A largish release with several new features.

Simon Eskildsen contributed heavily using TCP_INFO under Linux
to implement the (now 5 year old) check_client_connection feature:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-check_client_connection
  https://bogomips.org/unicorn-public/?q=s:check_client_connection&d:..20170324&x=t

This also led to FreeBSD and OpenBSD portability improvements in
one of our dependencies, raindrops:

  https://bogomips.org/raindrops-public/20170323024829.GA5190@dcvr/T/#u

Jeremy Evans contributed several new features.  First he
implemented after_worker_exit to aid debugging:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-after_worker_exit
  https://bogomips.org/unicorn-public/?q=s:after_worker_exit&d:..20170324&x=t#t

And then security-related features to isolate workers.  Workers
may now chroot to drop access to the master filesystem, and the
new after_worker_ready configuration hook now exists to aid with
chroot support in workers:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-after_worker_ready
  https://bogomips.org/unicorn/Unicorn/Worker.html#method-i-user
  https://bogomips.org/unicorn-public/?q=s:after_worker_ready&d:..20170324&x=t#t
  https://bogomips.org/unicorn-public/?q=s:chroot&d:..20170324&x=t#t

Additionally, workers may run in a completely different VM space
(nullifying preload_app and any CoW savings) with the new
worker_exec option:

  https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-worker_exec
  https://bogomips.org/unicorn-public/?q=s:worker_exec&d:..20170324&x=t#t

There are also several improvements to FreeBSD and OpenBSD
support with the addition of these features.

34 changes since 5.2.0 (2016-10-31):

Eric Wong (27):
      drop rb_str_set_len compatibility replacement
      TUNING: document THP caveat for Linux users
      tee_input: simplify condition for IO#write
      remove response_start_sent
      http_request: freeze constant strings passed IO#write
      Revert "remove response_start_sent"
      t/t0012-reload-empty-config.sh: access ivars directly if needed
      t0011-active-unix-socket.sh: fix race condition in test
      new test for check_client_connection
      revert signature change to HttpServer#process_client
      support "struct tcp_info" on non-Linux and Ruby 2.2+
      unicorn_http: reduce rb_global_variable calls
      oob_gc: rely on opt_aref_with optimization on Ruby 2.2+
      http_request: reduce insn size for check_client_connection
      freebsd: avoid EINVAL when setting accept filter
      test-lib: expr(1) portability fix
      tests: keep disabled tests defined
      test_exec: SO_KEEPALIVE value only needs to be true
      doc: fix links to raindrops project
      http_request: support proposed Raindrops::TCP states on non-Linux
      ISSUES: expand on mail archive info + subscription disclaimer
      test_ccc: use a pipe to synchronize test
      doc: remove private email support address
      input: update documentation and hide internals.
      http_server: initialize @pid ivar
      gemspec: remove olddoc from build dependency
      doc: add version annotations for new features

Jeremy Evans (6):
      Add after_worker_exit configuration option
      Fix code example in after_worker_exit documentation
      Add support for chroot to Worker#user
      Add after_worker_ready configuration option
      Add worker_exec configuration option
      Don't pass a block for fork when forking workers

Simon Eskildsen (1):
      check_client_connection: use tcp state on linux

-- 
5.3.0 in a week, maybe?

^ permalink raw reply	[relevance 6%]

* [ANN] raindrops 0.18.0 - real-time stats for preforking Rack servers
@ 2017-03-23  2:48  8% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2017-03-23  2:48 UTC (permalink / raw)
  To: ruby-talk, raindrops-public; +Cc: unicorn-public, Simon Eskildsen, Jeremy Evans

raindrops is a real-time stats toolkit to show statistics for Rack HTTP
servers.  It is designed for preforking servers such as unicorn, but
should support any Rack HTTP server on platforms supporting POSIX shared
memory.  It may also be used as a generic scoreboard for sharing atomic
counters across multiple processes.

* https://bogomips.org/raindrops/
* No subscription necessary, no HTML mail:
  raindrops-public@bogomips.org
* mail archives: https://bogomips.org/raindrops-public/
  http://ou63pmih66umazou.onion/raindrops-public/
  nntp://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
  nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.raindrops
* git clone git://bogomips.org/raindrops.git
* https://bogomips.org/raindrops/NEWS.atom.xml
* Demo site: https://raindrops-demo.bogomips.org:8443/

Changes:

    raindrops 0.18.0
    
    The most notable feature of this release is the addition of
    FreeBSD and OpenBSD TCP_INFO support.  This includes the
    Raindrops::TCP for portably mapping TCP state names to
    platform-dependent numeric values:
    
      https://bogomips.org/raindrops/Raindrops.html#TCP
    
    Thanks to Jeremy Evans and Simon Eskildsen on the
    unicorn-public@bogomips.org mailing list for inspiring
    these changes to raindrops.
    
    There's also a few internal cleanups, and documentation
    improvements, including some fixes to the largely-forgotten
    Raindrops::Aggreage::PMQ class:
    
      https://bogomips.org/raindrops/Raindrops/Aggregate/PMQ.html
    
    20 changes since 0.17.0:
    
          test_inet_diag_socket: fix Fixnum deprecation warning
          TODO: add item for IPv6 breakage
          ext: fix documentation for C ext-defined classes
          TCP_Info: custom documentation for #get!
          TypedData C-API conversion
          test_watcher: disable test correctly when aggregate is missing
          tcp_info: support this struct under FreeBSD
          define Raindrops::TCP hash for TCP states
          linux_inet_diag: reduce stack usage and simplify
          avoid reading errno repeatedly
          aggregate/pmq: avoid false sharing of lock buffers
          aggregate/pmq: remove io-extra requirement
          aggregate/pmq: avoid File#stat allocation
          Merge remote-tracking branch 'origin/freebsd'
          Merge remote-tracking branch 'origin/aggregate-pmq'
          doc: remove private email support address
          doc: update location of TCP_INFO-related stuff
          build: avoid olddoc for building the RubyGem
          doc: document Raindrops::TCP hash
          aggregate/pmq: update version numbers for Ruby and Linux

^ permalink raw reply	[relevance 8%]

* [PATCH] input: update documentation and hide internals.
@ 2017-03-20 20:08 13% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2017-03-20 20:08 UTC (permalink / raw)
  To: unicorn-public

rack 2.x exists nowadays still allows rewindable input as an
option, and we will still enable it by default to avoid breaking
any existing code.

Hide the internal documentation since we do not want people
depending on unicorn internals; so there's no reason to confuse
or overwhelm people with documentation about it.  Arguably,
TeeInput and StreamInput should not be documented publically at
all, but I guess that ship has long sailed...
---
 lib/unicorn/configurator.rb | 13 ++++++-------
 lib/unicorn/stream_input.rb |  9 +++++----
 lib/unicorn/tee_input.rb    | 14 +++++++-------
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 7ed5ffa..9f7f56f 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -55,7 +55,7 @@ class Unicorn::Configurator
     :pid => nil,
     :preload_app => false,
     :check_client_connection => false,
-    :rewindable_input => true, # for Rack 2.x: (Rack::VERSION[0] <= 1),
+    :rewindable_input => true,
     :client_body_buffer_size => Unicorn::Const::MAX_BODY,
   }
   #:startdoc:
@@ -505,13 +505,12 @@ def preload_app(bool)
   # Disabling rewindability can improve performance by lowering
   # I/O and memory usage for applications that accept uploads.
   # Keep in mind that the Rack 1.x spec requires
-  # \env[\"rack.input\"] to be rewindable, so this allows
-  # intentionally violating the current Rack 1.x spec.
+  # \env[\"rack.input\"] to be rewindable,
+  # but the Rack 2.x spec does not.
   #
-  # +rewindable_input+ defaults to +true+ when used with Rack 1.x for
-  # Rack conformance.  When Rack 2.x is finalized, this will most
-  # likely default to +false+ while still conforming to the newer
-  # (less demanding) spec.
+  # +rewindable_input+ defaults to +true+ for compatibility.
+  # Setting it to +false+ may be safe for applications and
+  # frameworks developed for Rack 2.x and later.
   def rewindable_input(bool)
     set_bool(:rewindable_input, bool)
   end
diff --git a/lib/unicorn/stream_input.rb b/lib/unicorn/stream_input.rb
index de5aeea..41d28a0 100644
--- a/lib/unicorn/stream_input.rb
+++ b/lib/unicorn/stream_input.rb
@@ -1,16 +1,17 @@
 # -*- encoding: binary -*-
 
-# When processing uploads, Unicorn may expose a StreamInput object under
-# "rack.input" of the (future) Rack (2.x) environment.
+# When processing uploads, unicorn may expose a StreamInput object under
+# "rack.input" of the Rack environment when
+# Unicorn::Configurator#rewindable_input is set to +false+
 class Unicorn::StreamInput
   # The I/O chunk size (in +bytes+) for I/O operations where
   # the size cannot be user-specified when a method is called.
   # The default is 16 kilobytes.
-  @@io_chunk_size = Unicorn::Const::CHUNK_SIZE
+  @@io_chunk_size = Unicorn::Const::CHUNK_SIZE # :nodoc:
 
   # Initializes a new StreamInput object.  You normally do not have to call
   # this unless you are writing an HTTP server.
-  def initialize(socket, request)
+  def initialize(socket, request) # :nodoc:
     @chunked = request.content_length.nil?
     @socket = socket
     @parser = request
diff --git a/lib/unicorn/tee_input.rb b/lib/unicorn/tee_input.rb
index 6f66162..2ccc2d9 100644
--- a/lib/unicorn/tee_input.rb
+++ b/lib/unicorn/tee_input.rb
@@ -1,6 +1,6 @@
 # -*- encoding: binary -*-
 
-# acts like tee(1) on an input input to provide a input-like stream
+# Acts like tee(1) on an input input to provide a input-like stream
 # while providing rewindable semantics through a File/StringIO backing
 # store.  On the first pass, the input is only read on demand so your
 # Rack application can use input notification (upload progress and
@@ -9,22 +9,22 @@
 # strict interpretation of Rack::Lint::InputWrapper functionality and
 # will not support any deviations from it.
 #
-# When processing uploads, Unicorn exposes a TeeInput object under
-# "rack.input" of the Rack environment.
+# When processing uploads, unicorn exposes a TeeInput object under
+# "rack.input" of the Rack environment by default.
 class Unicorn::TeeInput < Unicorn::StreamInput
   # The maximum size (in +bytes+) to buffer in memory before
   # resorting to a temporary file.  Default is 112 kilobytes.
-  @@client_body_buffer_size = Unicorn::Const::MAX_BODY
+  @@client_body_buffer_size = Unicorn::Const::MAX_BODY # :nodoc:
 
   # sets the maximum size of request bodies to buffer in memory,
   # amounts larger than this are buffered to the filesystem
-  def self.client_body_buffer_size=(bytes)
+  def self.client_body_buffer_size=(bytes) # :nodoc:
     @@client_body_buffer_size = bytes
   end
 
   # returns the maximum size of request bodies to buffer in memory,
   # amounts larger than this are buffered to the filesystem
-  def self.client_body_buffer_size
+  def self.client_body_buffer_size # :nodoc:
     @@client_body_buffer_size
   end
 
@@ -37,7 +37,7 @@ def new_tmpio # :nodoc:
 
   # Initializes a new TeeInput object.  You normally do not have to call
   # this unless you are writing an HTTP server.
-  def initialize(socket, request)
+  def initialize(socket, request) # :nodoc:
     @len = request.content_length
     super
     @tmp = @len && @len <= @@client_body_buffer_size ?
-- 
EW


^ permalink raw reply related	[relevance 13%]

* [PATCH] doc: add version annotations for new features
  @ 2017-03-08  7:44  6%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2017-03-08  7:44 UTC (permalink / raw)
  To: Jeremy Evans; +Cc: unicorn-public

I suppose this is a good idea, too.

Will merge before the 5.3.0 RCs and release (soonish, I think...)

-------8<--------
Subject: [PATCH] doc: add version annotations for new features

We will inevitably have people running old unicorn versions
for many years to come; but they may be reading the latest
documentation online.

Annotate when the new features (will) appear to avoid misleading
users on old versions.
---
 lib/unicorn/configurator.rb | 2 ++
 lib/unicorn/worker.rb       | 5 ++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 7ed5ffa..3eb8c22 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -186,6 +186,8 @@ def after_worker_exit(*args, &block)
   #
   # Do not use Configurator#user if you rely on changing users in the
   # after_worker_ready hook.
+  #
+  # after_worker_ready is only available in unicorn 5.3.0+
   def after_worker_ready(*args, &block)
     set_hook(:after_worker_ready, block_given? ? block : args[0])
   end
diff --git a/lib/unicorn/worker.rb b/lib/unicorn/worker.rb
index e22c1bf..2f5b6a6 100644
--- a/lib/unicorn/worker.rb
+++ b/lib/unicorn/worker.rb
@@ -124,7 +124,10 @@ def close # :nodoc:
   # Any and all errors raised within this method will be propagated
   # directly back to the caller (usually the +after_fork+ hook.
   # These errors commonly include ArgumentError for specifying an
-  # invalid user/group and Errno::EPERM for insufficient privileges
+  # invalid user/group and Errno::EPERM for insufficient privileges.
+  #
+  # chroot support is only available in unicorn 5.3.0+
+  # user and group switching appeared in unicorn 0.94.0 (2009-11-05)
   def user(user, group = nil, chroot = false)
     # we do not protect the caller, checking Process.euid == 0 is
     # insufficient because modern systems have fine-grained
-- 
EW

^ permalink raw reply related	[relevance 6%]

* Re: [PATCH] check_client_connection: use tcp state on linux
  2017-03-01  3:18 10%         ` Eric Wong
@ 2017-03-06 21:32  0%           ` Simon Eskildsen
  0 siblings, 0 replies; 200+ results
From: Simon Eskildsen @ 2017-03-06 21:32 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

Here's another update Eric!

* Use a frozen empty array and a class variable for TCP_Info to avoid
garbage. As far as I can tell, this shouldn't result in any garbage on
any requests (other than on the first request).
* Pass listener socket to #read to only check the client connection on
a TCP server.
* Short circuit CLOSE_WAIT after ESTABLISHED since in my testing it's
the most common state after ESTABLISHED, it makes the numbers
un-ordered, though. But comment should make it OK.
* Definition of of `check_client_connection` based on whether
Raindrops::TCP_Info is defined, instead of the class variable
approach.
* Changed the unit tests to pass a `nil` listener.

Tested on our staging environment, and still works like a dream.

I should note that I got the idea between this patch into Puma as well!

https://github.com/puma/puma/pull/1227


---
 lib/unicorn/http_request.rb | 44 ++++++++++++++++++++++++++++++++++++++------
 lib/unicorn/http_server.rb  |  6 +++---
 test/unit/test_request.rb   | 28 ++++++++++++++--------------
 3 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb
index 0c1f9bb..21a99ef 100644
--- a/lib/unicorn/http_request.rb
+++ b/lib/unicorn/http_request.rb
@@ -2,6 +2,7 @@
 # :enddoc:
 # no stable API here
 require 'unicorn_http'
+require 'raindrops'

 # TODO: remove redundant names
 Unicorn.const_set(:HttpRequest, Unicorn::HttpParser)
@@ -28,6 +29,7 @@ class Unicorn::HttpParser
   # Drop these frozen strings when Ruby 2.2 becomes more prevalent,
   # 2.2+ optimizes hash assignments when used with literal string keys
   HTTP_RESPONSE_START = [ 'HTTP', '/1.1 ']
+  EMPTY_ARRAY = [].freeze
   @@input_class = Unicorn::TeeInput
   @@check_client_connection = false

@@ -62,7 +64,7 @@ def self.check_client_connection=(bool)
   # returns an environment hash suitable for Rack if successful
   # This does minimal exception trapping and it is up to the caller
   # to handle any socket errors (e.g. user aborted upload).
-  def read(socket)
+  def read(socket, listener)
     clear
     e = env

@@ -83,11 +85,7 @@ def read(socket)
       false until add_parse(socket.kgio_read!(16384))
     end

-    # detect if the socket is valid by writing a partial response:
-    if @@check_client_connection && headers?
-      self.response_start_sent = true
-      HTTP_RESPONSE_START.each { |c| socket.write(c) }
-    end
+    check_client_connection(socket, listener) if @@check_client_connection

     e['rack.input'] = 0 == content_length ?
                       NULL_IO : @@input_class.new(socket, self)
@@ -108,4 +106,38 @@ def call
   def hijacked?
     env.include?('rack.hijack_io'.freeze)
   end
+
+  if defined?(Raindrops::TCP_Info)
+    def check_client_connection(socket, listener) # :nodoc:
+      if Kgio::TCPServer === listener
+        @@tcp_info ||= Raindrops::TCP_Info.new(socket)
+        @@tcp_info.get!(socket)
+        raise Errno::EPIPE, "client closed connection".freeze,
EMPTY_ARRAY if closed_state?(@@tcp_info.state)
+      else
+        write_http_header(socket)
+      end
+    end
+
+    def closed_state?(state) # :nodoc:
+      case state
+      when 1 # ESTABLISHED
+        false
+      when 8, 6, 7, 9, 11 # CLOSE_WAIT, TIME_WAIT, CLOSE, LAST_ACK, CLOSING
+        true
+      else
+        false
+      end
+    end
+  else
+    def check_client_connection(socket, listener) # :nodoc:
+      write_http_header(socket)
+    end
+  end
+
+  def write_http_header(socket) # :nodoc:
+    if headers?
+      self.response_start_sent = true
+      HTTP_RESPONSE_START.each { |c| socket.write(c) }
+    end
+  end
 end
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 35bd100..4190641 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -558,8 +558,8 @@ def e100_response_write(client, env)

   # once a client is accepted, it is processed in its entirety here
   # in 3 easy steps: read request, call app, write app response
-  def process_client(client)
-    status, headers, body = @app.call(env = @request.read(client))
+  def process_client(client, listener)
+    status, headers, body = @app.call(env = @request.read(client, listener))

     begin
       return if @request.hijacked?
@@ -655,7 +655,7 @@ def worker_loop(worker)
         # Unicorn::Worker#kgio_tryaccept is not like accept(2) at all,
         # but that will return false
         if client = sock.kgio_tryaccept
-          process_client(client)
+          process_client(client, sock)
           nr += 1
           worker.tick = time_now.to_i
         end
diff --git a/test/unit/test_request.rb b/test/unit/test_request.rb
index f0ccaf7..dbe8af7 100644
--- a/test/unit/test_request.rb
+++ b/test/unit/test_request.rb
@@ -30,7 +30,7 @@ def setup
   def test_options
     client = MockRequest.new("OPTIONS * HTTP/1.1\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal '', env['REQUEST_PATH']
     assert_equal '', env['PATH_INFO']
     assert_equal '*', env['REQUEST_URI']
@@ -40,7 +40,7 @@ def test_options
   def test_absolute_uri_with_query
     client = MockRequest.new("GET http://e:3/x?y=z HTTP/1.1\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal '/x', env['REQUEST_PATH']
     assert_equal '/x', env['PATH_INFO']
     assert_equal 'y=z', env['QUERY_STRING']
@@ -50,7 +50,7 @@ def test_absolute_uri_with_query
   def test_absolute_uri_with_fragment
     client = MockRequest.new("GET http://e:3/x#frag HTTP/1.1\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal '/x', env['REQUEST_PATH']
     assert_equal '/x', env['PATH_INFO']
     assert_equal '', env['QUERY_STRING']
@@ -61,7 +61,7 @@ def test_absolute_uri_with_fragment
   def test_absolute_uri_with_query_and_fragment
     client = MockRequest.new("GET http://e:3/x?a=b#frag HTTP/1.1\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal '/x', env['REQUEST_PATH']
     assert_equal '/x', env['PATH_INFO']
     assert_equal 'a=b', env['QUERY_STRING']
@@ -73,7 +73,7 @@ def test_absolute_uri_unsupported_schemes
     %w(ssh+http://e/ ftp://e/x http+ssh://e/x).each do |abs_uri|
       client = MockRequest.new("GET #{abs_uri} HTTP/1.1\r\n" \
                                "Host: foo\r\n\r\n")
-      assert_raises(HttpParserError) { @request.read(client) }
+      assert_raises(HttpParserError) { @request.read(client, nil) }
     end
   end

@@ -81,7 +81,7 @@ def test_x_forwarded_proto_https
     client = MockRequest.new("GET / HTTP/1.1\r\n" \
                              "X-Forwarded-Proto: https\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal "https", env['rack.url_scheme']
     res = @lint.call(env)
   end
@@ -90,7 +90,7 @@ def test_x_forwarded_proto_http
     client = MockRequest.new("GET / HTTP/1.1\r\n" \
                              "X-Forwarded-Proto: http\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal "http", env['rack.url_scheme']
     res = @lint.call(env)
   end
@@ -99,14 +99,14 @@ def test_x_forwarded_proto_invalid
     client = MockRequest.new("GET / HTTP/1.1\r\n" \
                              "X-Forwarded-Proto: ftp\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal "http", env['rack.url_scheme']
     res = @lint.call(env)
   end

   def test_rack_lint_get
     client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal "http", env['rack.url_scheme']
     assert_equal '127.0.0.1', env['REMOTE_ADDR']
     res = @lint.call(env)
@@ -114,7 +114,7 @@ def test_rack_lint_get

   def test_no_content_stringio
     client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal StringIO, env['rack.input'].class
   end

@@ -122,7 +122,7 @@ def test_zero_content_stringio
     client = MockRequest.new("PUT / HTTP/1.1\r\n" \
                              "Content-Length: 0\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal StringIO, env['rack.input'].class
   end

@@ -130,7 +130,7 @@ def test_real_content_not_stringio
     client = MockRequest.new("PUT / HTTP/1.1\r\n" \
                              "Content-Length: 1\r\n" \
                              "Host: foo\r\n\r\n")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert_equal Unicorn::TeeInput, env['rack.input'].class
   end

@@ -141,7 +141,7 @@ def test_rack_lint_put
       "Content-Length: 5\r\n" \
       "\r\n" \
       "abcde")
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert ! env.include?(:http_body)
     res = @lint.call(env)
   end
@@ -167,7 +167,7 @@ def client.kgio_read!(*args)
       "\r\n")
     count.times { assert_equal bs, client.syswrite(buf) }
     assert_equal 0, client.sysseek(0)
-    env = @request.read(client)
+    env = @request.read(client, nil)
     assert ! env.include?(:http_body)
     assert_equal length, env['rack.input'].size
     count.times {
-- 
2.11.0

On Tue, Feb 28, 2017 at 10:18 PM, Eric Wong <e@80x24.org> wrote:
>> Simon Eskildsen <simon.eskildsen@shopify.com> wrote:
>> > +      tcp_info = Raindrops::TCP_Info.new(socket)
>> > +      raise Errno::EPIPE, "client closed connection".freeze, [] if
>> > closed_state?(tcp_info.state)
>
> Also, I guess if you're using this frequently, it might make
> sense to keep the tcp_info object around and recycle it
> using the Raindrops::TCP_Info#get! method.
>
> #get! has always been supported in raindrops, but I just noticed
> RDoc wasn't picking it up properly :x
>
> Anyways I've fixed the documentation over on the raindrops list
>
>   https://bogomips.org/raindrops-public/20170301025541.26183-1-e@80x24.org/
>   ("[PATCH] ext: fix documentation for C ext-defined classes")
>
>   https://bogomips.org/raindrops-public/20170301025546.26233-1-e@80x24.org/
>   ("[PATCH] TCP_Info: custom documentation for #get!")
>
> ... and updated the RDoc on https://bogomips.org/raindrops/
>
> Heck, I wonder if it even makes sense to reuse a frozen empty
> Array when raising the exception...

^ permalink raw reply related	[relevance 0%]

* Re: [PATCH] check_client_connection: use tcp state on linux
  @ 2017-03-01  3:18 10%         ` Eric Wong
  2017-03-06 21:32  0%           ` Simon Eskildsen
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2017-03-01  3:18 UTC (permalink / raw)
  To: Simon Eskildsen; +Cc: unicorn-public

> Simon Eskildsen <simon.eskildsen@shopify.com> wrote:
> > +      tcp_info = Raindrops::TCP_Info.new(socket)
> > +      raise Errno::EPIPE, "client closed connection".freeze, [] if
> > closed_state?(tcp_info.state)

Also, I guess if you're using this frequently, it might make
sense to keep the tcp_info object around and recycle it
using the Raindrops::TCP_Info#get! method.

#get! has always been supported in raindrops, but I just noticed
RDoc wasn't picking it up properly :x

Anyways I've fixed the documentation over on the raindrops list

  https://bogomips.org/raindrops-public/20170301025541.26183-1-e@80x24.org/
  ("[PATCH] ext: fix documentation for C ext-defined classes")

  https://bogomips.org/raindrops-public/20170301025546.26233-1-e@80x24.org/
  ("[PATCH] TCP_Info: custom documentation for #get!")

... and updated the RDoc on https://bogomips.org/raindrops/

Heck, I wonder if it even makes sense to reuse a frozen empty
Array when raising the exception...

^ permalink raw reply	[relevance 10%]

* Re: Patch: Add after_worker_ready configuration option V2
  2017-02-23 18:49  4% Patch: Add after_worker_ready configuration option V2 Jeremy Evans
@ 2017-02-23 20:29  7% ` Eric Wong
    0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2017-02-23 20:29 UTC (permalink / raw)
  To: Jeremy Evans; +Cc: unicorn-public

Jeremy Evans <code@jeremyevans.net> wrote:
> Here's V2 of the after_worker_ready patch.  This adds some more
> documentation, and tries to give a better description of the
> advantages in the commit message.

Thanks, I've pushed this and the chroot patch out to the
'chroot' branch.  Willl wait a bit for comments from others
before merging into 'master'.

The following changes since commit c8f06be298d667ba85573668ee916680a258c2c7:

  Fix code example in after_worker_exit documentation (2017-02-23 19:26:30 +0000)

are available in the git repository at:

  git://bogomips.org/unicorn chroot

for you to fetch changes up to d322345251e15125df896bb8f0a5b53b49a1bf3f:

  Add after_worker_ready configuration option (2017-02-23 20:23:44 +0000)

----------------------------------------------------------------
Jeremy Evans (2):
      Add support for chroot to Worker#user
      Add after_worker_ready configuration option

 lib/unicorn/configurator.rb | 22 ++++++++++++++++++++++
 lib/unicorn/http_server.rb  |  4 ++--
 lib/unicorn/worker.rb       | 13 ++++++++++---
 3 files changed, 34 insertions(+), 5 deletions(-)

^ permalink raw reply	[relevance 7%]

* Re: Patch: Fix code example in after_worker_exit documentation
  2017-02-23 18:48 21% Patch: Fix code example in after_worker_exit documentation Jeremy Evans
@ 2017-02-23 20:21 12% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2017-02-23 20:21 UTC (permalink / raw)
  To: Jeremy Evans; +Cc: unicorn-public

Jeremy Evans <code@jeremyevans.net> wrote:
> Here's a separate commit for the documentation fix.

Thanks, pushed as c8f06be298d667ba85573668ee916680a258c2c7
to 'master'.  I added a "Fixes: " tag to link it the original.

> From 6efb4b8e07a0459180579b72fac5003e424837c0 Mon Sep 17 00:00:00 2001

Hint: you can omit the above line, and add "----8<----" so the
applier can use "git am --scissors" without having to just part
of the message.  It's no big deal, but I guess I'll do what I
can to promote --scissors as it's not too well-known.
(and usually, the entire email is the patch for "git am")

^ permalink raw reply	[relevance 12%]

* Re: Patch: Add after_worker_ready configuration option
  2017-02-23  9:23  5%     ` Eric Wong
@ 2017-02-23 20:00  0%       ` Jeremy Evans
  0 siblings, 0 replies; 200+ results
From: Jeremy Evans @ 2017-02-23 20:00 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

On 02/23 09:23, Eric Wong wrote:
> Jeremy Evans <code@jeremyevans.net> wrote:
> > On 02/23 02:32, Eric Wong wrote:
> > > Jeremy Evans <code@jeremyevans.net> wrote:
> > > Anyways, I'm somewhat inclined to accept this as well, but will
> > > think about it a bit, too.
> > > 
> > > One problem I have with this change is that it requires users
> > > read more documentation and know more caveats to use.
> >  
> > It's unfortunate, but I think it's necessary in this case. Unicorn's
> > default behavior works for most users, but this makes it so you
> > don't have to override HttpServer#init_worker_process to get similar
> > functionality.
> 
> Yeah.  Unfortunately, with every option comes more
> support/maintenance overhead.  So I'm trying to make sure we've
> explored every possible avenue before adding this new option.

I agree.  If I knew of a way to get this functionality without
overriding a private method, I would use it.  I'm not sure there is a
way currently, which I why I worked on the patch.

> > >     So I'm wondering if there can be some of that which could be
> > >     trimmed out someday or made optional, somehow.
> > 
> > I'm not sure how open you are to a plugin-like system for Unicorn, where
> > you can have separate files for separate features, and users can choose
> > which features the want to use.  This limits memory usage so that you
> > don't pay a memory cost for features you don't use.  This is the
> > approach used by Sequel, Roda, and Rodauth (other libraries I maintain),
> > and if you are interested in a similar system for Unicorn, I would be
> > happy to work on one.
> 
> Not really.  As I've stated many times in the past, unicorn is
> just one of many servers available for Rack users; so I've been
> against people building too many dependencies on unicorn, that
> comes at the expense of other servers.
 
True, but there are features that only unicorn provides.  If you want
those features, you have to use unicorn anyway. 

> What I had in mind was having a shim process which does socket
> setup, user switching, etc. before exec-ing unicorn in cases
> where a systemd-like spawner is not used.  But it's probably too
> small to make an impact on real apps anyways, since Ruby still
> has tons of methods which never get called, either.

I could see that decreasing memory usage slightly, but I agree it's
unlikely to make a significant impact.

> > I do have a couple of additional patches I plan to send, but I think it
> > may be better to ask here first.
> > 
> > One is that SIGUSR1 handling doesn't work well with chroot if the log
> > file is outside of the chroot, since the worker process may not have
> > access to reopen the file.  One simple fix is to reopen the logs in
> > the master process, then send SIGQUIT instead of SIGUSR1 to the child
> > processes.  Are you open to a patch that does that?
> 
> Right now, the worker exits with some log spew if reopening
> logs fails, and the worker respawns anyways, correct?
> 
> Perhaps that mapping can be made automatic if chroot is
> enabled.  I wonder if that's too much magic...
> Or the log spew could be suppressed when the error
> is ENOENT and chroot is enabled.
> 
> The sysadmin could also send SIGHUP to reload everything
> and respawn all children.
> 
> So, I'm wondering if using SIGHUP is too much of a burden, or if
> automatic USR1 => QUIT mapping for chroot users is too magical.

SIGHUP is actually fine.  I didn't realize it reopened log files
in the master process, but apparently it does, so I can just use
SIGHUP instead of SIGUSR1.

> > The second feature is more exotic security feature called fork+exec.
> > The current issue with unicorn's direct forking of children is that
> > forked children share the memory layout of the server.  This is good
> > from a memory usage standpoint due to CoW memory.  However, if there
> > is a memory vulnerability in the unicorn application, this makes it
> > easier to exploit, since if the a unicorn worker process crashes, the
> > master process will fork a child with pretty much the same memory
> > layout.  This allows address space discovery attacks.  Using fork+exec,
> > each child process would have a unique address space for ASLR, on
> > most Unix-like systems (Linux, MacOS X, NetBSD, OpenBSD, Solaris).
> > There are additional security advantages from fork+exec on OpenBSD, but
> > all Unix-like systems that use ASLR can benefit from the unique
> > memory layout per process.
> 
> It depends how intrusive the implementation is...

That I don't know yet.  I haven't implemented fork+exec before, so I'm
not sure how many changes are needed. I probably won't be able to work
on this right away.

> Is this merely calling exec in the worker?
> 
> I'm not sure if your use of "fork+exec" is merely the two
> well-known syscalls combined, or if there's something else;
> I'll assume the former, since that's enough to have a
> unique address space for Ruby bytecode.
> 
> Can this be done in an after_fork/after_worker_ready hook?
> 
> Socket inheritance can be done the same way it handles USR2
> upgrades and systemd socket inheritance.

I expect in addition to socket inheritance, we will need to handle pipe
inheritance for the @to_io and @master pipes in the worker.

Thanks,
Jeremy

^ permalink raw reply	[relevance 0%]

* Patch: Add after_worker_ready configuration option V2
@ 2017-02-23 18:49  4% Jeremy Evans
  2017-02-23 20:29  7% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Jeremy Evans @ 2017-02-23 18:49 UTC (permalink / raw)
  To: unicorn-public

Here's V2 of the after_worker_ready patch.  This adds some more
documentation, and tries to give a better description of the
advantages in the commit message.

From cbc6fe845ade8946b7db2ecd2b86a0bd8e18bbb8 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@jeremyevans.net>
Date: Tue, 21 Feb 2017 16:33:09 -0800
Subject: [PATCH] Add after_worker_ready configuration option

This adds a hook that is called after the application has
been loaded by the worker process, directly before it starts
accepting requests.  This hook is necessary if your application
needs to gain access to resources during initialization,
and then drop privileges before serving requests.

This is especially useful in conjunction with chroot support
so the app can load all the normal ruby libraries it needs
to function, and then chroot before accepting requests.

If you are preloading the app, it's possible to drop privileges
or chroot in after_fork, but if you are not preloading the app,
the only way to currently do this is to override the private
HttpServer#init_worker_process method, and overriding private
methods is a recipe for future breakage if the internals are
modified.  This hook allows for such functionality to be
supported and not break in future versions of Unicorn.
---
 lib/unicorn/configurator.rb | 22 ++++++++++++++++++++++
 lib/unicorn/http_server.rb  |  4 ++--
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 1e2b6e4..7ed5ffa 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -49,6 +49,9 @@ class Unicorn::Configurator
           server.logger.error(m)
         end
       },
+    :after_worker_ready => lambda { |server, worker|
+        server.logger.info("worker=#{worker.nr} ready")
+      },
     :pid => nil,
     :preload_app => false,
     :check_client_connection => false,
@@ -172,6 +175,21 @@ def after_worker_exit(*args, &block)
     set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
   end
 
+  # sets after_worker_ready hook to a given block.  This block will be called
+  # by a worker process after it has been fully loaded, directly before it
+  # starts responding to requests:
+  #
+  #  after_worker_ready do |server,worker|
+  #    server.logger.info("worker #{worker.nr} ready, dropping privileges")
+  #    worker.user('username', 'groupname')
+  #  end
+  #
+  # Do not use Configurator#user if you rely on changing users in the
+  # after_worker_ready hook.
+  def after_worker_ready(*args, &block)
+    set_hook(:after_worker_ready, block_given? ? block : args[0])
+  end
+
   # sets before_fork got be a given Proc object.  This Proc
   # object will be called by the master process before forking
   # each worker.
@@ -569,6 +587,10 @@ def working_directory(path)
   # This switch will occur after calling the after_fork hook, and only
   # if the Worker#user method is not called in the after_fork hook
   # +group+ is optional and will not change if unspecified.
+  #
+  # Do not use Configurator#user if you rely on changing users in the
+  # after_worker_ready hook.  Instead, you need to call Worker#user
+  # directly in after_worker_ready.
   def user(user, group = nil)
     # raises ArgumentError on invalid user/group
     Etc.getpwnam(user)
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index c2086cb..ef897ad 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -15,7 +15,7 @@ class Unicorn::HttpServer
                 :before_fork, :after_fork, :before_exec,
                 :listener_opts, :preload_app,
                 :orig_app, :config, :ready_pipe, :user
-  attr_writer   :after_worker_exit
+  attr_writer   :after_worker_exit, :after_worker_ready
 
   attr_reader :pid, :logger
   include Unicorn::SocketHelper
@@ -644,7 +644,7 @@ def worker_loop(worker)
     trap(:USR1) { nr = -65536 }
 
     ready = readers.dup
-    @logger.info "worker=#{worker.nr} ready"
+    @after_worker_ready.call(self, worker)
 
     begin
       nr < 0 and reopen_worker_logs(worker.nr)
-- 
2.11.0


^ permalink raw reply related	[relevance 4%]

* Patch: Fix code example in after_worker_exit documentation
@ 2017-02-23 18:48 21% Jeremy Evans
  2017-02-23 20:21 12% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Jeremy Evans @ 2017-02-23 18:48 UTC (permalink / raw)
  To: unicorn-public

Here's a separate commit for the documentation fix.

From 6efb4b8e07a0459180579b72fac5003e424837c0 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@jeremyevans.net>
Date: Thu, 23 Feb 2017 10:17:19 -0800
Subject: [PATCH] Fix code example in after_worker_exit documentation

---
 lib/unicorn/configurator.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 5bad925..1e2b6e4 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -162,7 +162,7 @@ def after_fork(*args, &block)
   # sets after_worker_exit hook to a given block.  This block will be called
   # by the master process after a worker exits:
   #
-  #  after_fork do |server,worker,status|
+  #  after_worker_exit do |server,worker,status|
   #    # status is a Process::Status instance for the exited worker process
   #    unless status.success?
   #      server.logger.error("worker process failure: #{status.inspect}")
-- 
2.11.0


^ permalink raw reply related	[relevance 21%]

* Re: Patch: Add after_worker_ready configuration option
  2017-02-23  3:43  6%   ` Jeremy Evans
@ 2017-02-23  9:23  5%     ` Eric Wong
  2017-02-23 20:00  0%       ` Jeremy Evans
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2017-02-23  9:23 UTC (permalink / raw)
  To: Jeremy Evans; +Cc: unicorn-public

Jeremy Evans <code@jeremyevans.net> wrote:

<snip> acknowledging everything above.

> On 02/23 02:32, Eric Wong wrote:
> > Jeremy Evans <code@jeremyevans.net> wrote:
> > Anyways, I'm somewhat inclined to accept this as well, but will
> > think about it a bit, too.
> > 
> > One problem I have with this change is that it requires users
> > read more documentation and know more caveats to use.
>  
> It's unfortunate, but I think it's necessary in this case. Unicorn's
> default behavior works for most users, but this makes it so you
> don't have to override HttpServer#init_worker_process to get similar
> functionality.

Yeah.  Unfortunately, with every option comes more
support/maintenance overhead.  So I'm trying to make sure we've
explored every possible avenue before adding this new option.

<snip>

> > (*) Fwiw, I wasn't thrilled to add user switching to unicorn back
> >     in 2009/2010, as it should not need to run privileged ports.
> 
> I think had you not added it, there wouldn't be a need for a chroot
> patch, since otherwise one would assume any user that wanted to
> drop privileges would just run the necessary code themselves.
> 
> One thing to keep in mind is that if you did not add the user switching
> code, developers who need it would implement it themselves, and would
> likely miss things like initgroups.

Heh.  As I was mentioning above, every feature can come with
new, unintended consequences :>  But yeah, maybe push things
up to Ruby stdlib, or systemd...

> >     So I'm wondering if there can be some of that which could be
> >     trimmed out someday or made optional, somehow.
> 
> I'm not sure how open you are to a plugin-like system for Unicorn, where
> you can have separate files for separate features, and users can choose
> which features the want to use.  This limits memory usage so that you
> don't pay a memory cost for features you don't use.  This is the
> approach used by Sequel, Roda, and Rodauth (other libraries I maintain),
> and if you are interested in a similar system for Unicorn, I would be
> happy to work on one.

Not really.  As I've stated many times in the past, unicorn is
just one of many servers available for Rack users; so I've been
against people building too many dependencies on unicorn, that
comes at the expense of other servers.

What I had in mind was having a shim process which does socket
setup, user switching, etc. before exec-ing unicorn in cases
where a systemd-like spawner is not used.  But it's probably too
small to make an impact on real apps anyways, since Ruby still
has tons of methods which never get called, either.

> I do have a couple of additional patches I plan to send, but I think it
> may be better to ask here first.
> 
> One is that SIGUSR1 handling doesn't work well with chroot if the log
> file is outside of the chroot, since the worker process may not have
> access to reopen the file.  One simple fix is to reopen the logs in
> the master process, then send SIGQUIT instead of SIGUSR1 to the child
> processes.  Are you open to a patch that does that?

Right now, the worker exits with some log spew if reopening
logs fails, and the worker respawns anyways, correct?

Perhaps that mapping can be made automatic if chroot is
enabled.  I wonder if that's too much magic...
Or the log spew could be suppressed when the error
is ENOENT and chroot is enabled.

The sysadmin could also send SIGHUP to reload everything
and respawn all children.

So, I'm wondering if using SIGHUP is too much of a burden, or if
automatic USR1 => QUIT mapping for chroot users is too magical.

(trying to avoid adding more options + documentation, as always :)

> The second feature is more exotic security feature called fork+exec.
> The current issue with unicorn's direct forking of children is that
> forked children share the memory layout of the server.  This is good
> from a memory usage standpoint due to CoW memory.  However, if there
> is a memory vulnerability in the unicorn application, this makes it
> easier to exploit, since if the a unicorn worker process crashes, the
> master process will fork a child with pretty much the same memory
> layout.  This allows address space discovery attacks.  Using fork+exec,
> each child process would have a unique address space for ASLR, on
> most Unix-like systems (Linux, MacOS X, NetBSD, OpenBSD, Solaris).
> There are additional security advantages from fork+exec on OpenBSD, but
> all Unix-like systems that use ASLR can benefit from the unique
> memory layout per process.

It depends how intrusive the implementation is...

Is this merely calling exec in the worker?

I'm not sure if your use of "fork+exec" is merely the two
well-known syscalls combined, or if there's something else;
I'll assume the former, since that's enough to have a
unique address space for Ruby bytecode.

Can this be done in an after_fork/after_worker_ready hook?

Socket inheritance can be done the same way it handles USR2
upgrades and systemd socket inheritance.

^ permalink raw reply	[relevance 5%]

* Re: Patch: Add after_worker_ready configuration option
  2017-02-23  2:32  9% ` Eric Wong
@ 2017-02-23  3:43  6%   ` Jeremy Evans
  2017-02-23  9:23  5%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Jeremy Evans @ 2017-02-23  3:43 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

On 02/23 02:32, Eric Wong wrote:
> Jeremy Evans <code@jeremyevans.net> wrote:
> > This adds a hook that is called after the application has
> > been loaded by the worker process, directly before it starts
> > accepting requests.  This hook is necessary if your application
> > needs to get gain access to resources during initialization,
> > and then drop privileges before serving requests.
> > 
> > This is especially useful in conjunction with chroot support
> > so the app can load all the normal ruby libraries it needs
> > to function, and then chroot before accepting requests.
> > 
> > If you are preloading the app, it's possible to drop privileges
> > or chroot in after_fork, but if you are not preloading the app,
> > there is not currently a properly place to handle this, hence
> > the reason for this feature.
> 
> This means using Unicorn::Worker#user directly,
> and not Unicorn::Configurator#user.  OK...

Correct.  We could add configuration support to specify when to call
Worker#user, but that seems like overkill.
 
> Also, were you planning to send a v2 for chroot support?
> I'm fine with either.

Sorry about that, I will send a v2 for chroot support tomorrow.

> 
> > --- a/lib/unicorn/configurator.rb
> > +++ b/lib/unicorn/configurator.rb
> 
> > @@ -162,7 +165,7 @@ def after_fork(*args, &block)
> >    # sets after_worker_exit hook to a given block.  This block will be called
> >    # by the master process after a worker exits:
> >    #
> > -  #  after_fork do |server,worker,status|
> > +  #  after_worker_exit do |server,worker,status|
> >    #    # status is a Process::Status instance for the exited worker process
> >    #    unless status.success?
> >    #      server.logger.error("worker process failure: #{status.inspect}")
> 
> This looks like an unrelated hunk which belongs in a separate
> patch.  I can squeeze in a separate fix for this (credited to
> you) or you can send a separate patch.
 
Correct, this was an unrelated bug in my last patch.  I'll separate this
hunk into a separate patch.

> > @@ -172,6 +175,18 @@ def after_worker_exit(*args, &block)
> >      set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
> >    end
> >  
> > +  # sets after_worker_ready hook to a given block.  This block will be called
> > +  # by a worker process after it has been fully loaded, directly before it
> > +  # starts responding to requests:
> > +  #
> > +  #  after_worker_ready do |server,worker|
> > +  #    server.logger.info("worker #{worker.nr} ready, dropping privileges")
> > +  #    worker.user('username', 'groupname')
> > +  #  end
> 
> The documentation should probably say something along the lines
> of:
> 
>     Do not use Unicorn::Configurator#user if you rely on
>     changing users in the after_worker_ready hook.
> 
> And maybe corresponding documentation for Unicorn::Configurator#user,
> too.

OK, I'll update the documentation to be more complete.

> Anyways, I'm somewhat inclined to accept this as well, but will
> think about it a bit, too.
> 
> One problem I have with this change is that it requires users
> read more documentation and know more caveats to use.
 
It's unfortunate, but I think it's necessary in this case. Unicorn's
default behavior works for most users, but this makes it so you
don't have to override HttpServer#init_worker_process to get similar
functionality.

> Adding to that, Unicorn::Configurator#user has been favored
> (documentation-wise) over Unicorn::Worker#user in the past;
> so it's a bit of a reversal(*)

I think Configurator#user still makes sense for most users.  As the
documentation mentions, directly calling Worker#user should only
be done if Configurator#user is not sufficient.

> Based on the series of changes you're making, I'm sensing you're
> working on some complex system which might need more security
> than a typical app.

These patches are related to all applications using Unicorn that I run
on OpenBSD (about 20 separate applications).  They are designed to
to reduce the attack surface if an attacker is able to find a
remote code execution vulnerability in one of the applications.

In addition to chroot(2), after chrooting, these applications also
use pledge(2), which is an OpenBSD-specific system call filter
(similar in principle to seccomp(2) in Linux).

> I know you use OpenBSD, and I don't know much about the init
> system or how deployment works, there.
 
It's a very simple sh(1) based-init system, similar to traditional Unix.
Most OpenBSD system daemons will start as root, chroot to a specific
directory, drop privileges (possibly separate privileges in separate
daemon processes connected via IPC), and finally use pledge(2) to limit
what each process can actually use in terms of system calls.

> Nowadays, it seems more common things (binding sockets,
> switching users, chrooting, etc..) is handled by init systems
> (at least systemd); and having that functionality in unicorn
> would mean redundant bloat.

I believe only Linux uses a systemd-like approach, and while most
Linux systems use systemd these days, usage is not universal
(notable exceptions are Slackware, Void, and Gentoo).  But my
knowledge of other operating systems is not very broad.

> It would be useful to me and folks who won't use these features
> to understand how and why they're used.  That can help justify
> the (admittedly small) memory overhead which comes with it.

True.  I'm sorry the commit messages didn't provide a more thorough
explanation.  I will try to improve that in the future.

> (*) Fwiw, I wasn't thrilled to add user switching to unicorn back
>     in 2009/2010, as it should not need to run privileged ports.

I think had you not added it, there wouldn't be a need for a chroot
patch, since otherwise one would assume any user that wanted to
drop privileges would just run the necessary code themselves.

One thing to keep in mind is that if you did not add the user switching
code, developers who need it would implement it themselves, and would
likely miss things like initgroups.

>     So I'm wondering if there can be some of that which could be
>     trimmed out someday or made optional, somehow.

I'm not sure how open you are to a plugin-like system for Unicorn, where
you can have separate files for separate features, and users can choose
which features the want to use.  This limits memory usage so that you
don't pay a memory cost for features you don't use.  This is the
approach used by Sequel, Roda, and Rodauth (other libraries I maintain),
and if you are interested in a similar system for Unicorn, I would be
happy to work on one.

I do have a couple of additional patches I plan to send, but I think it
may be better to ask here first.

One is that SIGUSR1 handling doesn't work well with chroot if the log
file is outside of the chroot, since the worker process may not have
access to reopen the file.  One simple fix is to reopen the logs in
the master process, then send SIGQUIT instead of SIGUSR1 to the child
processes.  Are you open to a patch that does that?

The second feature is more exotic security feature called fork+exec.
The current issue with unicorn's direct forking of children is that
forked children share the memory layout of the server.  This is good
from a memory usage standpoint due to CoW memory.  However, if there
is a memory vulnerability in the unicorn application, this makes it
easier to exploit, since if the a unicorn worker process crashes, the
master process will fork a child with pretty much the same memory
layout.  This allows address space discovery attacks.  Using fork+exec,
each child process would have a unique address space for ASLR, on
most Unix-like systems (Linux, MacOS X, NetBSD, OpenBSD, Solaris).
There are additional security advantages from fork+exec on OpenBSD, but
all Unix-like systems that use ASLR can benefit from the unique
memory layout per process.

Thanks,
Jeremy

^ permalink raw reply	[relevance 6%]

* Re: Patch: Add after_worker_ready configuration option
  @ 2017-02-23  2:32  9% ` Eric Wong
  2017-02-23  3:43  6%   ` Jeremy Evans
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2017-02-23  2:32 UTC (permalink / raw)
  To: Jeremy Evans; +Cc: unicorn-public

Jeremy Evans <code@jeremyevans.net> wrote:
> This adds a hook that is called after the application has
> been loaded by the worker process, directly before it starts
> accepting requests.  This hook is necessary if your application
> needs to get gain access to resources during initialization,
> and then drop privileges before serving requests.
> 
> This is especially useful in conjunction with chroot support
> so the app can load all the normal ruby libraries it needs
> to function, and then chroot before accepting requests.
> 
> If you are preloading the app, it's possible to drop privileges
> or chroot in after_fork, but if you are not preloading the app,
> there is not currently a properly place to handle this, hence
> the reason for this feature.

This means using Unicorn::Worker#user directly,
and not Unicorn::Configurator#user.  OK...

Also, were you planning to send a v2 for chroot support?
I'm fine with either.

> --- a/lib/unicorn/configurator.rb
> +++ b/lib/unicorn/configurator.rb

> @@ -162,7 +165,7 @@ def after_fork(*args, &block)
>    # sets after_worker_exit hook to a given block.  This block will be called
>    # by the master process after a worker exits:
>    #
> -  #  after_fork do |server,worker,status|
> +  #  after_worker_exit do |server,worker,status|
>    #    # status is a Process::Status instance for the exited worker process
>    #    unless status.success?
>    #      server.logger.error("worker process failure: #{status.inspect}")

This looks like an unrelated hunk which belongs in a separate
patch.  I can squeeze in a separate fix for this (credited to
you) or you can send a separate patch.

> @@ -172,6 +175,18 @@ def after_worker_exit(*args, &block)
>      set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
>    end
>  
> +  # sets after_worker_ready hook to a given block.  This block will be called
> +  # by a worker process after it has been fully loaded, directly before it
> +  # starts responding to requests:
> +  #
> +  #  after_worker_ready do |server,worker|
> +  #    server.logger.info("worker #{worker.nr} ready, dropping privileges")
> +  #    worker.user('username', 'groupname')
> +  #  end

The documentation should probably say something along the lines
of:

    Do not use Unicorn::Configurator#user if you rely on
    changing users in the after_worker_ready hook.

And maybe corresponding documentation for Unicorn::Configurator#user,
too.

Anyways, I'm somewhat inclined to accept this as well, but will
think about it a bit, too.

One problem I have with this change is that it requires users
read more documentation and know more caveats to use.

Adding to that, Unicorn::Configurator#user has been favored
(documentation-wise) over Unicorn::Worker#user in the past;
so it's a bit of a reversal(*)

Based on the series of changes you're making, I'm sensing you're
working on some complex system which might need more security
than a typical app.

I know you use OpenBSD, and I don't know much about the init
system or how deployment works, there.

Nowadays, it seems more common things (binding sockets,
switching users, chrooting, etc..) is handled by init systems
(at least systemd); and having that functionality in unicorn
would mean redundant bloat.

It would be useful to me and folks who won't use these features
to understand how and why they're used.  That can help justify
the (admittedly small) memory overhead which comes with it.

Thanks.


(*) Fwiw, I wasn't thrilled to add user switching to unicorn back
    in 2009/2010, as it should not need to run privileged ports.
    So I'm wondering if there can be some of that which could be
    trimmed out someday or made optional, somehow.

^ permalink raw reply	[relevance 9%]

* check_client_connection using getsockopt(2)
@ 2017-02-22 12:02  4% Simon Eskildsen
  0 siblings, 0 replies; 200+ results
From: Simon Eskildsen @ 2017-02-22 12:02 UTC (permalink / raw)
  To: unicorn-public

Hello!

Almost five years ago Tom Burns contributed the patch in collaboration
with Eric that introduced the `check_client_connection` configuration
option. To summarize the patch, it was a solution to a problem we have
of rapid refreshes during sales where Unicorn would render a page 5
times if an eager customer refreshed Shopify 5 times, despite only
seeing one-rendering.  This is a large amount of lost capacity. Four
of these connections would effectively be in a `CLOSE` state in the
backlog, get `accept(2)`ed and a response would be sent back only to
get an error that the client had closed its connection.

The patch solved this problem by instead of doing a single `write(2)`,
it would do a write of the generic HTTP version line, then jump into
the middleware stack and render the Rack response in a second write.
If the client had closed, the first `write(2)` of the HTTP version
header would usually throw an exception causing Unicorn to bail before
rendering the heavy Rack response. This saves a large amount of
capacity during spiky traffic.

A subsequent commit after testing by Eric revealed that:

> This only affects clients connecting over Unix domain sockets and TCP via loopback (127...*). It is unlikely to detect disconnects if the client is on a remote host (even on a fast LAN).

Thanks for that testing Eric. If we hadn't stumbled upon this in the
documentation proactively, this wouldn't have been easy to debug in
production.

In my testing, I can confirm Eric's tests. My testing essentially
consists of a snippet like the following to send rapid requests and
then closing the client. I've confirmed with Wireshark this is roughly
how popular browsers behave when refreshing fast on a slowly rendered
page:

100.times do |i|
  client = TCPSocket.new("some-unicorn", 20_000)
  client.write("GET /collections/#{rand(10000)}
HTTP/1.1\r\nHost:walrusser.myshopify.com\r\n\r\n")
  client.close
end

This confirms Eric's comment that the existing
`check_client_connection` works perfectly on loopback, but as soon as
you put an actual network between the Unicorn and client—it's only
effective 20% of the time, even with `TCP_NODELAY`. I'm assuming, due
to buffering, even when disabling Nagle's. As we're changing our
architecture, we move from ngx (lb) -> ngx (host) -> unicorn to ngx
(lb) -> unicorn. That means this patch will no longer work for us.

I propose instead of the early `write(2)` hack, that we use
`getsockopt(2)` with the `TCP_INFO` flag and read the state of the
socket. If it's in `CLOSE_WAIT` or `CLOSE`, we kill the connection and
move on to the next.

https://github.com/torvalds/linux/blob/8fa3b6f9392bf6d90cb7b908e07bd90166639f0a/include/uapi/linux/tcp.h#L163

This is not going to be portable, but we can do this on only Linux
which I suspect is where most production deployments of Unicorn that
would benefit from this feature run. It's not useful in development
(which is likely more common to not be Linux). We could also introduce
it under a new configuration option if desired. In my testing, this
works to reject 100% of requests early when not on loopback.

The code is essentially:

def client_closed?
  tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO)
  state = tcp_info.unpack("c")[0]
  state == TCP_CLOSE || state == TCP_CLOSE_WAIT
end

This could be called at the top of `#process_client` in `http_server.rb`.

Would there be interest in this upstream? Any comments on this
proposed implementation? Currently, we're using a middleware with the
Rack hijack API, but this seems like it belongs at the webserver
level.

^ permalink raw reply	[relevance 4%]

* Re: Patch: Add after_worker_exit configuration option
  2017-02-21 20:15  7%     ` Eric Wong
@ 2017-02-21 20:49  0%       ` Jeremy Evans
  0 siblings, 0 replies; 200+ results
From: Jeremy Evans @ 2017-02-21 20:49 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

On 02/21 08:15, Eric Wong wrote:
> Jeremy Evans <code@jeremyevans.net> wrote:
> > On 02/21 07:43, Eric Wong wrote:
> > > Jeremy Evans <code@jeremyevans.net> wrote:
> > > > This option can be used to implement custom behavior for handling
> > > > worker exits.  For example, let's say you have a specific request
> > > > that crashes a worker process, which you expect to be due to a
> > > > improperly programmed C extension. By modifying your worker to
> > > > save request related data in a temporary file and using this option,
> > > > you can get a record of what request is crashing the application,
> > > > which will make debugging easier.
> > > > 
> > > > This is not a complete patch as it doesn't include tests, but
> > > > before writing tests I wanted to see if this is something you'd
> > > > consider including in unicorn.
> > > 
> > > What advantage does this have over Ruby's builtin at_exit?
> > 
> > at_exit is not called if the interpreter crashes:
> > 
> > ruby -e 'at_exit{File.write('a.txt', 'a')}; Process.kill :SEGV, $$' 2>/dev/null
> > ([ -f a.txt ] && echo at_exit called) || echo at_exit not called
> 
> Ah, thanks.  I didn't read the code carefully, enough.
> The commit message and documentation should reflect that it's
> called in the master and not the worker.
> 
> Anyways, this is probably OK since I can't think of a less
> intrusive or more generic (across all Rack servers) way of doing
> it.  So I'm inclined to accept some version of this.
> 
> > --- a/lib/unicorn/http_server.rb
> > +++ b/lib/unicorn/http_server.rb
> > @@ -14,7 +14,8 @@ class Unicorn::HttpServer
> >    attr_accessor :app, :timeout, :worker_processes,
> >                  :before_fork, :after_fork, :before_exec,
> >                  :listener_opts, :preload_app,
> > -                :orig_app, :config, :ready_pipe, :user
> > +                :orig_app, :config, :ready_pipe, :user,
> > +                :after_worker_exit
> 
> I've been trying to reduce the method entry overhead across
> the board.  Since this is a new field, can it be attr_writer
> solely for configurator?
> 
> I don't think there's reader dependency other than below...
> 
> > @@ -395,8 +396,7 @@ def reap_all_workers
> >          proc_name 'master'
> >        else
> >          worker = @workers.delete(wpid) and worker.close rescue nil
> > -        m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}"
> > -        status.success? ? logger.info(m) : logger.error(m)
> > +        after_worker_exit.call(self, worker, status)
> 
> Which can be made to access the ivar directly:
> 
> 	   @after_worker_exit.call(self, worker, status)

Here's a revised patch that should address the issues you identified:

From 91b95652e4bdb7fc9af77e9ac06ad7400faef796 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@jeremyevans.net>
Date: Fri, 17 Feb 2017 16:12:33 -0800
Subject: [PATCH] Add after_worker_exit configuration option

This option is executed in the master process following all
worker process exits.  It is most useful in the case where
the worker process crashes the ruby interpreter, as the worker
process may not be able to send error notifications
appropriately.

For example, let's say you have a specific request that crashes a
worker process, which you expect to be due to a improperly
programmed C extension. By modifying your worker to save request
related data in a temporary file and using this option, you can get
a record of what request is crashing the application, which will
make debugging easier.

Example:

after_worker_exit do |server, worker, status|
  server.logger.info "worker #{status.success? ? 'exit' : 'crash'}: #{status}"

  file = "request.#{status.pid}.txt"
  if File.exist?(file)
    do_something_with(File.read(file)) unless status.success?
    File.delete(file)
  end
end
---
 lib/unicorn/configurator.rb | 21 +++++++++++++++++++++
 lib/unicorn/http_server.rb  |  4 ++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 3329c10..5bad925 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -41,6 +41,14 @@ class Unicorn::Configurator
     :before_exec => lambda { |server|
         server.logger.info("forked child re-executing...")
       },
+    :after_worker_exit => lambda { |server, worker, status|
+        m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}"
+        if status.success?
+          server.logger.info(m)
+        else
+          server.logger.error(m)
+        end
+      },
     :pid => nil,
     :preload_app => false,
     :check_client_connection => false,
@@ -151,6 +159,19 @@ def after_fork(*args, &block)
     set_hook(:after_fork, block_given? ? block : args[0])
   end
 
+  # sets after_worker_exit hook to a given block.  This block will be called
+  # by the master process after a worker exits:
+  #
+  #  after_fork do |server,worker,status|
+  #    # status is a Process::Status instance for the exited worker process
+  #    unless status.success?
+  #      server.logger.error("worker process failure: #{status.inspect}")
+  #    end
+  #  end
+  def after_worker_exit(*args, &block)
+    set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
+  end
+
   # sets before_fork got be a given Proc object.  This Proc
   # object will be called by the master process before forking
   # each worker.
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 35bd100..c2086cb 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -15,6 +15,7 @@ class Unicorn::HttpServer
                 :before_fork, :after_fork, :before_exec,
                 :listener_opts, :preload_app,
                 :orig_app, :config, :ready_pipe, :user
+  attr_writer   :after_worker_exit
 
   attr_reader :pid, :logger
   include Unicorn::SocketHelper
@@ -395,8 +396,7 @@ def reap_all_workers
         proc_name 'master'
       else
         worker = @workers.delete(wpid) and worker.close rescue nil
-        m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}"
-        status.success? ? logger.info(m) : logger.error(m)
+        @after_worker_exit.call(self, worker, status)
       end
     rescue Errno::ECHILD
       break
-- 
2.11.0


^ permalink raw reply related	[relevance 0%]

* Re: Patch: Add after_worker_exit configuration option
  @ 2017-02-21 20:15  7%     ` Eric Wong
  2017-02-21 20:49  0%       ` Jeremy Evans
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2017-02-21 20:15 UTC (permalink / raw)
  To: Jeremy Evans; +Cc: unicorn-public

Jeremy Evans <code@jeremyevans.net> wrote:
> On 02/21 07:43, Eric Wong wrote:
> > Jeremy Evans <code@jeremyevans.net> wrote:
> > > This option can be used to implement custom behavior for handling
> > > worker exits.  For example, let's say you have a specific request
> > > that crashes a worker process, which you expect to be due to a
> > > improperly programmed C extension. By modifying your worker to
> > > save request related data in a temporary file and using this option,
> > > you can get a record of what request is crashing the application,
> > > which will make debugging easier.
> > > 
> > > This is not a complete patch as it doesn't include tests, but
> > > before writing tests I wanted to see if this is something you'd
> > > consider including in unicorn.
> > 
> > What advantage does this have over Ruby's builtin at_exit?
> 
> at_exit is not called if the interpreter crashes:
> 
> ruby -e 'at_exit{File.write('a.txt', 'a')}; Process.kill :SEGV, $$' 2>/dev/null
> ([ -f a.txt ] && echo at_exit called) || echo at_exit not called

Ah, thanks.  I didn't read the code carefully, enough.
The commit message and documentation should reflect that it's
called in the master and not the worker.

Anyways, this is probably OK since I can't think of a less
intrusive or more generic (across all Rack servers) way of doing
it.  So I'm inclined to accept some version of this.

> --- a/lib/unicorn/http_server.rb
> +++ b/lib/unicorn/http_server.rb
> @@ -14,7 +14,8 @@ class Unicorn::HttpServer
>    attr_accessor :app, :timeout, :worker_processes,
>                  :before_fork, :after_fork, :before_exec,
>                  :listener_opts, :preload_app,
> -                :orig_app, :config, :ready_pipe, :user
> +                :orig_app, :config, :ready_pipe, :user,
> +                :after_worker_exit

I've been trying to reduce the method entry overhead across
the board.  Since this is a new field, can it be attr_writer
solely for configurator?

I don't think there's reader dependency other than below...

> @@ -395,8 +396,7 @@ def reap_all_workers
>          proc_name 'master'
>        else
>          worker = @workers.delete(wpid) and worker.close rescue nil
> -        m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}"
> -        status.success? ? logger.info(m) : logger.error(m)
> +        after_worker_exit.call(self, worker, status)

Which can be made to access the ivar directly:

	   @after_worker_exit.call(self, worker, status)

^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 5.2.0 - Rack HTTP server for fast clients and *nix
       [not found]     <20161031-unicorn-5.2.0-released@bogomips.org>
@ 2016-10-31 20:04  6% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2016-10-31 20:04 UTC (permalink / raw)
  To: ruby-talk, unicorn-public; +Cc: Mishael A Sibiryakov

unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

* https://bogomips.org/unicorn/
* public list: unicorn-public@bogomips.org
* mail archives: https://bogomips.org/unicorn-public/
* git clone git://bogomips.org/unicorn.git
* https://bogomips.org/unicorn/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

Changes:

    Most notably, this release allows us to support requests with
    lines delimited by LF-only, as opposed to the standard CRLF
    pair and allowed by RFC 2616 sec 19.3.

    Thanks to Mishael A Sibiryakov for the explanation and change:

      https://bogomips.org/unicorn-public/1476954332.1736.156.camel@junki.org/

    Thanks to Let's Encrypt, the website also moves to HTTPS
    <https://bogomips.org/unicorn/> to improve reader privacy.  The
    "unicorn.bogomips.org" subdomain will be retired soon to reduce
    subjectAltName bloat and speed up certificate renewals.

    There's also the usual round of documentation and example
    updates, too.

    Eric Wong (7):
          examples/init.sh: update to reduce upgrade raciness
          doc: systemd should only kill master in example
          examples/logrotate.conf: update example for systemd
          doc: update gmane URLs to point to our own archives
          relocate website to https://bogomips.org/unicorn/
          TODO: remove Rack 2.x item
          build: "install-gem" target avoids network

    Mishael A Sibiryakov (1):
          Add some tolerance (RFC2616 sec. 19.3)

^ permalink raw reply	[relevance 6%]

* [PATCH] relocate website to https://bogomips.org/unicorn/
@ 2016-10-25 22:25 42% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2016-10-25 22:25 UTC (permalink / raw)
  To: unicorn-public

HTTPS helps some with reader privacy and Let's Encrypt seems to
be working well enough the past few months.

This change will allow us to reduce subjectAltName bloat in our
TLS certificate over time.  It will also promote domain name
agility to support mirrors or migrations to other domains
(including a Tor hidden service mirror).

http://bogomips.org/unicorn/ will remain available for people on
legacy systems without usable TLS.  There is no plan for automatic
redirecting from HTTP to HTTPS at this time.
---

 I'm not sure when I'll remove "unicorn.bogomips.org"
 subjectAltName from the TLS certificate, yet, hopefully
 within a year; but maybe that's optimistic

 I never actually advertised the HTTPS site for this project
 before today, but search engines picked it up.  Oh well :<

 .olddoc.yml                       |  6 +++---
 Documentation/unicorn.1.txt       |  4 ++--
 Documentation/unicorn_rails.1.txt |  4 ++--
 GNUmakefile                       |  4 ++--
 HACKING                           |  2 +-
 ISSUES                            | 12 ++++++------
 Links                             |  4 ++--
 README                            |  4 ++--
 SIGNALS                           |  2 +-
 examples/big_app_gc.rb            |  2 +-
 examples/nginx.conf               |  2 +-
 examples/unicorn.conf.minimal.rb  |  4 ++--
 examples/unicorn.conf.rb          |  4 ++--
 lib/unicorn/configurator.rb       |  6 +++---
 lib/unicorn/http_server.rb        |  2 +-
 15 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/.olddoc.yml b/.olddoc.yml
index c4a9236..ee2d306 100644
--- a/.olddoc.yml
+++ b/.olddoc.yml
@@ -1,8 +1,8 @@
 ---
-cgit_url: http://bogomips.org/unicorn.git
+cgit_url: https://bogomips.org/unicorn.git
 git_url: git://bogomips.org/unicorn.git
-rdoc_url: http://unicorn.bogomips.org/
-ml_url: http://bogomips.org/unicorn-public/
+rdoc_url: https://bogomips.org/unicorn/
+ml_url: https://bogomips.org/unicorn-public/
 merge_html:
   unicorn_1: Documentation/unicorn.1.html
   unicorn_rails_1: Documentation/unicorn_rails.1.html
diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index 3f20a9a..e692078 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
@@ -181,7 +181,7 @@ the unicorn config file.
 * [Rack RDoc][2]
 * [Rackup HowTo][3]
 
-[1]: http://unicorn.bogomips.org/
+[1]: https://bogomips.org/unicorn/
 [2]: http://www.rubydoc.info/github/rack/rack/
 [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
-[4]: http://unicorn.bogomips.org/SIGNALS.html
+[4]: https://bogomips.org/unicorn/SIGNALS.html
diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt
index 2ce7501..088e2ff 100644
--- a/Documentation/unicorn_rails.1.txt
+++ b/Documentation/unicorn_rails.1.txt
@@ -169,7 +169,7 @@ used by Unicorn.
 * [Rack RDoc][2]
 * [Rackup HowTo][3]
 
-[1]: http://unicorn.bogomips.org/
+[1]: https://bogomips.org/unicorn/
 [2]: http://www.rubydoc.info/github/rack/rack/
 [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
-[4]: http://unicorn.bogomips.org/SIGNALS.html
+[4]: https://bogomips.org/unicorn/SIGNALS.html
diff --git a/GNUmakefile b/GNUmakefile
index 3f9c441..bc9c643 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -183,13 +183,13 @@ doc: .document $(ext)/unicorn_http.c man html .olddoc.yml $(PLACEHOLDERS)
 	install -m644 $(man1_paths) doc/
 	tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
 
-# publishes docs to http://unicorn.bogomips.org
+# publishes docs to https://bogomips.org/unicorn/
 publish_doc:
 	-git set-file-times
 	$(MAKE) doc
 	$(MAKE) doc_gz
 	chmod 644 $$(find doc -type f)
-	$(RSYNC) -av doc/ unicorn.bogomips.org:/srv/unicorn/
+	$(RSYNC) -av doc/ bogomips.org:/srv/bogomips/unicorn/
 	git ls-files | xargs touch
 
 # Create gzip variants of the same timestamp as the original so nginx
diff --git a/HACKING b/HACKING
index 0fa22cd..d55f1c7 100644
--- a/HACKING
+++ b/HACKING
@@ -57,7 +57,7 @@ Please wrap documentation at 72 characters-per-line or less (long URLs
 are exempt) so it is comfortably readable from terminals.
 
 When referencing mailing list posts, use
-<tt>http://bogomips.org/unicorn-public/$MESSAGE_ID/</tt> if possible
+<tt>https://bogomips.org/unicorn-public/$MESSAGE_ID/</tt> if possible
 since the Message-ID remains searchable even if a particular site
 becomes unavailable.
 
diff --git a/ISSUES b/ISSUES
index 21bd013..291441a 100644
--- a/ISSUES
+++ b/ISSUES
@@ -2,8 +2,8 @@
 
 mailto:unicorn-public@bogomips.org is the best place to report bugs,
 submit patches and/or obtain support after you have searched the
-{email archives}[http://bogomips.org/unicorn-public/] and
-{documentation}[http://unicorn.bogomips.org/].
+{email archives}[https://bogomips.org/unicorn-public/] and
+{documentation}[https://bogomips.org/unicorn/].
 
 * No subscription will ever be required to email us
 * Cc: all participants in a thread or commit, as subscription is optional
@@ -12,7 +12,7 @@ submit patches and/or obtain support after you have searched the
 * Do not send HTML mail or images, it will be flagged as spam
 * Anonymous and pseudonymous messages will always be welcome.
 * The email submission port (587) is enabled on the bogomips.org MX:
-  http://bogomips.org/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
+  https://bogomips.org/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
 
 If your issue is of a sensitive nature or you're just shy in public,
 then feel free to email us privately at mailto:unicorn@bogomips.org
@@ -67,7 +67,7 @@ document distributed with git) on guidelines for patch submission.
 * private: mailto:unicorn@bogomips.org
 * nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
 * nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
-* http://bogomips.org/unicorn-public/
+* https://bogomips.org/unicorn-public/
 
 Mailing list subscription is optional, so Cc: all participants.
 
@@ -78,9 +78,9 @@ You can follow along via NNTP:
 
 Or Atom feeds:
 
-	http://bogomips.org/unicorn-public/new.atom
+	https://bogomips.org/unicorn-public/new.atom
 
-	The HTML archives at http://bogomips.org/unicorn-public/
+	The HTML archives at https://bogomips.org/unicorn-public/
 	also has links to per-thread Atom feeds and downloadable
 	mboxes.
 
diff --git a/Links b/Links
index 6474a9d..7c113c8 100644
--- a/Links
+++ b/Links
@@ -26,7 +26,7 @@ or services behind them.
 * {raindrops}[http://raindrops.bogomips.org/] - real-time stats for
   preforking Rack servers
 
-* {UnXF}[http://bogomips.org/unxf/]  Un-X-Forward* the Rack environment,
+* {UnXF}[https://bogomips.org/unxf/]  Un-X-Forward* the Rack environment,
   useful since unicorn is designed to be deployed behind a reverse proxy.
 
 === unicorn is written to work with
@@ -52,5 +52,5 @@ or services behind them.
 * {Mongrel}[http://rubygems.org/gems/mongrel] - the awesome webserver
   unicorn is based on
 
-* {david}[http://bogomips.org/david.git] - a tool to explain why you need
+* {david}[https://bogomips.org/david.git] - a tool to explain why you need
   nginx in front of unicorn
diff --git a/README b/README
index 8079f37..29e04b4 100644
--- a/README
+++ b/README
@@ -82,7 +82,7 @@ You can get the latest source via git from the following locations
 
 You may browse the code from the web:
 
-* http://bogomips.org/unicorn.git
+* https://bogomips.org/unicorn.git
 * http://repo.or.cz/w/unicorn.git (gitweb)
 
 See the HACKING guide on how to contribute and build prerelease gems
@@ -128,7 +128,7 @@ All feedback (bug reports, user/development dicussion, patches, pull
 requests) go to the mailing list/newsgroup.  See the ISSUES document for
 information on the {mailing list}[mailto:unicorn-public@bogomips.org].
 
-The mailing list is archived at http://bogomips.org/unicorn-public/
+The mailing list is archived at https://bogomips.org/unicorn-public/
 Read-only NNTP access is available at:
 nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
 nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
diff --git a/SIGNALS b/SIGNALS
index 4d78065..1af851d 100644
--- a/SIGNALS
+++ b/SIGNALS
@@ -8,7 +8,7 @@ should be possible to easily share process management scripts between
 Unicorn and nginx.
 
 One example init script is distributed with unicorn:
-http://unicorn.bogomips.org/examples/init.sh
+https://bogomips.org/unicorn/examples/init.sh
 
 === Master Process
 
diff --git a/examples/big_app_gc.rb b/examples/big_app_gc.rb
index c4c8b04..9d05719 100644
--- a/examples/big_app_gc.rb
+++ b/examples/big_app_gc.rb
@@ -1,2 +1,2 @@
-# see {Unicorn::OobGC}[http://unicorn.bogomips.org/Unicorn/OobGC.html]
+# see {Unicorn::OobGC}[https://bogomips.org/unicorn/Unicorn/OobGC.html]
 # Unicorn::OobGC was broken in Unicorn v3.3.1 - v3.6.1 and fixed in v3.6.2
diff --git a/examples/nginx.conf b/examples/nginx.conf
index 0583c1f..e25712f 100644
--- a/examples/nginx.conf
+++ b/examples/nginx.conf
@@ -112,7 +112,7 @@ http {
     # try_files directive appeared in in nginx 0.7.27 and has stabilized
     # over time.  Older versions of nginx (e.g. 0.6.x) requires
     # "if (!-f $request_filename)" which was less efficient:
-    # http://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
+    # https://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
     try_files $uri/index.html $uri.html $uri @app;
 
     location @app {
diff --git a/examples/unicorn.conf.minimal.rb b/examples/unicorn.conf.minimal.rb
index 2a47910..2d1bf0a 100644
--- a/examples/unicorn.conf.minimal.rb
+++ b/examples/unicorn.conf.minimal.rb
@@ -1,9 +1,9 @@
 # Minimal sample configuration file for Unicorn (not Rack) when used
 # with daemonization (unicorn -D) started in your working directory.
 #
-# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
+# See https://bogomips.org/unicorn/Unicorn/Configurator.html for complete
 # documentation.
-# See also http://unicorn.bogomips.org/examples/unicorn.conf.rb for
+# See also https://bogomips.org/unicorn/examples/unicorn.conf.rb for
 # a more verbose configuration using more features.
 
 listen 2007 # by default Unicorn listens on port 8080
diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index 1e05cbb..d2897ef 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -2,10 +2,10 @@
 #
 # This configuration file documents many features of Unicorn
 # that may not be needed for some applications. See
-# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
+# https://bogomips.org/unicorn/examples/unicorn.conf.minimal.rb
 # for a much simpler configuration file.
 #
-# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
+# See https://bogomips.org/unicorn/Unicorn/Configurator.html for complete
 # documentation.
 
 # Use at least one worker per core if you're on a dedicated server,
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 948c6e3..3329c10 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -3,11 +3,11 @@
 
 # Implements a simple DSL for configuring a unicorn server.
 #
-# See http://unicorn.bogomips.org/examples/unicorn.conf.rb and
-# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
+# See https://bogomips.org/unicorn/examples/unicorn.conf.rb and
+# https://bogomips.org/unicorn/examples/unicorn.conf.minimal.rb
 # example configuration files.  An example config file for use with
 # nginx is also available at
-# http://unicorn.bogomips.org/examples/nginx.conf
+# https://bogomips.org/unicorn/examples/nginx.conf
 #
 # See the link:/TUNING.html document for more information on tuning unicorn.
 class Unicorn::Configurator
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 741cca5..35bd100 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -6,7 +6,7 @@
 # forked worker children.
 #
 # Users do not need to know the internals of this class, but reading the
-# {source}[http://bogomips.org/unicorn.git/tree/lib/unicorn/http_server.rb]
+# {source}[https://bogomips.org/unicorn.git/tree/lib/unicorn/http_server.rb]
 # is education for programmers wishing to learn how unicorn works.
 # See Unicorn::Configurator for information on how to configure unicorn.
 class Unicorn::HttpServer
-- 
EW

^ permalink raw reply related	[relevance 42%]

* Re: [PATCH] Add some tolerance (RFC2616 sec. 19.3)
  2016-10-20 17:55  6% ` Eric Wong
@ 2016-10-20 20:25  0%   ` Mishael A Sibiryakov
  0 siblings, 0 replies; 200+ results
From: Mishael A Sibiryakov @ 2016-10-20 20:25 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

On Thu, 2016-10-20 at 17:55 +0000, Eric Wong wrote:

> Thanks for that useful explanation.  Aside from the unnecessary,
> "Hi all,", that is an informative commit message which justifies
> the usefulness of that patch.
> 
> > 
> > Github commit https://github.com/uno4ki/unicorn/commit/ed127b66e162aaf1
> > 76de05720f6be758f8b41b1f
> 
> Unfortunately, the commit message in your git repo is lacking.
> I've used the text at the top of your email.

It's just a temporary fork and I'm too lazy ))

> Eeep, Evolution does some strange things with formatting
> whitespaces.  It looks like instructions for making it nicer are
> in the Linux kernel:
> 
> https://bogomips.org/mirrors/linux.git/plain/Documentation/email-clients.txt?h=v4.8

Whoops, my fault. 

> > +  def test_multiline_header_0d0a
> > +    parser = HttpParser.new
> > +    parser.buf << "GET / HTTP/1.0\r\nX-Multiline-Header: foo
> > bar\r\n\tcha cha\r\n\tzha zha\r\n\r\n"
> 
> I expect code to be wrapped at 80 lines or less.  Fixed locally.
> (I need big fonts, even 80 is a compromise, I really prefer 64)

Line 221 with "ssl bullshit" guided me to this.

> Anyways, pushed to the "rfc2616-sec19.3" branch.
> 
> I've also uploaded a prerelease 5.1.0.4.gd5fbb to RubyGems
> for folks without Ragel.
> 
> 	gem install --pre unicorn -v 5.1.0.4.gd5fbb
> 
> Anything else?  Expect a 5.2.0 release in a few days or so.
> Thanks.

Thanks for the quick acceptance.

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] Add some tolerance (RFC2616 sec. 19.3)
  @ 2016-10-20 17:55  6% ` Eric Wong
  2016-10-20 20:25  0%   ` Mishael A Sibiryakov
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2016-10-20 17:55 UTC (permalink / raw)
  To: Mishael A Sibiryakov; +Cc: unicorn-public

Mishael A Sibiryakov <death@junki.org> wrote:
> Hi all.
> 
> We're implementing client certificate authentication with nginx and
> unicorn. 
> 
> Nginx configured in the following way:
> 
> proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
> 
> When client submits certificate and nginx passes it to the unicorn,
> unicorn responds with 400 (Bad Request). This caused because nginx
> doesn't use "\r\n" they using just "\n" and multilne headers is failed
> to parse (I've added test).
> 
> Accorording to RFC2616 section 19.3:
> https://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.3
> 
> "The line terminator for message-header fields is the sequence CRLF.
> However, we recommend that applications, when parsing such headers,
> recognize a single LF as a line terminator and ignore the leading CR."
> 
> CRLF changed to ("\r\n" | "\n")

Thanks for that useful explanation.  Aside from the unnecessary,
"Hi all,", that is an informative commit message which justifies
the usefulness of that patch.

> Github commit https://github.com/uno4ki/unicorn/commit/ed127b66e162aaf1
> 76de05720f6be758f8b41b1f

Unfortunately, the commit message in your git repo is lacking.
I've used the text at the top of your email.

> PS: Googling "nginx unicorn ssl_client_cert" shows the problem. 
> 
> ---
>  ext/unicorn_http/unicorn_http_common.rl |  2 +-
>  test/unit/test_http_parser.rb           | 16 ++++++++++++++++
>  2 files changed, 17 insertions(+), 1 deletion(-)

Eeep, Evolution does some strange things with formatting
whitespaces.  It looks like instructions for making it nicer are
in the Linux kernel:

https://bogomips.org/mirrors/linux.git/plain/Documentation/email-clients.txt?h=v4.8

<snip>

> +  def test_multiline_header_0d0a
> +    parser = HttpParser.new
> +    parser.buf << "GET / HTTP/1.0\r\nX-Multiline-Header: foo
> bar\r\n\tcha cha\r\n\tzha zha\r\n\r\n"

I expect code to be wrapped at 80 lines or less.  Fixed locally.
(I need big fonts, even 80 is a compromise, I really prefer 64)

Anyways, pushed to the "rfc2616-sec19.3" branch.

I've also uploaded a prerelease 5.1.0.4.gd5fbb to RubyGems
for folks without Ragel.

	gem install --pre unicorn -v 5.1.0.4.gd5fbb

Anything else?  Expect a 5.2.0 release in a few days or so.
Thanks.

^ permalink raw reply	[relevance 6%]

* Re: [PATCH] `unicorn upgrade` script resilience against exceptions
  2016-06-07 13:41  0% ` [PATCH] `unicorn upgrade` script resilience against exceptions Eric Wong
@ 2016-06-07 15:17  0%   ` Jesper Rønn-Jensen
  0 siblings, 0 replies; 200+ results
From: Jesper Rønn-Jensen @ 2016-06-07 15:17 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

Thanks for input.

I will close this issue and wait for your patch later, then.

Will also close pull-request I put at github with reference to this thread.

PS. Thanks for tip on HTML vs Plain text mails. Didn't know Gmail
could send plain text :)



On Tue, Jun 7, 2016 at 3:41 PM, Eric Wong <e@80x24.org> wrote:
> Jesper Rønn-Jensen <jesperrr@gmail.com> wrote:
>> This is actually a change proposal "by accident". But first, some
>> background:
>
>         Please don't send HTML mail.  I guess the bounce message didn't
>         include the reason for the bounce, but should be fixed; now;
>         and the bounce will tell you to not send HTML.
>
>         Anyways if you stick to old-school Usenet/mailing list posting
>         conventions, I'm more than happy to help you :)
>
>> My server uses a standard version of this `init.sh` script. I found that
>> executing `unicorn upgrade` often gives me problems.
>
> Hm... I haven't looked at that script in a while given all
> the new-fangled init replacements...
>
>> For example, it breaks my Capistrano deploy script to use `unicorn:upgrade`
>> to deploy. This is a shame, since it's the correct
>> command for Unicorn to pick up any code changes. But unicorn upgrade in the
>> script fails with messages like:
>>
>> ```
>> sudo /etc/init.d/unicorn upgrade
>> Couldn't upgrade, starting 'export HOME=/home/deploy ; cd
>> /var/www/my_app/current && /home/deploy/.rvm/wrappers/my_app/bundle exec
>> unicorn -D -c /var/www/my_app/shared/config/unicorn.rb -E production'
>> instead
>> master failed to start, check stderr log for details
>> ```
>>
>> And the stderror log:
>> ```
>> E, [2016-06-07T09:03:27.517267 #27583] ERROR -- : reaped #<Process::Status:
>> pid 27621 exit 1> exec()-ed
>> /var/www/my_app/shared/vendor/bundle/ruby/2.3.0/gems/unicorn-5.1.0/lib/unicorn/http_server.rb:195:in
>>     `pid=': Already running on PID:27583 (or
>> pid=/var/www/my_app/shared/tmp/pids/unicorn.pid is stale)
>>     (ArgumentError)
>> ```
>>
>> I am proposing this change because I misread the documentation for the
>> SIGNALS!
>> I thought that Unicorn itself sends a QUIT after all subprocesses has ended
>> via SIG USR2.
>>
>> The change is to remove the QUIT signal to the PID.oldbin process, and that
>> apparently stops all the failures I ran into. So I made this change on a
>> server, and it works!
>>
>> I just don't understand why, since reading the documentation again it says:
>> https://github.com/defunkt/unicorn/blob/d23d4713dc9ab9732c574f5aa34a4b6740b43164/SIGNALS#L35
>>
>> > * USR2 - reexecute the running binary.  A separate QUIT
>> >  should be sent to the original process once the child is verified to
>> >  be up and running.
>>
>> So clearly, I should send the QUIT signal.
>
> Yes.
>
>> My goal is to have a resilient, robust deployment, where unicorn picks up
>> any code changes.
>
> Unfortunately, PID files have always been racy with USR2.
> Nowadays systemd is fairly standardized and seems to work
> pretty well for managing sockets and services.
>
> I'm still not a fan of some systemd things, but I think the socket
> activation part is very nice.  Example @.service and .socket files
> are distributed nowadays:
>
>         https://unicorn.bogomips.org/examples/unicorn@.service
>         https://unicorn.bogomips.org/examples/unicorn.socket
>
>> Can you help me and enlighten me as to why this proposed change works?
>
> Anyways, things are racy in that script and increasing the
> "sleep 2" to a higher number will help if your system is really
> overloaded.
>
>> ---
>>  examples/init.sh | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/examples/init.sh b/examples/init.sh
>> index 1f0e035..cbadc11 100644
>> --- a/examples/init.sh
>> +++ b/examples/init.sh
>> @@ -45,7 +45,7 @@ restart|reload)
>>   $CMD
>>   ;;
>>  upgrade)
>> - if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
>> + if sig USR2 && sleep 2 && sig 0
>>   then
>>   n=$TIMEOUT
>>   while test -s $old_pid && test $n -ge 0
>> --
>
> I actually wrote a better init script for a similar server,
> patch coming in a bit (or later, close to falling asleep).



-- 

Jesper Rønn-Jensen
Nine A/S
Mobile: +45 2989 1822
Blog http://justaddwater.dk/
jesperrr@gmail.com (Private e-mail and Google Talk IM)

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] `unicorn upgrade` script resilience against exceptions
       [not found]     <CAL-rKu6CZ731c=uHyZ8+Fg2fhC30e-3-J26XODacUK=YrfX+5Q@mail.gmail.com>
@ 2016-06-07 13:41  0% ` Eric Wong
  2016-06-07 15:17  0%   ` Jesper Rønn-Jensen
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2016-06-07 13:41 UTC (permalink / raw)
  To: Jesper Rønn-Jensen; +Cc: unicorn-public

Jesper Rønn-Jensen <jesperrr@gmail.com> wrote:
> This is actually a change proposal "by accident". But first, some
> background:

	Please don't send HTML mail.  I guess the bounce message didn't
	include the reason for the bounce, but should be fixed; now;
	and the bounce will tell you to not send HTML.

	Anyways if you stick to old-school Usenet/mailing list posting
	conventions, I'm more than happy to help you :)

> My server uses a standard version of this `init.sh` script. I found that
> executing `unicorn upgrade` often gives me problems.

Hm... I haven't looked at that script in a while given all
the new-fangled init replacements...

> For example, it breaks my Capistrano deploy script to use `unicorn:upgrade`
> to deploy. This is a shame, since it's the correct
> command for Unicorn to pick up any code changes. But unicorn upgrade in the
> script fails with messages like:
> 
> ```
> sudo /etc/init.d/unicorn upgrade
> Couldn't upgrade, starting 'export HOME=/home/deploy ; cd
> /var/www/my_app/current && /home/deploy/.rvm/wrappers/my_app/bundle exec
> unicorn -D -c /var/www/my_app/shared/config/unicorn.rb -E production'
> instead
> master failed to start, check stderr log for details
> ```
> 
> And the stderror log:
> ```
> E, [2016-06-07T09:03:27.517267 #27583] ERROR -- : reaped #<Process::Status:
> pid 27621 exit 1> exec()-ed
> /var/www/my_app/shared/vendor/bundle/ruby/2.3.0/gems/unicorn-5.1.0/lib/unicorn/http_server.rb:195:in
>     `pid=': Already running on PID:27583 (or
> pid=/var/www/my_app/shared/tmp/pids/unicorn.pid is stale)
>     (ArgumentError)
> ```
> 
> I am proposing this change because I misread the documentation for the
> SIGNALS!
> I thought that Unicorn itself sends a QUIT after all subprocesses has ended
> via SIG USR2.
> 
> The change is to remove the QUIT signal to the PID.oldbin process, and that
> apparently stops all the failures I ran into. So I made this change on a
> server, and it works!
> 
> I just don't understand why, since reading the documentation again it says:
> https://github.com/defunkt/unicorn/blob/d23d4713dc9ab9732c574f5aa34a4b6740b43164/SIGNALS#L35
> 
> > * USR2 - reexecute the running binary.  A separate QUIT
> >  should be sent to the original process once the child is verified to
> >  be up and running.
> 
> So clearly, I should send the QUIT signal.

Yes.

> My goal is to have a resilient, robust deployment, where unicorn picks up
> any code changes.

Unfortunately, PID files have always been racy with USR2.
Nowadays systemd is fairly standardized and seems to work
pretty well for managing sockets and services.

I'm still not a fan of some systemd things, but I think the socket
activation part is very nice.  Example @.service and .socket files
are distributed nowadays:

	https://unicorn.bogomips.org/examples/unicorn@.service
	https://unicorn.bogomips.org/examples/unicorn.socket

> Can you help me and enlighten me as to why this proposed change works?

Anyways, things are racy in that script and increasing the
"sleep 2" to a higher number will help if your system is really
overloaded.

> ---
>  examples/init.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/examples/init.sh b/examples/init.sh
> index 1f0e035..cbadc11 100644
> --- a/examples/init.sh
> +++ b/examples/init.sh
> @@ -45,7 +45,7 @@ restart|reload)
>   $CMD
>   ;;
>  upgrade)
> - if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
> + if sig USR2 && sleep 2 && sig 0
>   then
>   n=$TIMEOUT
>   while test -s $old_pid && test $n -ge 0
> -- 

I actually wrote a better init script for a similar server,
patch coming in a bit (or later, close to falling asleep).

^ permalink raw reply	[relevance 0%]

* [ANN] unicorn 5.1.0 - Rack HTTP server for fast clients and *nix
@ 2016-04-01  0:43  5% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2016-04-01  0:43 UTC (permalink / raw)
  To: ruby-talk, unicorn-public; +Cc: Adam Duke, Aaron Patterson

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

* http://unicorn.bogomips.org/
* public list: unicorn-public@bogomips.org
* mail archives: http://bogomips.org/unicorn-public/
* git clone git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

Changes:

    unicorn 5.1.0 - rack is optional, again

    Note: no code changes since 5.1.0.pre1 from January.^WNo, wait,
    last minute performance improvement added today.  See below.

    The big change is rack is not required (but still recommended).
    Applications are expected to depend on rack on their own so they can
    specify the version of rack they prefer without unicorn pulling
    in a newer, potentially incompatible version.

    unicorn will always attempt to work with multiple versions of rack
    as practical.

    The HTTP parser also switched to using the TypedData C-API for
    extra type safety and memory usage accounting support in the
    'objspace' extension.

    Thanks to Adam Duke to bringing the rack change to our attention
    and Aaron Patterson for helping with the matter.

    Last minute change: we now support the new leftpad() syscall under
    Linux for major performance and security improvements:

        http://mid.gmane.org/1459463613-32473-1-git-send-email-richard@nod.at

    8^H9 changes since 5.0.1:

          http: TypedData C-API conversion
          various documentation updates
          doc: bump olddoc to ~> 1.2 for extra NNTP URL
          rack is optional at runtime, required for dev
          doc update for ClientShutdown exceptions class
          unicorn 5.1.0.pre1 - rack is optional, again
          doc: reference --keep-file-descriptors for "bundle exec"
          doc: further trimming to reduce noise
          use leftpad Linux syscall for speed!

^ permalink raw reply	[relevance 5%]

* [PATCH] doc: further trimming to reduce noise
@ 2016-03-31  1:41  9% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2016-03-31  1:41 UTC (permalink / raw)
  To: unicorn-public

It's not worth mentioning pre-Rack versions of Rails anymore,
and there are a few async Rack applications reliant on
EventMachine which we do not use.

Some uses of chunked request decoding are not well-handled
with nginx in front, anyways; so avoid mentioning them.

Additionally, avoid introducing new terms into the lexicon
and just refer to "mailing list" as a generic term.
---
 ISSUES | 8 +++-----
 README | 7 +------
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/ISSUES b/ISSUES
index 394c852..21bd013 100644
--- a/ISSUES
+++ b/ISSUES
@@ -5,7 +5,7 @@ submit patches and/or obtain support after you have searched the
 {email archives}[http://bogomips.org/unicorn-public/] and
 {documentation}[http://unicorn.bogomips.org/].
 
-* No subscription will ever be required to email the public inbox.
+* No subscription will ever be required to email us
 * Cc: all participants in a thread or commit, as subscription is optional
 * Do not {top post}[http://catb.org/jargon/html/T/top-post.html] in replies
 * Quote as little as possible of the message you're replying to
@@ -69,9 +69,7 @@ document distributed with git) on guidelines for patch submission.
 * nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
 * http://bogomips.org/unicorn-public/
 
-We operate a {public-inbox}[http://public-inbox.org/] which
-feeds the mailing list.  Subscription is optional, so Cc:
-all participants.
+Mailing list subscription is optional, so Cc: all participants.
 
 You can follow along via NNTP:
 
@@ -86,7 +84,7 @@ Or Atom feeds:
 	also has links to per-thread Atom feeds and downloadable
 	mboxes.
 
-You may also subscribe via plain-text email:
+You may optionally subscribe via plain-text email:
 
 	mailto:unicorn-public+subscribe@bogomips.org
 	(and confirming the auto-reply)
diff --git a/README b/README
index 11de938..8079f37 100644
--- a/README
+++ b/README
@@ -27,9 +27,6 @@ both the the request and response in between unicorn and slow clients.
   all run within their own isolated address space and only serve one
   client at a time for maximum robustness.
 
-* Supports all Rack applications, along with pre-Rack versions of
-  Ruby on Rails via a Rack wrapper.
-
 * Builtin reopening of all log files in your application via
   USR1 signal.  This allows logrotate to rotate files atomically and
   quickly via rename instead of the racy and slow copytruncate method.
@@ -54,9 +51,7 @@ both the the request and response in between unicorn and slow clients.
 
 * Simple and easy Ruby DSL for configuration.
 
-* Decodes chunked transfers on-the-fly, thus allowing upload progress
-  notification to be implemented as well as being able to tunnel
-  arbitrary stream-based protocols over HTTP.
+* Decodes chunked requests on-the-fly.
 
 == License
 
-- 
EW


^ permalink raw reply related	[relevance 9%]

* Re: https://unicorn.bogomips.org accepts client certificate?
  2016-03-15 23:30  7%         ` Eric Wong
@ 2016-03-15 23:54  0%           ` Shota Fukumori (sora_h)
  0 siblings, 0 replies; 200+ results
From: Shota Fukumori (sora_h) @ 2016-03-15 23:54 UTC (permalink / raw)
  To: Eric Wong; +Cc: russm, unicorn-public, yahns-public

On Wed, Mar 16, 2016 at 8:30 AM, Eric Wong <e@80x24.org> wrote:
> I've updated https://unicorn.bogomips.org/ with the above change,
> can you confirm it works for you?  If so, I'll update the yahns
> documentation.

It worked -- my browser now doesn't prompt about a certificate :)

-- 
Shota Fukumori a.k.a. @sora_h http://sorah.jp/

^ permalink raw reply	[relevance 0%]

* Re: https://unicorn.bogomips.org accepts client certificate?
  @ 2016-03-15 23:30  7%         ` Eric Wong
  2016-03-15 23:54  0%           ` Shota Fukumori (sora_h)
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2016-03-15 23:30 UTC (permalink / raw)
  To: Shota Fukumori (sora_h); +Cc: russm, unicorn-public, yahns-public

"Shota Fukumori (sora_h)" <her@sorah.jp> wrote:
> To be clear, you have to have a client certificate on your certificate
> manager to be prompted.
> Server doesn't specify acceptable client certificate CA names, so any
> client certificate is ok.

Thanks for the report, I think I just fixed the problem:

  ctx.set_params # reasonable defaults for clients, apparently

However, webrick and drb both set VERIFY_NONE for servers:

  ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_NONE)

I've updated https://unicorn.bogomips.org/ with the above change,
can you confirm it works for you?  If so, I'll update the yahns
documentation.

^ permalink raw reply	[relevance 7%]

* Re: Systemd socket inheritance fails with “not a socket file descriptor”
  @ 2016-03-12  5:30  7%               ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2016-03-12  5:30 UTC (permalink / raw)
  To: Amir Yalon; +Cc: Christos Trochalakis, unicorn-public

Amir Yalon <amiryal@yxejamir.net> wrote:
> I will try to run my app using the 3rd method and report back as soon as
> I can.

Looking forward to it.  I'd like to release 5.1.0 final with any
necessary updates (most likely documentation) needed for this
problem in a week or so.

A huge thanks for bringing this up and to Christos for testing and
bringing up the potential (and IMHO very likely) RVM issue.

^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 5.1.0.pre1 - Rack HTTP server for fast clients and *nix
@ 2016-01-27 23:16  8% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2016-01-27 23:16 UTC (permalink / raw)
  To: ruby-talk, unicorn-public

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

* http://unicorn.bogomips.org/
* public list: unicorn-public@bogomips.org
* mail archives: http://bogomips.org/unicorn-public/
* git clone git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn

This is a pre-release, you will need to specify the version to
install explicitly when using RubyGems.

Changes:

    unicorn 5.1.0.pre1 - rack is optional, again

    The big change is rack is not required (but still recommended).
    Applications are expected to depend on rack on their own so they can
    specify the version of rack they prefer without unicorn pulling
    in a newer, potentially incompatible version.

    unicorn will always attempt to work with multiple versions of rack
    as practical.

    The HTTP parser also switched to using the TypedData C-API for
    extra type safety and memory usage accounting support in the
    'objspace' extension.

    Thanks to Adam Duke to bringing the rack change to our attention
    and Aaron Patterson for helping with the matter.

    There might be more documentation-related changes before 5.1.0
    final.  I am considering dropping pandoc from manpage generation
    and relying on pod2man (from Perl) because it has a wider install
    base.

    5 changes since v5.0.1:

          http: TypedData C-API conversion
          various documentation updates
          doc: bump olddoc to ~> 1.2 for extra NNTP URL
          rack is optional at runtime, required for dev
          doc update for ClientShutdown exceptions class

^ permalink raw reply	[relevance 8%]

* Re: [PATCH] limit rack version for ruby compatibility
  2016-01-08 21:56  0%     ` Aaron Patterson
@ 2016-01-08 22:13  0%       ` Adam Duke
  0 siblings, 0 replies; 200+ results
From: Adam Duke @ 2016-01-08 22:13 UTC (permalink / raw)
  To: Aaron Patterson; +Cc: rack-devel, unicorn-public

Is it reasonable to assume that any rack release that includes bumping
the ruby requirement to 2.2.2 would require a major version bump of
rack?

The dependency in the unicorn gemspec could be as simple as '< 2' if
that is the case.

On Fri, Jan 8, 2016 at 4:56 PM, Aaron Patterson
<tenderlove@ruby-lang.org> wrote:
> On Fri, Jan 08, 2016 at 01:50:46PM -0800, Aaron Patterson wrote:
>> On Fri, Jan 08, 2016 at 07:18:07PM +0000, Eric Wong wrote:
>> > Adam Duke <adamduke@twitter.com> wrote:
>> > > From: Adam Duke <adam.v.duke@gmail.com>
>> > > Date: Fri, 8 Jan 2016 13:06:31 -0500
>> > > Subject: [PATCH] limit rack version for ruby compatibility
>> > >
>> > > rack introduced a dependency on ruby 2.2.2 or greater in
>> > > https://github.com/rack/rack/commit/771d94e5dbe53058160a1f8a4cc56384c1d2a048
>> >
>> > Cc-ing rack-devel + Aaron
>> >
>> > Yikes!  ruby-core still supports Ruby 2.1 and possibly even 2.0.0
>> >
>> > And there doesn't seem to be any documentation on why Ruby 2.2.x
>> > is needed in the first place for rack.git
>> > commit a2fe30a5e70371c89c1b29fdc2dc5f8027bc5fe6
>> >
>> >     http://bogomips.org/mirrors/rack.git/patch?id=a2fe30a5e70371c8
>> >
>> > Aaron?
>>
>> The main reason I bumped it up to Ruby 2.2.x is because that will be the
>> minimum version of Ruby I'll be stuck with throughout Rack 2.x's
>> lifetime.  IOW, I can't drop Ruby versions in anything but a major
>> release so I'm being conservative and only going with the latest (at the
>> time that was 2.2).
>>
>> I could be convinced to bring down the version number, but I'd like to
>> know why first. :)
>
> Oh, I forgot to mention that I don't mind eliminating the Ruby version
> requirement as long as we put something in the README that says we only
> guarantee it works on 2.2.x and up.  Older versions could be "best
> effort".  I'm just afraid to do something like that because I really
> don't want to maintain 1.8 and 1.9 baggage (for example).  I used the
> gemspec to clearly announce the Ruby versions I actually test with.
>
> --
> Aaron Patterson
> http://tenderlovemaking.com/

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] limit rack version for ruby compatibility
  2016-01-08 21:50  0%   ` Aaron Patterson
@ 2016-01-08 21:56  0%     ` Aaron Patterson
  2016-01-08 22:13  0%       ` Adam Duke
  0 siblings, 1 reply; 200+ results
From: Aaron Patterson @ 2016-01-08 21:56 UTC (permalink / raw)
  To: Aaron Patterson; +Cc: rack-devel, Adam Duke, unicorn-public

[-- Attachment #1: Type: text/plain, Size: 1767 bytes --]

On Fri, Jan 08, 2016 at 01:50:46PM -0800, Aaron Patterson wrote:
> On Fri, Jan 08, 2016 at 07:18:07PM +0000, Eric Wong wrote:
> > Adam Duke <adamduke@twitter.com> wrote:
> > > From: Adam Duke <adam.v.duke@gmail.com>
> > > Date: Fri, 8 Jan 2016 13:06:31 -0500
> > > Subject: [PATCH] limit rack version for ruby compatibility
> > > 
> > > rack introduced a dependency on ruby 2.2.2 or greater in
> > > https://github.com/rack/rack/commit/771d94e5dbe53058160a1f8a4cc56384c1d2a048
> > 
> > Cc-ing rack-devel + Aaron
> > 
> > Yikes!  ruby-core still supports Ruby 2.1 and possibly even 2.0.0
> > 
> > And there doesn't seem to be any documentation on why Ruby 2.2.x
> > is needed in the first place for rack.git
> > commit a2fe30a5e70371c89c1b29fdc2dc5f8027bc5fe6
> > 
> > 	http://bogomips.org/mirrors/rack.git/patch?id=a2fe30a5e70371c8
> > 
> > Aaron?
> 
> The main reason I bumped it up to Ruby 2.2.x is because that will be the
> minimum version of Ruby I'll be stuck with throughout Rack 2.x's
> lifetime.  IOW, I can't drop Ruby versions in anything but a major
> release so I'm being conservative and only going with the latest (at the
> time that was 2.2).
> 
> I could be convinced to bring down the version number, but I'd like to
> know why first. :)

Oh, I forgot to mention that I don't mind eliminating the Ruby version
requirement as long as we put something in the README that says we only
guarantee it works on 2.2.x and up.  Older versions could be "best
effort".  I'm just afraid to do something like that because I really
don't want to maintain 1.8 and 1.9 baggage (for example).  I used the
gemspec to clearly announce the Ruby versions I actually test with.

-- 
Aaron Patterson
http://tenderlovemaking.com/


[-- Attachment #2: Type: application/pgp-signature, Size: 456 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] limit rack version for ruby compatibility
  2016-01-08 19:18  6% ` Eric Wong
@ 2016-01-08 21:50  0%   ` Aaron Patterson
  2016-01-08 21:56  0%     ` Aaron Patterson
  0 siblings, 1 reply; 200+ results
From: Aaron Patterson @ 2016-01-08 21:50 UTC (permalink / raw)
  To: rack-devel; +Cc: Adam Duke, unicorn-public

[-- Attachment #1: Type: text/plain, Size: 2839 bytes --]

On Fri, Jan 08, 2016 at 07:18:07PM +0000, Eric Wong wrote:
> Adam Duke <adamduke@twitter.com> wrote:
> > From: Adam Duke <adam.v.duke@gmail.com>
> > Date: Fri, 8 Jan 2016 13:06:31 -0500
> > Subject: [PATCH] limit rack version for ruby compatibility
> > 
> > rack introduced a dependency on ruby 2.2.2 or greater in
> > https://github.com/rack/rack/commit/771d94e5dbe53058160a1f8a4cc56384c1d2a048
> 
> Cc-ing rack-devel + Aaron
> 
> Yikes!  ruby-core still supports Ruby 2.1 and possibly even 2.0.0
> 
> And there doesn't seem to be any documentation on why Ruby 2.2.x
> is needed in the first place for rack.git
> commit a2fe30a5e70371c89c1b29fdc2dc5f8027bc5fe6
> 
> 	http://bogomips.org/mirrors/rack.git/patch?id=a2fe30a5e70371c8
> 
> Aaron?

The main reason I bumped it up to Ruby 2.2.x is because that will be the
minimum version of Ruby I'll be stuck with throughout Rack 2.x's
lifetime.  IOW, I can't drop Ruby versions in anything but a major
release so I'm being conservative and only going with the latest (at the
time that was 2.2).

I could be convinced to bring down the version number, but I'd like to
know why first. :)

> > In order to maintain support for ruby versions less than 2.2.2, limit
> > the rack dependency to supported versions for the current ruby.
> > ---
> >  unicorn.gemspec | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/unicorn.gemspec b/unicorn.gemspec
> > index 1099361..ce7080a 100644
> > --- a/unicorn.gemspec
> > +++ b/unicorn.gemspec
> > @@ -35,7 +35,11 @@
> >    # up/downgrade to any other version, the Rack dependency may be
> >    # commented out.  Nevertheless, upgrading to Rails 2.3.4 or later is
> >    # *strongly* recommended for security reasons.
> > -  s.add_dependency(%q<rack>)
> > +  if RUBY_VERSION < '2.2.2'
> > +    s.add_dependency(%q<rack>, '~> 1.6.4')
> > +  else
> > +    s.add_dependency(%q<rack>)
> > +  end
> 
> Interesting, I built a gem with RubyGems 2.5.1 and this conditional
> was preserved in the gemspec.  I tried this in the past (2009/2010?)
> and any conditionals written like this got clobbered in the final
> gemspec.

I wonder if that's true even after you upload to rubygems.org.  I'd
guess it's not true as they don't want to support arbitrary ruby code
for specs.

> In other words, conditionals used to be evaluated at "gem build" time,
> not "gem install" time.  We should check when this improvement was
> introduced into RubyGems should we go this route.
> 
> Also, maybe '~> 1.6.4' is too strict, '~> 1.6' could be better in case
> a rack 1.7 comes out in parallel to rack 2.0

Agree here.  1.7 may be possible, and I want to make the guarantee that
its API is backwards compatible with 1.6.

-- 
Aaron Patterson
http://tenderlovemaking.com/


[-- Attachment #2: Type: application/pgp-signature, Size: 456 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] limit rack version for ruby compatibility
  @ 2016-01-08 19:18  6% ` Eric Wong
  2016-01-08 21:50  0%   ` Aaron Patterson
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2016-01-08 19:18 UTC (permalink / raw)
  To: Adam Duke; +Cc: unicorn-public, Aaron Patterson, rack-devel

Adam Duke <adamduke@twitter.com> wrote:
> From: Adam Duke <adam.v.duke@gmail.com>
> Date: Fri, 8 Jan 2016 13:06:31 -0500
> Subject: [PATCH] limit rack version for ruby compatibility
> 
> rack introduced a dependency on ruby 2.2.2 or greater in
> https://github.com/rack/rack/commit/771d94e5dbe53058160a1f8a4cc56384c1d2a048

Cc-ing rack-devel + Aaron

Yikes!  ruby-core still supports Ruby 2.1 and possibly even 2.0.0

And there doesn't seem to be any documentation on why Ruby 2.2.x
is needed in the first place for rack.git
commit a2fe30a5e70371c89c1b29fdc2dc5f8027bc5fe6

	http://bogomips.org/mirrors/rack.git/patch?id=a2fe30a5e70371c8

Aaron?

> In order to maintain support for ruby versions less than 2.2.2, limit
> the rack dependency to supported versions for the current ruby.
> ---
>  unicorn.gemspec | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/unicorn.gemspec b/unicorn.gemspec
> index 1099361..ce7080a 100644
> --- a/unicorn.gemspec
> +++ b/unicorn.gemspec
> @@ -35,7 +35,11 @@
>    # up/downgrade to any other version, the Rack dependency may be
>    # commented out.  Nevertheless, upgrading to Rails 2.3.4 or later is
>    # *strongly* recommended for security reasons.
> -  s.add_dependency(%q<rack>)
> +  if RUBY_VERSION < '2.2.2'
> +    s.add_dependency(%q<rack>, '~> 1.6.4')
> +  else
> +    s.add_dependency(%q<rack>)
> +  end

Interesting, I built a gem with RubyGems 2.5.1 and this conditional
was preserved in the gemspec.  I tried this in the past (2009/2010?)
and any conditionals written like this got clobbered in the final
gemspec.

In other words, conditionals used to be evaluated at "gem build" time,
not "gem install" time.  We should check when this improvement was
introduced into RubyGems should we go this route.

Also, maybe '~> 1.6.4' is too strict, '~> 1.6' could be better in case
a rack 1.7 comes out in parallel to rack 2.0

^ permalink raw reply	[relevance 6%]

* [PUSHED] various documentation updates
@ 2016-01-07  3:41 34% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2016-01-07  3:41 UTC (permalink / raw)
  To: unicorn-public

* add nntp_url to the olddoc website footer
* update legacy support status for 4.x (not 4.8.x)
* update copyright range to 2016
* note all of our development tools are Free Software, too
* remove cgit mention; it may not always be cgit
  (but URLs should remain compatible).
* discourage downloading snapshot tarballs;
  "git clone" + periodic "git fetch" is more efficient
* remove most mentions of unicorn_rails as that
  was meant for ancient Rails 1.x/2.x users
* update path reference to Ruby 2.3.0
* fix nginx upstream module link to avoid redirect
* shorten Message-ID example to avoid redirects
  and inadvertant linkage
---
  Also pushed to the website http://unicorn.bogomips.org/
  (using olddoc.git @ c98abe82b6b3 from git://80x24.org/olddoc.git)

  Curious, does anybody out there use Rails 2.x or earlier?

 .olddoc.yml                       |  1 +
 Documentation/unicorn.1.txt       |  1 -
 Documentation/unicorn_rails.1.txt |  2 +-
 HACKING                           |  2 +-
 README                            | 17 +++++------------
 lib/unicorn/configurator.rb       |  5 +++--
 lib/unicorn/http_server.rb        |  4 ++--
 7 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/.olddoc.yml b/.olddoc.yml
index 063c1c6..cda8ac3 100644
--- a/.olddoc.yml
+++ b/.olddoc.yml
@@ -13,3 +13,4 @@ noindex:
 - unicorn_rails_1
 public_email: unicorn-public@bogomips.org
 private_email: unicorn@bogomips.org
+nntp_url: nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index efdda4b..3f20a9a 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
@@ -175,7 +175,6 @@ the unicorn config file.
 
 # SEE ALSO
 
-* unicorn_rails(1)
 * *Rack::Builder* ri/RDoc
 * *Unicorn::Configurator* ri/RDoc
 * [Unicorn RDoc][1]
diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt
index bff703e..2ce7501 100644
--- a/Documentation/unicorn_rails.1.txt
+++ b/Documentation/unicorn_rails.1.txt
@@ -4,7 +4,7 @@
 
 # NAME
 
-unicorn_rails - a script/server-like command to launch the Unicorn HTTP server
+unicorn_rails - unicorn launcher for Rails 1.x and 2.x users
 
 # SYNOPSIS
 
diff --git a/HACKING b/HACKING
index 6c5f897..0fa22cd 100644
--- a/HACKING
+++ b/HACKING
@@ -57,7 +57,7 @@ Please wrap documentation at 72 characters-per-line or less (long URLs
 are exempt) so it is comfortably readable from terminals.
 
 When referencing mailing list posts, use
-"http://bogomips.org/unicorn-public/m/$MESSAGE_ID.html" if possible
+<tt>http://bogomips.org/unicorn-public/$MESSAGE_ID/</tt> if possible
 since the Message-ID remains searchable even if a particular site
 becomes unavailable.
 
diff --git a/README b/README
index db9f0d4..11de938 100644
--- a/README
+++ b/README
@@ -13,7 +13,7 @@ both the the request and response in between unicorn and slow clients.
   {nginx}[http://nginx.org/] or {Rack}[http://rack.github.io/].
 
 * Compatible with Ruby 1.9.3 and later.
-  unicorn 4.8.x will remain supported for Ruby 1.8 users.
+  unicorn 4.x remains supported for Ruby 1.8 users.
 
 * Process management: unicorn will reap and restart workers that
   die from broken apps.  There is no need to manage multiple processes
@@ -60,7 +60,7 @@ both the the request and response in between unicorn and slow clients.
 
 == License
 
-unicorn is copyright 2009 by all contributors (see logs in git).
+unicorn is copyright 2009-2016 by all contributors (see logs in git).
 It is based on Mongrel 1.1.5.
 Mongrel is copyright 2007 Zed A. Shaw and contributors.
 
@@ -68,7 +68,7 @@ unicorn is licensed under (your choice) of the GPLv2 or later
 (GPLv3+ preferred), or Ruby (1.8)-specific terms.
 See the included LICENSE file for details.
 
-unicorn is 100% Free Software.
+unicorn is 100% Free Software (including all development tools used).
 
 == Install
 
@@ -85,10 +85,9 @@ You can get the latest source via git from the following locations
   git://bogomips.org/unicorn.git
   git://repo.or.cz/unicorn.git (mirror)
 
-You may browse the code from the web and download the latest snapshot
-tarballs here:
+You may browse the code from the web:
 
-* http://bogomips.org/unicorn.git (cgit)
+* http://bogomips.org/unicorn.git
 * http://repo.or.cz/w/unicorn.git (gitweb)
 
 See the HACKING guide on how to contribute and build prerelease gems
@@ -102,12 +101,6 @@ In APP_ROOT, run:
 
   unicorn
 
-=== Ancient Rails 1.2 - 2.x versions
-
-In RAILS_ROOT, run:
-
-  unicorn_rails
-
 unicorn will bind to all interfaces on TCP port 8080 by default.
 You may use the +--listen/-l+ switch to bind to a different
 address:port or a UNIX socket.
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 4da19bb..948c6e3 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -181,8 +181,6 @@ def before_exec(*args, &block)
   # to have nginx always retry backends that may have had workers
   # SIGKILL-ed due to timeouts.
   #
-  #    # See http://wiki.nginx.org/NginxHttpUpstreamModule for more details
-  #    # on nginx upstream configuration:
   #    upstream unicorn_backend {
   #      # for UNIX domain socket setups:
   #      server unix:/path/to/.unicorn.sock fail_timeout=0;
@@ -192,6 +190,9 @@ def before_exec(*args, &block)
   #      server 192.168.0.8:8080 fail_timeout=0;
   #      server 192.168.0.9:8080 fail_timeout=0;
   #    }
+  #
+  # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html
+  # for more details on nginx upstream configuration.
   def timeout(seconds)
     set_int(:timeout, seconds, 3)
     # POSIX says 31 days is the smallest allowed maximum timeout for select()
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index ca56ed3..741cca5 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -36,7 +36,7 @@ class Unicorn::HttpServer
   # or even different installations of the same applications without
   # downtime.  Keys of this constant Hash are described as follows:
   #
-  # * 0 - the path to the unicorn/unicorn_rails executable
+  # * 0 - the path to the unicorn executable
   # * :argv - a deep copy of the ARGV array the executable originally saw
   # * :cwd - the working directory of the application, this is where
   # you originally started Unicorn.
@@ -45,7 +45,7 @@ class Unicorn::HttpServer
   # you can set the following in your Unicorn config file, HUP and then
   # continue with the traditional USR2 + QUIT upgrade steps:
   #
-  #   Unicorn::HttpServer::START_CTX[0] = "/home/bofh/2.2.0/bin/unicorn"
+  #   Unicorn::HttpServer::START_CTX[0] = "/home/bofh/2.3.0/bin/unicorn"
   START_CTX = {
     :argv => ARGV.map(&:dup),
     0 => $0.dup,
-- 
EW

^ permalink raw reply related	[relevance 34%]

* Shared Metrics Between Workers
@ 2015-11-13  0:51  6% Jeff Utter
  0 siblings, 0 replies; 200+ results
From: Jeff Utter @ 2015-11-13  0:51 UTC (permalink / raw)
  To: unicorn-public

Hello,

I was wondering if anyone can offer any advice in handling stats
collections between worker processes in forking servers (like unicorn).
Specifically, I am attempting to work on a solution for the Prometheus ruby
gem. Some details are in this issue here:
https://github.com/prometheus/client_ruby/issues/9

Prometheus works with a "scrape" model, where every few seconds a
prometheus server hits a http endpoint that exposes status. With the
current middleware the stats will only represent whichever worker is hit.

I have read through the documentation for unicorn and poked around the
source code some  -- as well as searched for similar projects for
inspiration.

The earliest, promising solution I considered was raindrops, but it looks
as though you need to know all of the possible metrics up front - which
won't necessarily work as prometheus could use metrics based on parameters
which could vary.

Does anyone have any experience working with something like this?

Thanks for any suggestions.

^ permalink raw reply	[relevance 6%]

* [PATCH 2/2] inheriting sockets from UNICORN_FD does not close them
  2015-10-27  3:33  6% [PATCH 0/2] socket inheritance behavior/bug => feature! Eric Wong
@ 2015-10-27  3:33 19% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-10-27  3:33 UTC (permalink / raw)
  To: unicorn-public

For some reason, I thought invalid descriptors passed to UNICORN_FD
would be automatically closed by the master process; but apparently
this hasn't been the case.  On the other hand, this bug has been
around for over 6 years now and nobody noticed or cared enough to
tell us, so fixing it might break existing setups.

Since there may be users relying on this behavior, we cannot change
the behavior anymore; so update the documentation and write at test
to ensure we can never "fix" this bug at the expense of breaking
any working setups which may be out there.

Keep in mind that a before_exec hook may always be used to modify
the UNICORN_FD environment by setting the close_on_exec flag and
removing the appropriate descriptor from the environment.

I originally intended to add the ability to inherit new listeners
without a config file specification so systemd users can avoid
repeating themselves in the systemd and unicorn config files,
but apparently there is nothing to change in our code.
---
 Documentation/unicorn.1.txt |  4 +---
 test/exec/test_exec.rb      | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index 193860f..5b82ad5 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
@@ -166,9 +166,7 @@ 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.
+numbers of the listen socket(s).
 
 # SEE ALSO
 
diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb
index af6f151..ca0b7bc 100644
--- a/test/exec/test_exec.rb
+++ b/test/exec/test_exec.rb
@@ -128,6 +128,26 @@ def test_sd_listen_fds_emulation
     # [ruby-core:69895] [Bug #11336] fixed by r51576
   end if RUBY_VERSION.to_f >= 2.3
 
+  def test_inherit_listener_unspecified
+    File.open("config.ru", "wb") { |fp| fp.write(HI) }
+    sock = TCPServer.new(@addr, @port)
+    sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 0)
+
+    pid = xfork do
+      redirect_test_io do
+        ENV['UNICORN_FD'] = sock.fileno.to_s
+        exec($unicorn_bin, sock.fileno => sock.fileno)
+      end
+    end
+    res = hit(["http://#@addr:#@port/"])
+    assert_equal [ "HI\n" ], res
+    assert_shutdown(pid)
+    assert_equal 1, sock.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).int,
+                'unicorn should always set SO_KEEPALIVE on inherited sockets'
+  ensure
+    sock.close if sock
+  end
+
   def test_working_directory_rel_path_config_file
     other = Tempfile.new('unicorn.wd')
     File.unlink(other.path)
-- 
EW


^ permalink raw reply related	[relevance 19%]

* [PATCH 0/2] socket inheritance behavior/bug => feature!
@ 2015-10-27  3:33  6% Eric Wong
  2015-10-27  3:33 19% ` [PATCH 2/2] inheriting sockets from UNICORN_FD does not close them Eric Wong
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2015-10-27  3:33 UTC (permalink / raw)
  To: unicorn-public

Given long enough, some bugs need to become documented behavior
(see [PATCH 2/2]).

Anyways, I guess we'll release 5.0.0 final in a day or two.  I was
intending to release 5.0.0 today until I noticed how un-DRY having
listeners configured in both systemd and unicorn config files would
be.  And then I noticed we have an existing bug as documented in 2/2
which would allow the user to be DRY after all.

Eric Wong (2):
      sd_listen_fds emulation cleanup
      inheriting sockets from UNICORN_FD does not close them

 Documentation/unicorn.1.txt |  4 +---
 lib/unicorn/http_server.rb  |  4 ++--
 test/exec/test_exec.rb      | 50 ++++++++++++++++++++++++++++++++++-----------
 3 files changed, 41 insertions(+), 17 deletions(-)

Fwiw, in case anybody is uncomfortable with the mere mention of the
word "systemd"; unicorn will never have any dependencies on systemd.
It will merely use systemd if available.

^ permalink raw reply	[relevance 6%]

* [PATCH] doc: update mail archive info
@ 2015-10-05  2:43  4% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-10-05  2:43 UTC (permalink / raw)
  To: unicorn-public

public-inbox supports read-only NNTP access nowadays to make it
easier to follow archives.  It is read-only to encourage Cc:-ing
all participants (which avoids reliance on the few-points-of-failure
behavior of NNTP).  Unlike email, NNTP also lacks good anti-spam
filtering.

Additionally, the gmane group also got redirected to the
bogomips.org address at some point since RubyForge died.

While we're at it, link to my post about enabling the submission
port (587).  It's been a year and nothing bad has happened, yet.

Finally, remove most of the documentation for ssoma since it's
unlikely anybody will use it given the existence of NNTP access.
It did little besides clutter the page.  However, git:// (used
by ssoma) remains strictly more efficient than NNTP.

Vebavpnyyl, gur AAGC freire sbe choyvp-vaobk pna unaqyr
gubhfnaqf bs fybj pyvragf.  Fbzrguvat havpbea jvyy arire or noyr
gb qb :C
---
 ISSUES | 45 ++++++++++++++++++---------------------------
 README |  5 +++++
 2 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/ISSUES b/ISSUES
index b172f8a..7c91555 100644
--- a/ISSUES
+++ b/ISSUES
@@ -11,6 +11,8 @@ submit patches and/or obtain support after you have searched the
 * Quote as little as possible of the message you're replying to
 * Do not send HTML mail, it will be flagged as spam
 * Anonymous and pseudonymous messages will always be welcome.
+* The email submission port (587) is enabled on the bogomips.org MX:
+  http://bogomips.org/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
 
 If your issue is of a sensitive nature or you're just shy in public,
 then feel free to email us privately at mailto:unicorn@bogomips.org
@@ -63,39 +65,28 @@ document distributed with git) on guidelines for patch submission.
 
 * public: mailto:unicorn-public@bogomips.org
 * private: mailto:unicorn@bogomips.org
+* nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+* nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
+* http://bogomips.org/unicorn-public/
 
 We operate a {public-inbox}[http://public-inbox.org/] which
-feeds the mailing list.  You may subscribe either using
-{ssoma}[http://ssoma.public-inbox.org/] or by sending a mail
-to mailto:unicorn-public+subscribe@bogomips.org
+feeds the mailing list.  Subscription is optional, so Cc:
+all participants.
 
-ssoma is a mail archiver/fetcher using git.  It operates in a similar
-fashion to tools such as slrnpull, fetchmail, or getmail.  ssoma
-subscription instructions:
+You can follow along via NNTP:
 
-	URL=git://bogomips.org/unicorn-public
-	LISTNAME=unicorn
+	nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn
+	nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
 
-	# to initialize a maildir (this may be a new or existing maildir,
-	# ssoma will not touch existing messages)
-	# If you prefer mbox, use mbox:/path/to/mbox as the last argument
-	# You may also use imap://$MAILSERVER/INBOX for an IMAP account
-	# or imaps:// for an IMAPS account, as well.
-	ssoma add $LISTNAME $URL maildir:/path/to/maildir
+Or Atom feeds:
 
-	# read with your favorite MUA (only using mutt as an example)
-	mutt -f /path/to/maildir # (or /path/to/mbox)
+	http://bogomips.org/unicorn-public/new.atom
 
-	# to keep your mbox or maildir up-to-date, periodically run the following:
-	ssoma sync $LISTNAME
+	The HTML archives at http://bogomips.org/unicorn-public/
+	also has links to per-thread Atom feeds and downloadable
+	mboxes.
 
-	# your MUA may modify and delete messages from the maildir or mbox,
-	# this does not affect ssoma functionality at all
+You may also subscribe via plain-text email:
 
-	# to sync all your ssoma subscriptions
-	ssoma sync
-
-	# You may wish to sync in your cronjob
-	ssoma sync --cron
-
-HTML archives are available here: http://bogomips.org/unicorn-public/
+	mailto:unicorn-public+subscribe@bogomips.org
+	(and confirming the auto-reply)
diff --git a/README b/README
index dc121d3..db9f0d4 100644
--- a/README
+++ b/README
@@ -140,6 +140,11 @@ All feedback (bug reports, user/development dicussion, patches, pull
 requests) go to the mailing list/newsgroup.  See the ISSUES document for
 information on the {mailing list}[mailto:unicorn-public@bogomips.org].
 
+The mailing list is archived at http://bogomips.org/unicorn-public/
+Read-only NNTP access is available at:
+nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
+nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
+
 For the latest on unicorn releases, you may also finger us at
 unicorn@bogomips.org or check our NEWS page (and subscribe to our Atom
 feed).
-- 
EW


^ permalink raw reply related	[relevance 4%]

* Re: Request to follow SemVer/mention it in homepage
  2015-10-01  4:56  0%           ` Pirate Praveen
@ 2015-10-01 11:18  0%             ` Pirate Praveen
  0 siblings, 0 replies; 200+ results
From: Pirate Praveen @ 2015-10-01 11:18 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

[dropping jhass]

He says "It's probably just conflicting opinion, distributing Ruby
applications to untrained people is still uncommon"

On Thursday 01 October 2015 10:26 AM, Pirate Praveen wrote:
> [copying jhass, maintainer of diaspora]
> 
> jhass, they prefer email to issue tracker so I copied you here.
> 
> You can see the complete discussion here 
> http://bogomips.org/unicorn-public/560A31F1.3060608%40debian.org/t/#u
>
>  On Thursday 01 October 2015 01:21 AM, Eric Wong wrote:
>> Pirate Praveen <praveen@debian.org> wrote:
>>> Can you mention the recommended way of adding unicorn in a 
>>> Gemfile in your home page?
> 
>> I'm not very knowledgeable about bundler, but app servers
>> probably should not be in any packaged Gemfile at all.
> 
> May be jhass can explain the rationale for adding unicorn to
> Gemfile better.

jhass: "Adding unicorn to the Gemfile eases installation by taking a
step out of it, allows site local installation of it
(--path/--deployment) and ensures the right version so our
integrations (config/unicorn.rb, config/eye.rb, script/server) don't
break."

With debian packaging, our aim is to get a user setup an application
like gitlab or diaspora, just using the package manager they are
already familiar with. They don't have to know what language it is
written, what framework or application server or what database it is
using, all they are interested is the application specific configuration
.

How much compatibility we can expect for config/unicorn.rb?

>>> gitlab and diaspora has unicorn in their Gemfile, for a user
>>> they want gitlab or diaspora and they don't care if its using
>>> unicorn or puma or passenger.
>>> 
>>> I need some kind of an official statement about compatibility 
>>> which I can show to projects like gitlab and diaspora, so they 
>>> don't insist on exact patch release of unicorn. I could patch
>>> the Gemfile, but that adds extra burden on me as a maintainer
>>> which I'd like to avoid if possible.
> 
>> "Official statements" do not have much weight behind them;
>> history does.
> 
>> They can look at the git history (especially that of manpages and
>>  documentation) to see the only feature removals were for 
>> undocumented cruft.
> 
> jhass, can we relax unicorn dependency to ~> 4.9?
> 
>> Personally, I intensely dislike "official" things; so people 
>> shouldn't take what I (or anybody) writes as gospel.
> 
> 
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCAAGBQJWDRZyAAoJEM4fnGdFEsIq+HsP/1T373t8YXTm0e+EAwJxcGaH
SpSdhDrZGcz9oI3vmwx8N1dX86/28hZzU5TEwi/xB4KN/Xzd+fZwTp1lpwTMcEI9
rSUPnknDo8FatT17fg6B99RmB30uIRbIgVgzfUIj30LL0bGC0ulVlVZEZ95jURb4
YVwXuxgRUH5gV7Ql/LpkBnnTni6kgy9Jsrq7ShaaxGNY2NsMrV3hAeN2aSuSJNU/
jUOZCjXzoDKdGS/pfdPTOdAHVSzKtnJ9cZhktBPbSmvHrJ0Zx7Di6zG8TJAQO+EG
n3qlR/ghke4MzNWIprVcqxH37ML6ww913UBCyVRGNOtU+c2/sEd+AlyIjBIzRK9n
Nq5jpcAd5doJHgfIesTxWSX4QhjH6XPqPpbMvIFEwHHpiv8lNi/+Rp5mTFAHiEJY
zEQCSOQmOBiLY56q/e/OVnK+L+6s9gCxYkynzsmgfrJ0HjBd9DNENMpKgboUj3sN
8I+CqerNq3h4lSvnAyb9pdUiAmSv+uD4aMXtgCltWlcC2cNQL51w6OKBO8+hKMuw
uKFihtyUkSD/51e4vmx5lVmz0+7vXPY1CyezbreX50V/zJcYMhJy0Cg42L+BGEWu
8lqrLxoCxua7j5p+hya1D0xuCvQ9eVKmfA2oXwJ7ChR6ZdACMfV6vn47UzYXIyBk
7HbtK7HFc7QVuC3Xg/e8
=JLvl
-----END PGP SIGNATURE-----

^ permalink raw reply	[relevance 0%]

* Re: Request to follow SemVer/mention it in homepage
  2015-09-30 19:51  7%         ` Eric Wong
@ 2015-10-01  4:56  0%           ` Pirate Praveen
  2015-10-01 11:18  0%             ` Pirate Praveen
  0 siblings, 1 reply; 200+ results
From: Pirate Praveen @ 2015-10-01  4:56 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public, Jonne Haß

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

[copying jhass, maintainer of diaspora]

jhass, they prefer email to issue tracker so I copied you here.

You can see the complete discussion here
http://bogomips.org/unicorn-public/560A31F1.3060608%40debian.org/t/#u

On Thursday 01 October 2015 01:21 AM, Eric Wong wrote:
> Pirate Praveen <praveen@debian.org> wrote:
>> Can you mention the recommended way of adding unicorn in a
>> Gemfile in your home page?
> 
> I'm not very knowledgeable about bundler, but app servers probably 
> should not be in any packaged Gemfile at all.

May be jhass can explain the rationale for adding unicorn to Gemfile
better.

>> gitlab and diaspora has unicorn in their Gemfile, for a user they
>> want gitlab or diaspora and they don't care if its using unicorn
>> or puma or passenger.
>> 
>> I need some kind of an official statement about compatibility
>> which I can show to projects like gitlab and diaspora, so they
>> don't insist on exact patch release of unicorn. I could patch the
>> Gemfile, but that adds extra burden on me as a maintainer which
>> I'd like to avoid if possible.
> 
> "Official statements" do not have much weight behind them; history
> does.
> 
> They can look at the git history (especially that of manpages and 
> documentation) to see the only feature removals were for
> undocumented cruft.

jhass, can we relax unicorn dependency to ~> 4.9?

> Personally, I intensely dislike "official" things; so people
> shouldn't take what I (or anybody) writes as gospel.
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCAAGBQJWDLz7AAoJEM4fnGdFEsIqN5MQAKEWGiI3IBfOYmquIplkG/7E
5gohMKsCDJlj6lgqaPIHzvekIW7ssNlxKv9cmeA/v+uNNCKZw6OEw4dmkfJHq5VV
mQ+bBCKkymTFR7ZrIWIs43D0E4To4Sf5LD6MpECiQI1MypFoy66rl0FqJR9PQcF0
nPqcI8LDEICePZwgPdeRrTrS4vCfr4U+BmQWuYovIjwAGEoslnNeblKE+q4LcnGu
09XWelo8eYL62EI6XB92KWCFx0isiEBGQK0PzLqZUbWz17Y7kNMxeAnfmPZQFoe5
4qI7SEtSusFU3OW2t6Eyj6/bh+hP7W2jtMnub+B+QBBUqjf50WV0p4FqUUXMzheS
wDJbtVdYNbNO4f6cWLMVGC18jOVzJw86luc+QoxptTCShku+gFROrkA4w+ciHpNk
2x92Z/S2ejYZlJKGhH97KqMe2gAKgikwYk2zgjSLtpxxrAPiE2nP3tX5KKOG7BNO
iUPdftzLD04oEr21QMb/gRpCEP0f8zsECK/vkpB4VjfjM9HhgEDJZzOfOTvHs04b
avILU6iTUQkSMcWhtdp8bxsifhD+sSjhThWbbMyomV9LdjVBf9gf3J4pzTALT5Rf
rc+V0Gf+dScHpSFMphY7Y7vKuS/PjKvLq1qD2rAsOtDVPDxVT99HsVTUUNR6lAY0
eHegzfNqE/oqHosK1dLN
=AglS
-----END PGP SIGNATURE-----

^ permalink raw reply	[relevance 0%]

* Re: Request to follow SemVer/mention it in homepage
  @ 2015-09-30 19:51  7%         ` Eric Wong
  2015-10-01  4:56  0%           ` Pirate Praveen
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2015-09-30 19:51 UTC (permalink / raw)
  To: Pirate Praveen; +Cc: unicorn-public

Pirate Praveen <praveen@debian.org> wrote:
> Can you mention the recommended way of adding unicorn in a Gemfile in
> your home page?

I'm not very knowledgeable about bundler, but app servers probably
should not be in any packaged Gemfile at all.

> gitlab and diaspora has unicorn in their Gemfile, for a user they want
> gitlab or diaspora and they don't care if its using unicorn or puma or
> passenger.
> 
> I need some kind of an official statement about compatibility which I
> can show to projects like gitlab and diaspora, so they don't insist on
> exact patch release of unicorn. I could patch the Gemfile, but that
> adds extra burden on me as a maintainer which I'd like to avoid if
> possible.

"Official statements" do not have much weight behind them; history does.

They can look at the git history (especially that of manpages and
documentation) to see the only feature removals were for undocumented
cruft.

Personally, I intensely dislike "official" things; so people shouldn't
take what I (or anybody) writes as gospel.

^ permalink raw reply	[relevance 7%]

* Re: Request to follow SemVer/mention it in homepage
  @ 2015-09-29 19:43  7%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-09-29 19:43 UTC (permalink / raw)
  To: Jérémy Lecour; +Cc: Pirate Praveen, unicorn-public

Jérémy Lecour <jeremy.lecour@gmail.com> wrote:
> On Tue, Sep 29, 2015 at 9:36 AM, Eric Wong <e@80x24.org> wrote:
> > Tying a Rack app to unicorn is totally, completely wrong and defeats the
> > point of Rack.
> 
> I completely agree with that statement.
> 
> However, having an app with hard dependency on a specific app server
> is not the same a providing a default setup for a given app server.
> 
> For example, an app like Gitlab, Discourse or whatever might provide a
> default good configuration for Unicorn, a set of optimisations in the
> context of a Unicorn (pre/post fork instructions…) and have something
> that works great out of the box, even if it's not restricted to
> Unicorn.

Right, Debian has Recommends/Suggests: fields for soft dependencies; but
I still consider that overkill.

> Someone who would want to change to Passenger, Puma or else would have
> to adapt the configuration and port the optimizations, but the app
> would work the same as with Unicorn, without crippled features.
> Someone who wouldn't change or tweak anything would have a good
> setting by default.

Perhaps there could be per-server Debian packages such as:

	gitlab-webrick  (should be the default)
	gitlab-puma
	gitlab-passenger
	gitlab-unicorn
	...

Given unicorn has always required the use of nginx for exposure to
public clients, unicorn is perhaps the worst choice as a default
server for people unwilling to read documentation and edit config
files.

^ permalink raw reply	[relevance 7%]

* Re: Unicorn returns blank page after no use
  @ 2015-07-01 17:30  6% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-07-01 17:30 UTC (permalink / raw)
  To: Farjad Adamjee; +Cc: unicorn-public

Farjad Adamjee <fadamjee@vailsys.com> wrote:
> Hello,
> 
> I am not sure if this is the correct place for this, I have googled
> around to see if anyone else has encountered such an issue, but I
> did not find anything.

This is the correct place :)  Plain-text email is the only way I
handle support for ease-of-archival and distribution.

> I am having this issue where after a period of time of no use (on
> beta [production] environment), maybe 12 hours or so, the unicorn
> process sleeps. When I go and re-request the page, it returns blank.

This sounds like a database (or any other persistent connection
backend) connection expiring due to an idle timeout.

This could also be a firewall/router timeout problem between the
server running unicorn and the database host.

Tony experienced this last year:
http://bogomips.org/unicorn-public/m/CAKM1sPNRsES6H6ByK6bO9Djwa8WvYV6HJ-rEaHopRUYBVFfuhg@mail.gmail.com

You can confirm by running lsof on a worker processes to look for
open sockets.  In case the connection loss isn't noticed by the
OS, use strace (or any other similar syscall tracer for your OS)
instead and watch connection activity.

With strace (or similar) knock yourself down to one worker
process via SIGTTOU to the master to ensure you're always tracing
the correct one.

> I am using Apache proxy to Unicorn.

By the way, this is not recommended for slow clients.
nginx (Open Source edition) is currently the only supported proxy.

>   # Using this method we get 0 downtime deploys.
>   defined?(ActiveRecord::Base) and
> ActiveRecord::Base.connection.disconnect!
>   defined?(OathKeeper) and OathKeeper.disconnect!

I suggest disabling any idle timeout you might have, enabling TCP
keepalive and enabling reconnects (see AR and your database driver
documentation).  Worst case (firewall/router problem you can't
fix via configuration), is to send a request to unicorn every
few minutes/hours to keep things going.

Perhaps OathKeeper has the same problem, too...
I've never heard of it until now.

^ permalink raw reply	[relevance 6%]

* [PATCH] doc: update some invalid URLs
@ 2015-06-26  0:47 20% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-06-26  0:47 UTC (permalink / raw)
  To: unicorn-public

Most of these were found by the `linkchecker' package
in Debian.
---
 Documentation/unicorn.1.txt       | 4 ++--
 Documentation/unicorn_rails.1.txt | 4 ++--
 KNOWN_ISSUES                      | 4 ++--
 Links                             | 3 ++-
 README                            | 2 +-
 SIGNALS                           | 2 +-
 Sandbox                           | 6 +++---
 lib/unicorn/http_server.rb        | 3 ++-
 8 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index b03962e..193860f 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
@@ -180,6 +180,6 @@ startup, otherwise the socket will be closed.
 * [Rackup HowTo][3]
 
 [1]: http://unicorn.bogomips.org/
-[2]: http://rdoc.info/gems/r#/gems/rack/frames
-[3]: http://wiki.github.com/rack/rack/tutorial-rackup-howto
+[2]: http://www.rubydoc.info/github/rack/rack/
+[3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
 [4]: http://unicorn.bogomips.org/SIGNALS.html
diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt
index c5db3a1..bff703e 100644
--- a/Documentation/unicorn_rails.1.txt
+++ b/Documentation/unicorn_rails.1.txt
@@ -170,6 +170,6 @@ used by Unicorn.
 * [Rackup HowTo][3]
 
 [1]: http://unicorn.bogomips.org/
-[2]: http://rdoc.info/gems/r#/gems/rack/frames
-[3]: http://wiki.github.com/rack/rack/tutorial-rackup-howto
+[2]: http://www.rubydoc.info/github/rack/rack/
+[3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
 [4]: http://unicorn.bogomips.org/SIGNALS.html
diff --git a/KNOWN_ISSUES b/KNOWN_ISSUES
index 69e4f57..1950223 100644
--- a/KNOWN_ISSUES
+++ b/KNOWN_ISSUES
@@ -38,7 +38,7 @@ acceptable solution.  Those issues are documented here.
   after_fork hook to get correct random number generation.  We have a builtin
   workaround for this starting with \Unicorn 3.6.1
 
-  See http://redmine.ruby-lang.org/issues/show/4338
+  See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/36450
 
 * On Ruby 1.8 prior to Ruby 1.8.7-p248, *BSD platforms have a broken
   stdio that causes failure for file uploads larger than 112K.  Upgrade
@@ -49,7 +49,7 @@ acceptable solution.  Those issues are documented here.
   "Kernel.rand" in your after_fork hook to reinitialize the random
   number generator.
 
-  See http://redmine.ruby-lang.org/issues/show/2962 for more details
+  See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/28655
 
 * Rails 2.3.2 bundles its own version of Rack.  This may cause subtle
   bugs when simultaneously loaded with the system-wide Rack Rubygem
diff --git a/Links b/Links
index 5e868fd..5a586c1 100644
--- a/Links
+++ b/Links
@@ -34,7 +34,8 @@ or services behind them.
 * {Rack}[http://rack.github.io/] - a minimal interface between webservers
   supporting Ruby and Ruby frameworks
 
-* {Ruby}[http://www.ruby-lang.org/] - the programming language of Rack and \Unicorn
+* {Ruby}[https://www.ruby-lang.org/en/] - the programming language of
+  Rack and \Unicorn
 
 * {nginx}[http://nginx.org/] - the reverse proxy for use with \Unicorn
 
diff --git a/README b/README
index f084d0c..bd626e9 100644
--- a/README
+++ b/README
@@ -10,7 +10,7 @@ both the the request and response in between \Unicorn and slow clients.
 
 * Designed for Rack, Unix, fast clients, and ease-of-debugging.  We
   cut out everything that is better supported by the operating system,
-  {nginx}[http://nginx.net/] or {Rack}[http://rack.github.io/].
+  {nginx}[http://nginx.org/] or {Rack}[http://rack.github.io/].
 
 * Compatible with Ruby 1.9.3 and later.
   unicorn 4.8.x will remain supported for Ruby 1.8 users.
diff --git a/SIGNALS b/SIGNALS
index ef0b0d9..4d78065 100644
--- a/SIGNALS
+++ b/SIGNALS
@@ -3,7 +3,7 @@
 In general, signals need only be sent to the master process.  However,
 the signals Unicorn uses internally to communicate with the worker
 processes are documented here as well.  With the exception of TTIN/TTOU,
-signal handling matches the behavior of {nginx}[http://nginx.net/] so it
+signal handling matches the behavior of {nginx}[http://nginx.org/] so it
 should be possible to easily share process management scripts between
 Unicorn and nginx.
 
diff --git a/Sandbox b/Sandbox
index f662b27..a6c3fe7 100644
--- a/Sandbox
+++ b/Sandbox
@@ -3,8 +3,8 @@
 Since unicorn includes executables and is usually used to start a Ruby
 process, there are certain caveats to using it with tools that sandbox
 RubyGems installations such as
-{Bundler}[http://gembundler.com/] or
-{Isolate}[http://github.com/jbarnette/isolate].
+{Bundler}[http://bundler.io/] or
+{Isolate}[https://github.com/jbarnette/isolate].
 
 == General deployment
 
@@ -58,7 +58,7 @@ the before_exec hook:
 
 If you're using an older Bundler version (0.9.x), you may need to set or
 reset GEM_HOME, GEM_PATH and PATH environment variables in the
-before_exec hook as illustrated by http://gist.github.com/534668
+before_exec hook as illustrated by https://gist.github.com/534668
 
 === Ruby 2.0.0 close-on-exec and SIGUSR2 incompatibility
 
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 9129ed8..3282ec7 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -486,7 +486,8 @@ class Unicorn::HttpServer
     Unicorn::Configurator::RACKUP.clear
     @ready_pipe = @init_listeners = @before_exec = @before_fork = nil
 
-    srand # http://redmine.ruby-lang.org/issues/4338
+    # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/36450
+    srand # remove in unicorn 6
 
     # The OpenSSL PRNG is seeded with only the pid, and apps with frequently
     # dying workers can recycle pids
-- 
EW


^ permalink raw reply related	[relevance 20%]

* [ANN] unicorn 4.9.0 - Rack HTTP server for fast clients and *nix
@ 2015-04-24  3:17  5% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-04-24  3:17 UTC (permalink / raw)
  To: ruby-talk; +Cc: unicorn-public, Mike Mulvaney

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between unicorn and slow clients.

* http://unicorn.bogomips.org/
* public list: unicorn-public@bogomips.org
* mail archives: http://bogomips.org/unicorn-public/
* git clone git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml

Changes:

  unicorn 4.9.0 - TempfileReaper support in Rack 1.6

  This release supports the Rack::TempfileReaper middleware found
  in rack 1.6 for cleaning up disk space used by temporary files.
  We also use Rack::TempfileReaper for cleaning up large temporary
  files buffered with TeeInput.  Users on rack 1.5 and earlier
  will see no changes.

  There's also a bunch of documentation/build system improvements.

  This is likely to be the last Ruby 1.8-compatible release, unicorn 5.x
  will require 1.9.3 or later as well as dropping lots of cruft (the
  stupid "Status:" header in responses being the most notable).

  21 changes backported from master:

        ISSUES: update with mailing list subscription
        FAQ: add entry for Rails autoflush_log
        dev: remove isolate dependency
        unicorn.gemspec: depend on test-unit 3.0
        remove RubyForge and Freecode references
        remove mongrel.rubyforge.org references
        examples: add run_once to before_fork hook example
        t/t0002-parser-error.sh: relax test for rack 1.6.0
        switch docs + website to olddoc
        README: clarify/reduce references to unicorn_rails
        gemspec: fixup olddoc migration
        GNUmakefile: fix clean gem build + reduce build cruft
        doc: update support status for Ruby versions
        fix uninstalled testing and reduce require paths
        test_socket_helper: do not depend on SO_REUSEPORT
        ISSUES: add section for bugs in other projects
        explain 11 byte magic number for self-pipe
        Links: mark Rainbows! as historical, reference yahns
        doc: document UNICORN_FD in manpage
        tee_input: support for Rack::TempfileReaper middleware
        support TempfileReaper in deployment and development envs
-- 
EW

^ permalink raw reply	[relevance 5%]

* unicorn 4.8.x-stable branch pushed to git
@ 2015-04-22 19:02  7% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-04-22 19:02 UTC (permalink / raw)
  To: unicorn-public; +Cc: Mulvaney, Mike

Only backporting documentation + build/test system fixes, but I'll
probably apply and push the TeeInput patch in:
http://bogomips.org/unicorn-public/m/20150422183808.GA5277@dcvr.yhbt.net.txt

The following changes since commit 7087bb7ed5a1b9d9f24069cb92707d086668b6dc:

  unicorn 4.8.3 - the end of an era (2014-05-07 07:49:19 +0000)

are available in the git repository at:

  git://bogomips.org/unicorn 4.8.x-stable

for you to fetch changes up to 548e1e67d314f6ebd17df37ece0ee20632462f6f:

  doc: document UNICORN_FD in manpage (2015-04-22 18:57:39 +0000)

----------------------------------------------------------------
Eric Wong (19):
      ISSUES: update with mailing list subscription
      FAQ: add entry for Rails autoflush_log
      dev: remove isolate dependency
      unicorn.gemspec: depend on test-unit 3.0
      remove RubyForge and Freecode references
      remove mongrel.rubyforge.org references
      examples: add run_once to before_fork hook example
      t/t0002-parser-error.sh: relax test for rack 1.6.0
      switch docs + website to olddoc
      README: clarify/reduce references to unicorn_rails
      gemspec: fixup olddoc migration
      GNUmakefile: fix clean gem build + reduce build cruft
      doc: update support status for Ruby versions
      fix uninstalled testing and reduce require paths
      test_socket_helper: do not depend on SO_REUSEPORT
      ISSUES: add section for bugs in other projects
      explain 11 byte magic number for self-pipe
      Links: mark Rainbows! as historical, reference yahns
      doc: document UNICORN_FD in manpage

 .document                             |  1 -
 .gitignore                            |  4 +-
 .wrongdoc.yml => .olddoc.yml          |  6 ++-
 Documentation/unicorn.1.txt           |  7 ++++
 FAQ                                   | 10 ++++-
 GNUmakefile                           | 71 +++++++++++++----------------------
 HACKING                               | 31 ++++-----------
 ISSUES                                | 46 +++++++++++++++++++++--
 KNOWN_ISSUES                          | 20 +++++-----
 Links                                 |  5 ++-
 README                                | 10 ++---
 Rakefile                              | 44 ----------------------
 Sandbox                               |  2 +-
 examples/unicorn.conf.rb              | 11 ++++++
 lib/unicorn/configurator.rb           |  2 -
 lib/unicorn/http_server.rb            |  6 ++-
 local.mk.sample                       | 59 -----------------------------
 script/isolate_for_tests              | 31 ---------------
 t/GNUmakefile                         |  6 +--
 t/README                              |  2 +-
 t/t0002-parser-error.sh               |  6 +--
 test/exec/test_exec.rb                |  2 +-
 test/test_helper.rb                   |  4 +-
 test/unit/test_http_parser.rb         |  6 +--
 test/unit/test_http_parser_ng.rb      |  2 +-
 test/unit/test_http_parser_xftrust.rb |  2 +-
 test/unit/test_request.rb             |  2 +-
 test/unit/test_response.rb            |  6 +--
 test/unit/test_server.rb              |  6 +--
 test/unit/test_signals.rb             |  2 +-
 test/unit/test_socket_helper.rb       |  8 ++--
 test/unit/test_upload.rb              |  2 +-
 test/unit/test_util.rb                |  2 +-
 unicorn.gemspec                       | 13 +++----
 34 files changed, 167 insertions(+), 270 deletions(-)
 rename .wrongdoc.yml => .olddoc.yml (85%)
 delete mode 100644 local.mk.sample
 delete mode 100755 script/isolate_for_tests

^ permalink raw reply	[relevance 7%]

* [PATCH] doc: document UNICORN_FD in manpage
@ 2015-03-12 22:32 22% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-03-12 22:32 UTC (permalink / raw)
  To: unicorn-public

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
@@ -163,6 +163,13 @@ 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.
+
 # SEE ALSO
 
 * unicorn_rails(1)
-- 
2.3.2.209.gd67f9d5


^ permalink raw reply related	[relevance 22%]

* Re: [PATCH] ISSUES: add section for bugs in other projects
  @ 2015-02-10 17:26 10% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-02-10 17:26 UTC (permalink / raw)
  To: unicorn-public

Squashing the following, since we don't want things sinkholed
or missed:

--- a/ISSUES
+++ b/ISSUES
@@ -6,7 +6,7 @@ submit patches and/or obtain support after you have searched the
 {documentation}[http://unicorn.bogomips.org/].
 
 * No subscription will ever be required to email the public inbox.
-* Please Cc: all participants in a thread, as subscription is optional
+* Cc: all participants in a thread or commit, as subscription is optional
 * Do not {top post}[http://catb.org/jargon/html/T/top-post.html] in replies
 * Quote as little as possible of the message you're replying to
 * Do not send HTML mail, it will likely be flagged as spam
@@ -39,9 +39,13 @@ but their mailing list remains operational.
 
 Uncommon bugs we encounter in the Linux kernel should be Cc:-ed to the
 Linux kernel mailing list (LKML) at mailto:linux-kernel@vger.kernel.org
-and other kernel lists such as mailto:netdev@vger.kernel.org
-(for networking issues).  No subscription is necessary, and the our
-mailing list follows the same conventions as LKML for interopability.
+and subsystem maintainers such as mailto:netdev@vger.kernel.org
+(for networking issues).  It is expected practice to Cc: anybody
+involved with any problematic commits (including those in the
+Signed-off-by: and other trailer lines).  No subscription is necessary,
+and the our mailing list follows the same conventions as LKML for
+interopability.  There is a kernel.org Bugzilla instance, but it is
+ignored by most developers.
 
 Likewise for any rare glibc bugs we might encounter, we should Cc:
 mailto:libc-alpha@sourceware.org

^ permalink raw reply	[relevance 10%]

* [PATCH] GNUmakefile: fix clean gem build + reduce build cruft
@ 2015-02-04 20:16 11% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2015-02-04 20:16 UTC (permalink / raw)
  To: unicorn-public

Ensure we have a NEWS file for building the gem beforehand.
We don't need to polute lib/ with object files, either.
---
 GNUmakefile | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile
index 4c40dc9..8bd63ee 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -57,10 +57,7 @@ $(ext)/Makefile: $(ext)/extconf.rb $(c_files)
 	cd $(@D) && $(RUBY) extconf.rb
 $(ext)/unicorn_http.$(DLEXT): $(ext)/Makefile
 	$(MAKE) -C $(@D)
-lib/unicorn_http.$(DLEXT): $(ext)/unicorn_http.$(DLEXT)
-	@mkdir -p lib
-	install -m644 $< $@
-http: lib/unicorn_http.$(DLEXT)
+http: $(ext)/unicorn_http.$(DLEXT)
 
 test-install: $(test_prefix)/.stamp
 $(test_prefix)/.stamp: $(inst_deps)
@@ -85,6 +82,7 @@ test-unit: $(wildcard test/unit/test_*.rb)
 $(slow_tests): $(test_prefix)/.stamp
 	@$(MAKE) $(shell $(awk_slow) $@)
 
+# ensure we can require just the HTTP parser without the rest of unicorn
 test-require: $(ext)/unicorn_http.$(DLEXT)
 	$(RUBY) --disable-gems -I$(ext) -runicorn_http -e Unicorn
 
@@ -134,7 +132,6 @@ $(T): $(test_prefix)/.stamp
 
 install: $(bins) $(ext)/unicorn_http.c
 	$(prep_setup_rb)
-	$(RM) lib/unicorn_http.$(DLEXT)
 	$(RM) -r .install-tmp
 	mkdir .install-tmp
 	cp -p bin/* .install-tmp
@@ -150,7 +147,7 @@ prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C $(ext) clean
 clean:
 	-$(MAKE) -C $(ext) clean
 	-$(MAKE) -C Documentation clean
-	$(RM) $(ext)/Makefile lib/unicorn_http.$(DLEXT)
+	$(RM) $(ext)/Makefile
 	$(RM) $(setup_rb_files) $(t_log)
 	$(RM) -r $(test_prefix) man
 
@@ -160,7 +157,10 @@ man html:
 pkg_extra := GIT-VERSION-FILE lib/unicorn/version.rb LATEST NEWS \
              $(ext)/unicorn_http.c $(man1_paths)
 
-.manifest: $(ext)/unicorn_http.c man
+NEWS:
+	$(OLDDOC) prepare
+
+.manifest: $(ext)/unicorn_http.c man NEWS
 	(git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
 	  LC_ALL=C sort > $@+
 	cmp $@+ $@ || mv $@+ $@
-- 
EW


^ permalink raw reply related	[relevance 11%]

* Re: No, passenger 5.0 is not faster than unicorn :)
  2014-12-03 11:00  5% ` Hongli Lai
  2014-12-03 11:05  0%   ` Sam Saffron
@ 2014-12-03 14:10  0%   ` Bráulio Bhavamitra
  1 sibling, 0 replies; 200+ results
From: Bráulio Bhavamitra @ 2014-12-03 14:10 UTC (permalink / raw)
  To: Hongli Lai; +Cc: unicorn-public, Hitendra Hugo Melo

Hello Hongli,

Thank you the guide, I've already learned a bit from it.

We already use nginx for static files and ssl and varnish for caching
public pages, so maybe turbocaching won't help too much.

In this test I've tested passenger in standalone mode (--max-pool-size
1) and unicorn with one worker. On a slow page, the variation was
minimal (~8.26 req/s in unicorn and ~8.11 in passenger). I haven't
tested fast and cacheable page.

Also, I've used ab for benchmarking. Next time will try wrk.

cheers,
bráulio

On Wed, Dec 3, 2014 at 8:00 AM, Hongli Lai <hongli@phusion.nl> wrote:
> Unicorn *is* in general very good and very efficient, no doubt about that.
> Eric Wong has made great design choices and is an excellent programmer.
>
> Having said that, in certain specific cases there's still room for
> improvement. That's why we focused so much on microoptimizations and
> specific optimizations like turbocaching. Have you followed Phusion
> Passenger's Server Optimization Guide?
> https://www.phusionpassenger.com/documentation/ServerOptimizationGuide.html
>
> Also, you have to ensure that your Rails app sets the correct caching
> headers. By default, Rails sets "Cache-Control: private, no-store" so that
> the turbocache cannot kick in. You should see very different results if you
> add "headers['Cache-Control'] = 'public'" to your Rails app. If you need any
> help with this, please feel free to contact me off-list. I'd be happy to
> help. We have also a benchmarking kit so that you can double check the
> results; email me if you're interested in this.
>
> As Sam said, most of the time will be spent in the Rails app. But
> turbocaching is one notable exception: it's the one feature that can speed
> things up even if your app is slow - provided that you set HTTP caching
> headers correctly.
>
> Unicorn is excellent at what it does: it's a minimal server with a specific
> I/O model that is supposed to be used behind a buffering reverse proxy.
> There is nothing wrong with that, and for the workloads that it's designed
> for, it's great. Phusion Passenger has merely chosen a non-generalist
> approach that aims to squeeze additional performance from specific cases. Of
> course, nothing's a silver bullet. Like any tool, it only works if you use
> it correctly.
>
> On Wed, Dec 3, 2014 at 10:50 AM, Bráulio Bhavamitra <braulio@eita.org.br>
> wrote:
>>
>> Hello all,
>>
>> I've just tested a one instance each (one worker with unicorn and
>> --max-pool-size 1 passenger 5) on the rails app I work.
>>
>> And the results are just as I expected, no miracle at all: Unicorn is
>> still the fatest!
>> (the difference is only a few milliseconds less per request)
>>
>> The blocking design of unicorn is proving itself very efficient.
>>
>> cheers!
>> bráulio
>>
>
>
>
> --
> Phusion | Web Application deployment, scaling, and monitoring solutions
>
> Web: http://www.phusion.nl/
> E-mail: info@phusion.nl
> Chamber of commerce no: 08173483 (The Netherlands)



-- 
"Lute pela sua ideologia. Seja um com sua ideologia. Viva pela sua
ideologia. Morra por sua ideologia" P.R. Sarkar

EITA - Educação, Informação e Tecnologias para Autogestão
http://cirandas.net/brauliobo
http://eita.org.br

"Paramapurusha é meu pai e Parama Prakriti é minha mãe. O universo é
meu lar e todos nós somos cidadãos deste cosmo. Este universo é a
imaginação da Mente Macrocósmica, e todas as entidades estão sendo
criadas, preservadas e destruídas nas fases de extroversão e
introversão do fluxo imaginativo cósmico. No âmbito pessoal, quando
uma pessoa imagina algo em sua mente, naquele momento, essa pessoa é a
única proprietária daquilo que ela imagina, e ninguém mais. Quando um
ser humano criado mentalmente caminha por um milharal também
imaginado, a pessoa imaginada não é a propriedade desse milharal, pois
ele pertence ao indivíduo que o está imaginando. Este universo foi
criado na imaginação de Brahma, a Entidade Suprema, por isso a
propriedade deste universo é de Brahma, e não dos microcosmos que
também foram criados pela imaginação de Brahma. Nenhuma propriedade
deste mundo, mutável ou imutável, pertence a um indivíduo em
particular; tudo é o patrimônio comum de todos."
Restante do texto em
http://cirandas.net/brauliobo/blog/a-problematica-de-hoje-em-dia

^ permalink raw reply	[relevance 0%]

* Re: No, passenger 5.0 is not faster than unicorn :)
  2014-12-03 11:00  5% ` Hongli Lai
@ 2014-12-03 11:05  0%   ` Sam Saffron
  2014-12-03 14:10  0%   ` Bráulio Bhavamitra
  1 sibling, 0 replies; 200+ results
From: Sam Saffron @ 2014-12-03 11:05 UTC (permalink / raw)
  To: Hongli Lai; +Cc: Bráulio Bhavamitra, unicorn-public, Hitendra Hugo Melo

Yeah, anonymous caching is super critical, we monkey it in here:
https://github.com/discourse/discourse/blob/master/lib/middleware/anonymous_cache.rb
to be honest this really should be part of rails.

On Wed, Dec 3, 2014 at 10:00 PM, Hongli Lai <hongli@phusion.nl> wrote:
> Unicorn *is* in general very good and very efficient, no doubt about that.
> Eric Wong has made great design choices and is an excellent programmer.
>
> Having said that, in certain specific cases there's still room for
> improvement. That's why we focused so much on microoptimizations and
> specific optimizations like turbocaching. Have you followed Phusion
> Passenger's Server Optimization Guide?
> https://www.phusionpassenger.com/documentation/ServerOptimizationGuide.html
>
> Also, you have to ensure that your Rails app sets the correct caching
> headers. By default, Rails sets "Cache-Control: private, no-store" so that
> the turbocache cannot kick in. You should see very different results if you
> add "headers['Cache-Control'] = 'public'" to your Rails app. If you need
> any help with this, please feel free to contact me off-list. I'd be happy
> to help. We have also a benchmarking kit so that you can double check the
> results; email me if you're interested in this.
>
> As Sam said, most of the time will be spent in the Rails app. But
> turbocaching is one notable exception: it's the one feature that can speed
> things up even if your app is slow - provided that you set HTTP caching
> headers correctly.
>
> Unicorn is excellent at what it does: it's a minimal server with a specific
> I/O model that is supposed to be used behind a buffering reverse proxy.
> There is nothing wrong with that, and for the workloads that it's designed
> for, it's great. Phusion Passenger has merely chosen a non-generalist
> approach that aims to squeeze additional performance from specific cases.
> Of course, nothing's a silver bullet. Like any tool, it only works if you
> use it correctly.
>
> On Wed, Dec 3, 2014 at 10:50 AM, Bráulio Bhavamitra <braulio@eita.org.br>
> wrote:
>
>> Hello all,
>>
>> I've just tested a one instance each (one worker with unicorn and
>> --max-pool-size 1 passenger 5) on the rails app I work.
>>
>> And the results are just as I expected, no miracle at all: Unicorn is
>> still the fatest!
>> (the difference is only a few milliseconds less per request)
>>
>> The blocking design of unicorn is proving itself very efficient.
>>
>> cheers!
>> bráulio
>>
>>
>
>
> --
> Phusion | Web Application deployment, scaling, and monitoring solutions
>
> Web: http://www.phusion.nl/
> E-mail: info@phusion.nl
> Chamber of commerce no: 08173483 (The Netherlands)
>
>

^ permalink raw reply	[relevance 0%]

* Re: No, passenger 5.0 is not faster than unicorn :)
  @ 2014-12-03 11:00  5% ` Hongli Lai
  2014-12-03 11:05  0%   ` Sam Saffron
  2014-12-03 14:10  0%   ` Bráulio Bhavamitra
  0 siblings, 2 replies; 200+ results
From: Hongli Lai @ 2014-12-03 11:00 UTC (permalink / raw)
  To: Bráulio Bhavamitra; +Cc: unicorn-public, Hitendra Hugo Melo

Unicorn *is* in general very good and very efficient, no doubt about that.
Eric Wong has made great design choices and is an excellent programmer.

Having said that, in certain specific cases there's still room for
improvement. That's why we focused so much on microoptimizations and
specific optimizations like turbocaching. Have you followed Phusion
Passenger's Server Optimization Guide?
https://www.phusionpassenger.com/documentation/ServerOptimizationGuide.html

Also, you have to ensure that your Rails app sets the correct caching
headers. By default, Rails sets "Cache-Control: private, no-store" so that
the turbocache cannot kick in. You should see very different results if you
add "headers['Cache-Control'] = 'public'" to your Rails app. If you need
any help with this, please feel free to contact me off-list. I'd be happy
to help. We have also a benchmarking kit so that you can double check the
results; email me if you're interested in this.

As Sam said, most of the time will be spent in the Rails app. But
turbocaching is one notable exception: it's the one feature that can speed
things up even if your app is slow - provided that you set HTTP caching
headers correctly.

Unicorn is excellent at what it does: it's a minimal server with a specific
I/O model that is supposed to be used behind a buffering reverse proxy.
There is nothing wrong with that, and for the workloads that it's designed
for, it's great. Phusion Passenger has merely chosen a non-generalist
approach that aims to squeeze additional performance from specific cases.
Of course, nothing's a silver bullet. Like any tool, it only works if you
use it correctly.

On Wed, Dec 3, 2014 at 10:50 AM, Bráulio Bhavamitra <braulio@eita.org.br>
wrote:

> Hello all,
>
> I've just tested a one instance each (one worker with unicorn and
> --max-pool-size 1 passenger 5) on the rails app I work.
>
> And the results are just as I expected, no miracle at all: Unicorn is
> still the fatest!
> (the difference is only a few milliseconds less per request)
>
> The blocking design of unicorn is proving itself very efficient.
>
> cheers!
> bráulio
>
>


-- 
Phusion | Web Application deployment, scaling, and monitoring solutions

Web: http://www.phusion.nl/
E-mail: info@phusion.nl
Chamber of commerce no: 08173483 (The Netherlands)


^ permalink raw reply	[relevance 5%]

* Re: Having issue with Unicorn
  @ 2014-10-24 18:02  4%   ` Imdad
  0 siblings, 0 replies; 200+ results
From: Imdad @ 2014-10-24 18:02 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

Thanks Eric, here is my deploy.rb and config/unicorn.rb
NOTE: /releases/6 and /releases/28 both have same error message

config/unicorn.rb
==============
# Set your full path to application.
app_dir = File.expand_path('../../', __FILE__)
shared_dir = File.expand_path('../../../shared/', __FILE__)

# Set unicorn options
worker_processes 2
preload_app true
timeout 30

# Fill path to your app
working_directory app_dir

# Set up socket location
listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64

# Loging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"

# Set master PID location
pid "#{shared_dir}/pids/unicorn.pid"

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = "#{app_dir}/Gemfile"
end

deploy.rb
==========
require 'mina/bundler'
require 'mina/rails'
require 'mina/git'
require 'mina/rbenv'  # for rbenv support. (http://rbenv.org)
# require 'mina/rvm'    # for rvm support. (http://rvm.io)
# TODO: Look into this later
#require 'mina_sidekiq/tasks'
require 'mina/unicorn'


# Basic settings:
#   domain       - The hostname to SSH to.
#   deploy_to    - Path to deploy into.
#   repository   - Git repo to clone from. (needed by mina/git)
#   branch       - Branch name to deploy. (needed by mina/git)
set_default :rbenv_path, "/root/.rbenv" #{}"/root/.rbenv"
#set_default :bundle_path, '/root/.rbenv/shims/bundle'
#set_default :bundle_bin, 'bundle exec'

set :domain, '104.131.74.69'

set :deploy_to, '/var/www/hailisys'

set :repository, 'https://gitlab.com/hailisys/hailisys.git'
set :branch, 'master'
set :user, 'root'
set :forward_agent, true
# MOIN: Fix Password issue
set :term_mode, nil
# MOIN: Could be staging, production
set :rails_env, 'production'
set :port, '22'
set :unicorn_pid, "#{deploy_to}/shared/pids/unicorn.pid"

# For system-wide RVM install.
#   set :rvm_path, '/usr/local/rvm/bin/rvm'

# Manually create these paths in shared/ (eg: shared/config/database.yml)
in your server.
# They will be linked in the 'deploy:link_shared_paths' step.
set :shared_paths, ['config/database.yml', 'log']

# Optional settings:
#   set :user, 'foobar'    # Username in the server to SSH to.
#   set :port, '30000'     # SSH port number.
#   set :forward_agent, true     # SSH forward_agent.

# This task is the environment that is loaded for most commands, such as
# `mina deploy` or `mina rake`.
task :environment do
  # If you're using rbenv, use this to load the rbenv environment.
  # Be sure to commit your .rbenv-version to your repository.
  invoke :'rbenv:load'

  # For those using RVM, use this to load an RVM version@gemset.
  # invoke :'rvm:use[ruby-1.9.3-p125@default]'
end

# Put any custom mkdir's in here for when `mina setup` is ran.
# For Rails apps, we'll make some of the shared paths that are shared
between
# all releases.

task :setup => :environment do
  queue! %[mkdir -p "#{deploy_to}/shared/log"]
  queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"]

  queue! %[mkdir -p "#{deploy_to}/shared/config"]
  queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"]

  queue! %[mkdir -p "#{deploy_to}/shared/pids"]
  queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/pids"]

  queue! %[mkdir -p "#{deploy_to}/shared/sockets"]
  queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/sockets"]

  queue! %[touch "#{deploy_to}/shared/config/database.yml"]
  queue  %[echo "-----> Be sure to edit 'shared/config/database.yml'."]

  # sidekiq needs a place to store its pid file and log file
  queue! %[mkdir -p "#{deploy_to}/shared/pids/"]
  queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/pids"]
end

desc "Deploys the current version to the server."
task :deploy => :environment do
  deploy do

    # stop accepting new workers
    # TODO: Look into this later
    # invoke :'sidekiq:quiet'

    # Put things that will set up an empty directory into a fully set-up
    # instance of your project.
    invoke :'git:clone'
    invoke :'deploy:link_shared_paths'
    invoke :'bundle:install'
    invoke :'rails:db_migrate'
    invoke :'rails:assets_precompile'
    invoke :'deploy:cleanup'

    to :launch do
      # Passenger
      # queue "mkdir -p #{deploy_to}/#{current_path}/tmp/"
      # queue "touch #{deploy_to}/#{current_path}/tmp/restart.txt"

      # TODO: Look into this later
      # invoke :'sidekiq:restart'
      invoke :'unicorn:restart'
      #invoke :'unicorn:start'
      #queue "touch #{deploy_to}/tmp/restart.txt"

    end
  end
end

# For help in making your deploy script, see the Mina documentation:
#
#  - http://nadarei.co/mina
#  - http://nadarei.co/mina/tasks
#  - http://nadarei.co/mina/settings
#  - http://nadarei.co/mina/helpers

Please suggest what could be wrong.


Cheers!
Imdad Ali Khan
Mob (0) 9818484057
http://www.linkedin.com/in/imdad

On 24 October 2014 23:15, Eric Wong <e@80x24.org> wrote:

> Imdad <khanimdad@gmail.com> wrote:
> > I have rails4, nginx, unicorn and mona for app deployed
> > http://104.131.74.69/
> >
> > But after deploy hitting on above link results in error, and the log says
> >
> > root@Hailisys:~# tail -n 0 -f
> > /var/www/hailisys/shared/log/unicorn.stderr.log
> > I, [2014-10-24T17:28:53.162084 #15819]  INFO -- : executing
> > ["/var/www/hailisys/releases/6/vendor/bundle/ruby/2.1.0/bin/unicorn",
> "-c",
> > "/var/www/hailisys/current/config/unicorn.rb", "-D", "-E", "production",
> > {11=>#<Kgio::UNIXServer:fd 11>}] (in /var/www/hailisys/releases/28)
>
> You're working inside /releases/28 here...
>
> >
> /var/www/hailisys/current/vendor/bundle/ruby/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:475:in
> > `exec': No such file or directory -
> > /var/www/hailisys/releases/6/vendor/bundle/ruby/2.1.0/bin/unicorn
> > (Errno::ENOENT)
>
> However, it's trying to run out of /releases/6, which I assume is
> old enough to be removed by now.
>
> You should be able to set working_directory in your config/unicorn.rb:
>
>         working_directory "/var/www/hailisys/current"
>
> Then SIGHUP to reload the config before sending SIGUSR2 to it.
>
> Hopefully that works.  Normally you shouldn't need to set
> working_directory if you're working out of "/current";
> but I'm not sure what your deploy environment looks like.
>


^ permalink raw reply	[relevance 4%]

* Re: Master hooks needed
  2014-10-04  2:04  6%           ` Bráulio Bhavamitra
@ 2014-10-04  2:25  0%             ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2014-10-04  2:25 UTC (permalink / raw)
  To: Bráulio Bhavamitra; +Cc: unicorn-public

Bráulio Bhavamitra <braulio@eita.org.br> wrote:
> Documentation is an excelent solution :)

OK, pushed to the website[1] and unicorn.git as
commit 3318b070c6513a3baa7ce7ac26f4835f46ccff1f

    examples: add run_once to before_fork hook example

    There may be code in a before_fork hook which should run only once,
    document an example using a guard variable since it may not be
    immediately obvious to all users.

    Inspired-by: Bráulio Bhavamitra <braulio@eita.org.br>

http://bogomips.org/unicorn-public/m/20141004015707.GA1951@dcvr.yhbt.net.html

[1] http://unicorn.bogomips.org/examples/

^ permalink raw reply	[relevance 0%]

* Re: Master hooks needed
  2014-10-04  1:57  6%         ` Eric Wong
@ 2014-10-04  2:04  6%           ` Bráulio Bhavamitra
  2014-10-04  2:25  0%             ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Bráulio Bhavamitra @ 2014-10-04  2:04 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

Documentation is an excelent solution :)

On Fri, Oct 3, 2014 at 10:57 PM, Eric Wong <e@80x24.org> wrote:
> Bráulio Bhavamitra <braulio@eita.org.br> wrote:
>> I think the hook is needed because I took too much time to figure out
>> the problem and much more time to figure out the solution (this
>> master_run variable). Also, I don't think this master_run solution is
>> elegant.
>
> A guard variable is fairly common practice for initialization.
> It's not always nice, but I do not consider the existing hooks
> to be elegant, either; they're only unfortunately necessary.
>
> I consider having redundant features to be even worse.
>
> How about the following documentation change instead?
>
> --- a/examples/unicorn.conf.rb
> +++ b/examples/unicorn.conf.rb
> @@ -54,12 +54,23 @@ GC.respond_to?(:copy_on_write_friendly=) and
>  # fast LAN.
>  check_client_connection false
>
> +# local variable to guard against running a hook multiple times
> +run_once = true
> +
>  before_fork do |server, worker|
>    # the following is highly recomended for Rails + "preload_app true"
>    # as there's no need for the master process to hold a connection
>    defined?(ActiveRecord::Base) and
>      ActiveRecord::Base.connection.disconnect!
>
> +  # Occasionally, it may be necessary to run non-idempotent code in the
> +  # master before forking.  Keep in mind the above disconnect! example
> +  # is idempotent and does not need a guard.
> +  if run_once
> +    # do_something_once_here ...
> +    run_once = false # prevent from firing again
> +  end
> +
>    # The following is only recommended for memory/DB-constrained
>    # installations.  It is not needed if your system can house
>    # twice as many worker_processes as you have configured.



-- 
"Lute pela sua ideologia. Seja um com sua ideologia. Viva pela sua
ideologia. Morra por sua ideologia" P.R. Sarkar

EITA - Educação, Informação e Tecnologias para Autogestão
http://cirandas.net/brauliobo
http://eita.org.br

"Paramapurusha é meu pai e Parama Prakriti é minha mãe. O universo é
meu lar e todos nós somos cidadãos deste cosmo. Este universo é a
imaginação da Mente Macrocósmica, e todas as entidades estão sendo
criadas, preservadas e destruídas nas fases de extroversão e
introversão do fluxo imaginativo cósmico. No âmbito pessoal, quando
uma pessoa imagina algo em sua mente, naquele momento, essa pessoa é a
única proprietária daquilo que ela imagina, e ninguém mais. Quando um
ser humano criado mentalmente caminha por um milharal também
imaginado, a pessoa imaginada não é a propriedade desse milharal, pois
ele pertence ao indivíduo que o está imaginando. Este universo foi
criado na imaginação de Brahma, a Entidade Suprema, por isso a
propriedade deste universo é de Brahma, e não dos microcosmos que
também foram criados pela imaginação de Brahma. Nenhuma propriedade
deste mundo, mutável ou imutável, pertence a um indivíduo em
particular; tudo é o patrimônio comum de todos."
Restante do texto em
http://cirandas.net/brauliobo/blog/a-problematica-de-hoje-em-dia

^ permalink raw reply	[relevance 6%]

* Re: Master hooks needed
  @ 2014-10-04  1:57  6%         ` Eric Wong
  2014-10-04  2:04  6%           ` Bráulio Bhavamitra
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2014-10-04  1:57 UTC (permalink / raw)
  To: Bráulio Bhavamitra; +Cc: unicorn-public

Bráulio Bhavamitra <braulio@eita.org.br> wrote:
> I think the hook is needed because I took too much time to figure out
> the problem and much more time to figure out the solution (this
> master_run variable). Also, I don't think this master_run solution is
> elegant.

A guard variable is fairly common practice for initialization.
It's not always nice, but I do not consider the existing hooks
to be elegant, either; they're only unfortunately necessary.

I consider having redundant features to be even worse.

How about the following documentation change instead?

--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -54,12 +54,23 @@ GC.respond_to?(:copy_on_write_friendly=) and
 # fast LAN.
 check_client_connection false
 
+# local variable to guard against running a hook multiple times
+run_once = true
+
 before_fork do |server, worker|
   # the following is highly recomended for Rails + "preload_app true"
   # as there's no need for the master process to hold a connection
   defined?(ActiveRecord::Base) and
     ActiveRecord::Base.connection.disconnect!
 
+  # Occasionally, it may be necessary to run non-idempotent code in the
+  # master before forking.  Keep in mind the above disconnect! example
+  # is idempotent and does not need a guard.
+  if run_once
+    # do_something_once_here ...
+    run_once = false # prevent from firing again
+  end
+
   # The following is only recommended for memory/DB-constrained
   # installations.  It is not needed if your system can house
   # twice as many worker_processes as you have configured.

^ permalink raw reply	[relevance 6%]

* Re: Master hooks needed
  2014-10-03 12:22  6% ` Eric Wong
  2014-10-03 12:36  0%   ` Valentin Mihov
@ 2014-10-04  0:53  0%   ` Bráulio Bhavamitra
    1 sibling, 1 reply; 200+ results
From: Bráulio Bhavamitra @ 2014-10-04  0:53 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn-public

The problem is actually worser, and the worker.nr == 0 can't be used.
I had to do something like this:

master_run = true

before_fork do |server, worker|
  if master_run
     #warm up server...

     #kill old pid...

     #disconnect active record

     master_run = false
  end

  # other stuff for each worker
end

In the last example, using worker.nr == 0 would make the server crash
in case the worker 0 was killed/restarted.

Also the AR's disconnect and *many other stuff* people put on
before_fork should only be run once the master was preloaded, not for
every worker.

So I still think at least a hook like master_preloaded(server) is necessary.

cheers,
bráulio

On Fri, Oct 3, 2014 at 9:22 AM, Eric Wong <e@80x24.org> wrote:
> Bráulio Bhavamitra <braulio@eita.org.br> wrote:
>> Hello all,
>>
>> If I need to hook something after master load, I'm currently doing:
>>
>> before_fork do |server, worker|
>>   # worker 0 is the first to init, so hold the master here
>>   if worker.nr == 0
>>      #warm up server...
>>
>>      #kill old pid...
>>   end
>>
>>   # other stuff for each worker
>> end
>>
>> Both operations I currently do (server warm up and old pid kill) need
>> to be run only once, and not for every worker as before_fork does,
>> that's why I had to put the condition seen above.
>
> The above is fine if your first worker never dies.  I think you can add
> a local variable to ensure it only runs the first time worker.nr == 0 is
> started, in case a worker dies.  Something like:
>
>     first = true
>     before_fork do |server, worker|
>       # worker 0 is the first to init, so hold the master here
>       if worker.nr == 0 && first
>          first = false
>          #warm up server...
>
>          #kill old pid...
>       end
>
>       # other stuff for each worker
>     end
>
> For what it's worth, I'm not a fan of auto-killing the old PID in the
> unicorn config and regret having it in the example config.  It's only
> for the most memory-constrained configs and fragile (because anything
> with pid files is always fragile).
>
>> So hooks for master is needed, something like
>> master_after_load(server) and master_init(server).
>>
>> What do you think?
>
> rack.git also has a Rack::Builder#warmup method.  Aman originally
> proposed it for unicorn, but it's useful outside of unicorn so
> we moved it to Rack.
>
> In general, I'm against adding new hooks/options because they tend to
> make maintainability and documentation harder for ops folks.
> I still have nightmares of some Capistrano config filled with hooks
> from years ago :x
>
> Features like these also makes migrating away from unicorn harder, so
> that is another reason we ended up adding #warmup to Rack and not
> unicorn.

^ permalink raw reply	[relevance 0%]

* Re: Master hooks needed
  2014-10-03 12:22  6% ` Eric Wong
@ 2014-10-03 12:36  0%   ` Valentin Mihov
  2014-10-04  0:53  0%   ` Bráulio Bhavamitra
  1 sibling, 0 replies; 200+ results
From: Valentin Mihov @ 2014-10-03 12:36 UTC (permalink / raw)
  To: Eric Wong; +Cc: Bráulio Bhavamitra, unicorn-public

On Fri, Oct 3, 2014 at 3:22 PM, Eric Wong <e@80x24.org> wrote:
>
> Bráulio Bhavamitra <braulio@eita.org.br> wrote:
> > Hello all,
> >
> > If I need to hook something after master load, I'm currently doing:
> >
> > before_fork do |server, worker|
> >   # worker 0 is the first to init, so hold the master here
> >   if worker.nr == 0
> >      #warm up server...
> >
> >      #kill old pid...
> >   end
> >
> >   # other stuff for each worker
> > end
> >
> > Both operations I currently do (server warm up and old pid kill) need
> > to be run only once, and not for every worker as before_fork does,
> > that's why I had to put the condition seen above.
>
> The above is fine if your first worker never dies.  I think you can add
> a local variable to ensure it only runs the first time worker.nr == 0 is
> started, in case a worker dies.  Something like:
>
>     first = true
>     before_fork do |server, worker|
>       # worker 0 is the first to init, so hold the master here
>       if worker.nr == 0 && first
>          first = false
>          #warm up server...
>
>          #kill old pid...
>       end
>
>       # other stuff for each worker
>     end
>
> For what it's worth, I'm not a fan of auto-killing the old PID in the
> unicorn config and regret having it in the example config.  It's only
> for the most memory-constrained configs and fragile (because anything
> with pid files is always fragile).
>
> > So hooks for master is needed, something like
> > master_after_load(server) and master_init(server).
> >
> > What do you think?
>
> rack.git also has a Rack::Builder#warmup method.  Aman originally
> proposed it for unicorn, but it's useful outside of unicorn so
> we moved it to Rack.
>
> In general, I'm against adding new hooks/options because they tend to
> make maintainability and documentation harder for ops folks.
> I still have nightmares of some Capistrano config filled with hooks
> from years ago :x
>
> Features like these also makes migrating away from unicorn harder, so
> that is another reason we ended up adding #warmup to Rack and not
> unicorn.
>

Isn't it much better to do the warmup in an initializer instead in
unicorn? This way you can preload_app=true and the master will execute
the warmup code and fork. Killing the old pid is probably stopping you
from do that, right?

--Valentin

^ permalink raw reply	[relevance 0%]

* Re: Master hooks needed
  @ 2014-10-03 12:22  6% ` Eric Wong
  2014-10-03 12:36  0%   ` Valentin Mihov
  2014-10-04  0:53  0%   ` Bráulio Bhavamitra
  0 siblings, 2 replies; 200+ results
From: Eric Wong @ 2014-10-03 12:22 UTC (permalink / raw)
  To: Bráulio Bhavamitra; +Cc: unicorn-public

Bráulio Bhavamitra <braulio@eita.org.br> wrote:
> Hello all,
> 
> If I need to hook something after master load, I'm currently doing:
> 
> before_fork do |server, worker|
>   # worker 0 is the first to init, so hold the master here
>   if worker.nr == 0
>      #warm up server...
> 
>      #kill old pid...
>   end
> 
>   # other stuff for each worker
> end
> 
> Both operations I currently do (server warm up and old pid kill) need
> to be run only once, and not for every worker as before_fork does,
> that's why I had to put the condition seen above.

The above is fine if your first worker never dies.  I think you can add
a local variable to ensure it only runs the first time worker.nr == 0 is
started, in case a worker dies.  Something like:

    first = true
    before_fork do |server, worker|
      # worker 0 is the first to init, so hold the master here
      if worker.nr == 0 && first
         first = false
         #warm up server...

         #kill old pid...
      end

      # other stuff for each worker
    end

For what it's worth, I'm not a fan of auto-killing the old PID in the
unicorn config and regret having it in the example config.  It's only
for the most memory-constrained configs and fragile (because anything
with pid files is always fragile).

> So hooks for master is needed, something like
> master_after_load(server) and master_init(server).
> 
> What do you think?

rack.git also has a Rack::Builder#warmup method.  Aman originally
proposed it for unicorn, but it's useful outside of unicorn so
we moved it to Rack.

In general, I'm against adding new hooks/options because they tend to
make maintainability and documentation harder for ops folks.
I still have nightmares of some Capistrano config filled with hooks
from years ago :x

Features like these also makes migrating away from unicorn harder, so
that is another reason we ended up adding #warmup to Rack and not
unicorn.

^ permalink raw reply	[relevance 6%]

* Re: Weird Unicorn Timeout Issues (Hibernation problem?)
  2014-08-04 19:45  6%         ` Eric Wong
@ 2014-08-04 20:06  0%           ` Michael Fischer
  0 siblings, 0 replies; 200+ results
From: Michael Fischer @ 2014-08-04 20:06 UTC (permalink / raw)
  To: Eric Wong; +Cc: Tony Devlin, unicorn-public

On Mon, Aug 4, 2014 at 12:45 PM, Eric Wong <e@80x24.org> wrote:

[1] Perhaps persistent connections will be an option in the future
>     if the support/documentation overhead is worth it, as nginx
>     supports persistent connections to backends nowadays.
>

I don't believe the added complexity is worth the effort.

--Michael


^ permalink raw reply	[relevance 0%]

* Re: Weird Unicorn Timeout Issues (Hibernation problem?)
  @ 2014-08-04 19:45  6%         ` Eric Wong
  2014-08-04 20:06  0%           ` Michael Fischer
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2014-08-04 19:45 UTC (permalink / raw)
  To: Tony Devlin; +Cc: unicorn-public

Tony Devlin <tonydevlin@gmail.com> wrote:
> Thank you Eric,
> 
> I will look into the other worker to see what is going on with it.  I still
> appreciate any hints you all can give me on where I can check.   I'm also
> looking into the OS TCP timeouts to see if what Daniel said may be a
> problem.

General rule for me is to get the problem reproducible in the smallest
possible way.  That could mean removing features, cutting out large
chunks of code, cutting out certain request types, reducing
workers.

More things:

1) Can you make sure nginx is not trying to maintain persistent
  connections?  nginx should respect unicorn closing the connection
  but I haven't checked the latest versions of nginx.
  lsof can help here, too.

  unicorn currently does not do persistent connections, allowing
  an M:N relationship between nginx instances and unicorn
  instances[1]

2) Any other odd external dependencies such as NFS mounts,
   file locks, FIFOs, etc?


[1] Perhaps persistent connections will be an option in the future
    if the support/documentation overhead is worth it, as nginx
    supports persistent connections to backends nowadays.

^ permalink raw reply	[relevance 6%]

* Re: Weird Unicorn Timeout Issues (Hibernation problem?)
  @ 2014-08-04 19:34  7%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2014-08-04 19:34 UTC (permalink / raw)
  To: Daniel Condomitti; +Cc: Tony Devlin, unicorn-public

Daniel Condomitti <daniel@condomitti.com> wrote:
> It could also be that your TCP keepalive interval is higher than your
> database server’s connection timeout. I’ve run into that in the past.

That kicks in at around 2 hours by default on Linux systems.
I'm not sure it would matter for Tony's case since he hit it
after ~30 minutes of idle (unless he tuned the knobs himself).

ref: tcp_keep* knobs in
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/ip-sysctl.txt

unicorn itself has no timers outside of the configurable timeout.

^ permalink raw reply	[relevance 7%]

* Re: Please move to github
  @ 2014-08-02 20:15  6%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2014-08-02 20:15 UTC (permalink / raw)
  To: Gary Grossman; +Cc: unicorn-public, michael

Gary Grossman <gary.grossman@gmail.com> wrote:
> We'd pretty much need to introduce some kind of configuration
> switch, at least for the short term and maybe for the long term.
> The hope would be that it could become the default setting.
> Apps that don't use UTF8 should be able to set their desired default
> external encoding appropriately.

If possible, I would like to avoid an option and rely on
Encoding.default_external in a new major version.  Too many ways to set
the same thing is confusing and requires extra documentation overhead.

> >The rack-devel mailing list had a discussion on this in September 2010
> >and a decision was never reached. You can search the archives at:
> >http://groups.google.com/group/rack-devel
> 
> I came across this thread but didn't realize that was the last word
> so far when it came to Rack and encodings.
> 
> This might be one of those instances where it would be helpful for
> implementation to lead specification. Unicorn is one of the leading
> servers of its genre, if not the leader. If you supported a switch
> that made the encoding regime more sane, I think other popular servers
> like Thin and Passenger would swiftly follow and it might re-energize
> the discussion about getting encodings into the Rack spec once and
> for all, and give a base for experimentation and iteration for
> getting the encodings in the spec right.

I might start with WEBrick (or the Rack/WEBrick handler).  WEBrick is
distributed with Ruby and maintained by the core team.  It's not used in
production much, but it the reference implementation which is usable
from all Ruby implementations.

naruse (from that rack-devel thread) is also active in Ruby core and
is very knowledgeable in these areas.

> Thanks again for reviewing the patch. I'll work on a new patch that
> incorporates your comments and has a switch for enabling/disabling
> the functionality, and I'll try to follow roughly what the spec
> group in 2010 thought would make sense in terms of encodings for
> the various strings in the env. And I'll see if I can ask the
> Rack folks to chime in.

Definitely get other Rack folks to chime in, even if it is a
unicorn-only change.  This has been a problem for years already,
so taking more time to get things right won't hurt.

^ permalink raw reply	[relevance 6%]

* handling SMTP subscribers to public-inboxen
  @ 2014-05-07 19:54  6%         ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2014-05-07 19:54 UTC (permalink / raw)
  To: meta
  Cc: Lin Jen-Shin (godfat), Liste Unicorn, Jérémy Lecour,
	Alejandro Riera, Bráulio Bhavamitra, unicorn-public

Alejandro Riera <ariera@gmail.com> wrote:
> "Lin Jen-Shin (godfat)" <godfat@godfat.org> wrote:
> > I guess I am too lazy/busy to dig into this, so an SMTP would be great
> > for me. I am also ok to be listed as a public subscriber.
> 
> Same here, SMTP sounds great :)

Copying discussion to the meta@public-inbox.org list...

Thanks all for your response.  I'll set up something on the ssoma side
which replays messages to subscribers.  This will make it easy to
fork/migrate subscription lists to different servers.

I'll probably use VERP[1] to handle bounces.  However, most of the
normal bounce processing mechanisms (including VERP) seems to leave
users open to malicious unsubscribes.  In other words, an attacker
may fake bounce messages to take users off a list (VERP or not).
The reference documentation for VERP just makes faking bounces
trivially easy.

So I think we need to make the bounce address unguessable by the
attacker.  Perhaps using something like Crypt-VERPString[2] is
necessary?  Keep in mind somebody sniffing your plain-text SMTP traffic
will (and will always) be able to extract the bounce address; so this
only increases the difficulty level to do a malicious unsubscribe.

The secret key should be able to change when migrating between servers
(or if compromised) without being a big problem, as most bounces occur
hours/days within delivery time; not months/years afterwards.

[1] http://cr.yp.to/proto/verp.txt
[2] http://search.cpan.org/dist/Crypt-VERPString

^ permalink raw reply	[relevance 6%]

* Re: [ANN] unicorn 4.8.3 - the end of an era
  2014-05-07  8:05  6% [ANN] unicorn 4.8.3 - the end of an era Eric Wong
  @ 2014-05-07 12:08  0% ` Bráulio Bhavamitra
  1 sibling, 0 replies; 200+ results
From: Bráulio Bhavamitra @ 2014-05-07 12:08 UTC (permalink / raw)
  To: Eric Wong; +Cc: Unicorn, unicorn-public

+1, pushing to ssoma when emails standards empire is very strong is
way too much...

Another mailing list in another server should be created...

regards,
bráulio

On Wed, May 7, 2014 at 5:05 AM, Eric Wong <e@80x24.org> wrote:
> Changes:
>
> This release updates documentation to reflect the migration of the
> mailing list to a new public-inbox[1] instance.  This is necessary
> due to the impending RubyForge shutdown on May 15, 2014.
>
> The public-inbox address is: unicorn-public@bogomips.org
>     (no subscription required, plain text only)
> ssoma[2] git archives: git://bogomips.org/unicorn-public
> browser-friendly archives: http://bogomips.org/unicorn-public/
>
> Using, getting help for, and contributing to unicorn will never
> require any of the following:
>
> 1) non-Free software (including SaaS)
> 2) registration or sign-in of any kind
> 3) a real identity (we accept mail from Mixmaster)
> 4) a graphical user interface
>
> Nowadays, plain-text email is the only ubiquitous platform which
> meets all our requirements for communication.
>
> There is also one small bugfix to handle premature grandparent death
> upon initial startup.  Most users are unaffected.
>
> [1] policy: http://public-inbox.org/ - git://80x24.org/public-inbox
>     an "archives first" approach to mailing lists
> [2] mechanism: http://ssoma.public-inbox.org/ - git://80x24.org/ssoma
>     some sort of mail archiver (using git)
>
> * http://unicorn.bogomips.org/
> * unicorn-public@bogomips.org
> * git://bogomips.org/unicorn.git
> * http://unicorn.bogomips.org/NEWS.atom.xml
>
> --
> Eric Wong
> __
> http://bogomips.org/unicorn-public/ - unicorn-public@bogomips.org
> please quote as little as necessary when replying



-- 
"Lute pela sua ideologia. Seja um com sua ideologia. Viva pela sua
ideologia. Morra por sua ideologia" P.R. Sarkar

EITA - Educação, Informação e Tecnologias para Autogestão
http://cirandas.net/brauliobo
http://eita.org.br

"Paramapurusha é meu pai e Parama Prakriti é minha mãe. O universo é
meu lar e todos nós somos cidadãos deste cosmo. Este universo é a
imaginação da Mente Macrocósmica, e todas as entidades estão sendo
criadas, preservadas e destruídas nas fases de extroversão e
introversão do fluxo imaginativo cósmico. No âmbito pessoal, quando
uma pessoa imagina algo em sua mente, naquele momento, essa pessoa é a
única proprietária daquilo que ela imagina, e ninguém mais. Quando um
ser humano criado mentalmente caminha por um milharal também
imaginado, a pessoa imaginada não é a propriedade desse milharal, pois
ele pertence ao indivíduo que o está imaginando. Este universo foi
criado na imaginação de Brahma, a Entidade Suprema, por isso a
propriedade deste universo é de Brahma, e não dos microcosmos que
também foram criados pela imaginação de Brahma. Nenhuma propriedade
deste mundo, mutável ou imutável, pertence a um indivíduo em
particular; tudo é o patrimônio comum de todos."
Restante do texto em
http://cirandas.net/brauliobo/blog/a-problematica-de-hoje-em-dia

^ permalink raw reply	[relevance 0%]

* [ANN] unicorn 4.8.3 - the end of an era
@ 2014-05-07  8:05  6% Eric Wong
    2014-05-07 12:08  0% ` [ANN] unicorn 4.8.3 - the end of an era Bráulio Bhavamitra
  0 siblings, 2 replies; 200+ results
From: Eric Wong @ 2014-05-07  8:05 UTC (permalink / raw)
  To: mongrel-unicorn; +Cc: unicorn-public

Changes:

This release updates documentation to reflect the migration of the
mailing list to a new public-inbox[1] instance.  This is necessary
due to the impending RubyForge shutdown on May 15, 2014.

The public-inbox address is: unicorn-public@bogomips.org
    (no subscription required, plain text only)
ssoma[2] git archives: git://bogomips.org/unicorn-public
browser-friendly archives: http://bogomips.org/unicorn-public/

Using, getting help for, and contributing to unicorn will never
require any of the following:

1) non-Free software (including SaaS)
2) registration or sign-in of any kind
3) a real identity (we accept mail from Mixmaster)
4) a graphical user interface

Nowadays, plain-text email is the only ubiquitous platform which
meets all our requirements for communication.

There is also one small bugfix to handle premature grandparent death
upon initial startup.  Most users are unaffected.

[1] policy: http://public-inbox.org/ - git://80x24.org/public-inbox
    an "archives first" approach to mailing lists
[2] mechanism: http://ssoma.public-inbox.org/ - git://80x24.org/ssoma
    some sort of mail archiver (using git)

* http://unicorn.bogomips.org/
* unicorn-public@bogomips.org
* git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml

-- 
Eric Wong

^ permalink raw reply	[relevance 6%]

* Re: Issues with PID file renaming
  2013-12-12 19:15  0%           ` Petteri Räty
@ 2013-12-12 20:51  0%             ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2013-12-12 20:51 UTC (permalink / raw)
  To: unicorn list

Petteri Räty <betelgeuse@gentoo.org> wrote:
> On 11.12.2013 15.54, Michael Fischer wrote:
> > On Tue, Dec 10, 2013 at 10:44 PM, Petteri Räty <betelgeuse@gentoo.org> wrote:
> > 
> >> At least for pid based monitoring tools it is (I do agree with others
> >> that you should also be monitoring http though). For example monit
> >> requires that you give it a pid file. Why is it wrong for them to point
> >> to the same pid?
> > 
> > Monit doesn't require a pid, never has:
> > 
> > http://mmonit.com/monit/documentation/monit.html#connection_testing
> > 
> 
> If you only want to do connection testing. What if you want to monitor
> the memory usage of unicorn processes?

Your monitoring has to adapt to the new processes anyways.  Can it
really not deal with a PID file being temporarily absent?

There's a plethora of tools in the wild which deal with PID files.
Consider this case:

It's likely a tool will see foo.pid.oldbin existing, and wait for
foo.pid to become available.  If foo.pid is already available from a
hardlink, it'll be pointing to the old PID, and any tool which backs out
of the upgrade by intending to kill the new PID will end up hitting the
old one.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: Issues with PID file renaming
  2013-12-11 13:54  7%         ` Michael Fischer
@ 2013-12-12 19:15  0%           ` Petteri Räty
  2013-12-12 20:51  0%             ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Petteri Räty @ 2013-12-12 19:15 UTC (permalink / raw)
  To: mongrel-unicorn

On 11.12.2013 15.54, Michael Fischer wrote:
> On Tue, Dec 10, 2013 at 10:44 PM, Petteri Räty <betelgeuse@gentoo.org> wrote:
> 
>> At least for pid based monitoring tools it is (I do agree with others
>> that you should also be monitoring http though). For example monit
>> requires that you give it a pid file. Why is it wrong for them to point
>> to the same pid?
> 
> Monit doesn't require a pid, never has:
> 
> http://mmonit.com/monit/documentation/monit.html#connection_testing
> 

If you only want to do connection testing. What if you want to monitor
the memory usage of unicorn processes?

> To answer your question, though, the reason the pid files must contain
> different PIDs is that the two processes (previous and
> current-generation masters) have different PIDs.  And some of us do
> care that they differ :)
> 

Eric's original comment and my response was about the pid files having
the same content (albeit shortly).

Regards,
Petteri

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: Issues with PID file renaming
  @ 2013-12-11 13:54  7%         ` Michael Fischer
  2013-12-12 19:15  0%           ` Petteri Räty
  0 siblings, 1 reply; 200+ results
From: Michael Fischer @ 2013-12-11 13:54 UTC (permalink / raw)
  To: unicorn list

On Tue, Dec 10, 2013 at 10:44 PM, Petteri Räty <betelgeuse@gentoo.org> wrote:

> At least for pid based monitoring tools it is (I do agree with others
> that you should also be monitoring http though). For example monit
> requires that you give it a pid file. Why is it wrong for them to point
> to the same pid?

Monit doesn't require a pid, never has:

http://mmonit.com/monit/documentation/monit.html#connection_testing

To answer your question, though, the reason the pid files must contain
different PIDs is that the two processes (previous and
current-generation masters) have different PIDs.  And some of us do
care that they differ :)

--Michael
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: What does it mean for the unicorn process to be bound to a terminal?
  2013-11-26 18:35  6%   ` Rodrigo Rosenfeld Rosas
@ 2013-11-26 19:21  0%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2013-11-26 19:21 UTC (permalink / raw)
  To: unicorn list; +Cc: Rodrigo Rosenfeld Rosas

Rodrigo Rosenfeld Rosas <rr.rosas@gmail.com> wrote:
> I see. If I understood correctly this only happens in foreground
> mode, so something like that would help me to understand the
> sentence:

> "...If your unicorn process is bound to an interactive terminal
> (running in the foreground), you can skip this step."

I used "not daemonized", since it's possible for a background process
to have a controlling terminal:

     unicorn ... & # runs background, still attached to terminal
     fg # foreground again

Pushed as fa17da92aa4e76d5fd63cb9b74d6884d611ec899
(also added a link to the init.sh example)
---------------------------8<----------------------------
Subject: [PATCH] doc: clarify SIGNALS and reference init example

"interactive terminal" needed clarification.

While we're at it, link to the init.sh example since it may
be shared with nginx.

Reported-by: Rodrigo Rosenfeld Rosas
ref: <5294E9D4.5030608@gmail.com>
---
 SIGNALS | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/SIGNALS b/SIGNALS
index 8851775..48c651e 100644
--- a/SIGNALS
+++ b/SIGNALS
@@ -7,6 +7,9 @@ signal handling matches the behavior of {nginx}[http://nginx.net/] so it
 should be possible to easily share process management scripts between
 Unicorn and nginx.
 
+One example init script is distributed with unicorn:
+http://unicorn.bogomips.org/examples/init.sh
+
 === Master Process
 
 * HUP - reloads config file and gracefully restart all workers.
@@ -101,8 +104,8 @@ The procedure is exactly like that of nginx:
 
 3. You can now send WINCH to the old master process so only the new workers
    serve requests.  If your unicorn process is bound to an interactive
-   terminal, you can skip this step.  Step 5 will be more difficult but
-   you can also skip it if your process is not daemonized.
+   terminal (not daemonized), you can skip this step.  Step 5 will be more
+   difficult but you can also skip it if your process is not daemonized.
 
 4. You should now ensure that everything is running correctly with the
    new workers as the old workers die off.
---------------------------8<----------------------------
> I believe it would help the documentation if you added a link to
> init.sh in the SIGNALS page:
> 
> http://bogomips.org/unicorn.git/tree/examples/init.sh

> Anyway, even that script won't take care of making sure that the
> reload action will rollback in case of an unsuccessful deploy.
> 
> I realize it's not easy to detect if the deploy was successful and
> that it's very application dependent, but some generic procedures
> would be helpful for a basic Rails application. Unfortunately I
> don't know what would be a good strategy, that's why I asked :P

Right.  Different apps require different validation, especially
those intended for GUI web browsers.

> Thank you for explaining the interactive terminal binding question :)

No problem!
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 0%]

* Re: What does it mean for the unicorn process to be bound to a terminal?
  2013-11-26 18:04  6% ` Eric Wong
@ 2013-11-26 18:35  6%   ` Rodrigo Rosenfeld Rosas
  2013-11-26 19:21  0%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Rodrigo Rosenfeld Rosas @ 2013-11-26 18:35 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

Em 26-11-2013 16:04, Eric Wong escreveu:
> Rodrigo Rosenfeld Rosas <rr.rosas@gmail.com> wrote:
>> For a long time I struggle to understand this part:
>>
>> http://unicorn.bogomips.org/SIGNALS.html
>>
>> "3. You can now send WINCH to the old master process so only the new
>> workers serve requests. If your unicorn process is bound to an
>> interactive terminal, you can skip this step."
>>
>> I asked a teammate and he didn't understand this part either, so
>> maybe it's confusing for other people too.
>>
>> Would you mind to clarify what you mean by that?
> It means actions on the terminal which started unicorn won't affect it.
> So if the user hits Ctrl-C from the terminal, unicorn will not receive
> SIGINT.  Likewise for Ctrl-\ and SIGINT, and if a user resizes his
> terminal (common with xterm and friends), there's no SIGWINCH.
>
> setsid(2) is the syscall used to detach from a controlling terminal
> (among other things).  Maybe there's documentation elsewhere to the
> setsid(2) which explains this part more, but neither the POSIX nor Linux
> manpage for that distributed by Debian (wheezy) really explain this.
I see. If I understood correctly this only happens in foreground mode, 
so something like that would help me to understand the sentence:

"...If your unicorn process is bound to an interactive terminal (running in the foreground), you can skip this step."

>> Also, a section with suggestions on how to properly automate a
>> deployment with no downtime would be helpful.
>>
>> What I see is that most recipes, like the ones I've seen for
>> Capistrano for example, will simply send a QUIT after USR2 to the
>> old master without actually checking if the deploy was successful
>> and won't use the WINCH and HUP signals to deal with health
>> checking...
> Patches welcome.

I'd provide one if I could figure out some good way to automate this. 
Currently I perform all steps manually in production for zero downtime 
and only manage the other environments with Capistrano, except when I 
have a programmed downtime window for production.

> I haven't deployed an app entirely with Capistrano in
> years nor do I use any common/widely-known deployment system.  I usually
> just end using something like the init script in examples/init.sh

I believe it would help the documentation if you added a link to init.sh 
in the SIGNALS page:

http://bogomips.org/unicorn.git/tree/examples/init.sh

Anyway, even that script won't take care of making sure that the reload 
action will rollback in case of an unsuccessful deploy.

I realize it's not easy to detect if the deploy was successful and that 
it's very application dependent, but some generic procedures would be 
helpful for a basic Rails application. Unfortunately I don't know what 
would be a good strategy, that's why I asked :P

Thank you for explaining the interactive terminal binding question :)

Best,
Rodrigo.

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: What does it mean for the unicorn process to be bound to a terminal?
  @ 2013-11-26 18:04  6% ` Eric Wong
  2013-11-26 18:35  6%   ` Rodrigo Rosenfeld Rosas
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2013-11-26 18:04 UTC (permalink / raw)
  To: unicorn list; +Cc: Rodrigo Rosenfeld Rosas

Rodrigo Rosenfeld Rosas <rr.rosas@gmail.com> wrote:
> For a long time I struggle to understand this part:
> 
> http://unicorn.bogomips.org/SIGNALS.html
> 
> "3. You can now send WINCH to the old master process so only the new
> workers serve requests. If your unicorn process is bound to an
> interactive terminal, you can skip this step."
> 
> I asked a teammate and he didn't understand this part either, so
> maybe it's confusing for other people too.
> 
> Would you mind to clarify what you mean by that?

It means actions on the terminal which started unicorn won't affect it.
So if the user hits Ctrl-C from the terminal, unicorn will not receive
SIGINT.  Likewise for Ctrl-\ and SIGINT, and if a user resizes his
terminal (common with xterm and friends), there's no SIGWINCH.

setsid(2) is the syscall used to detach from a controlling terminal
(among other things).  Maybe there's documentation elsewhere to the
setsid(2) which explains this part more, but neither the POSIX nor Linux
manpage for that distributed by Debian (wheezy) really explain this.

> Also, a section with suggestions on how to properly automate a
> deployment with no downtime would be helpful.
> 
> What I see is that most recipes, like the ones I've seen for
> Capistrano for example, will simply send a QUIT after USR2 to the
> old master without actually checking if the deploy was successful
> and won't use the WINCH and HUP signals to deal with health
> checking...

Patches welcome.  I haven't deployed an app entirely with Capistrano in
years nor do I use any common/widely-known deployment system.  I usually
just end using something like the init script in examples/init.sh
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: unicorn simple cgi without rails
  @ 2013-10-10 22:53  6% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2013-10-10 22:53 UTC (permalink / raw)
  To: unicorn list

nomad Bellcam <damonswirled@hotmail.com> wrote:
> my website is mostly static with some small cgi areas, and i like to
> use ruby for the cgi. when i did my research for the best ruby cgi
> handler for nginx, unicorn figured prominently in my results, and so i
> became interested in trying it. i spent some time reading up on how to
> configure and use it but have been unsuccessful implementing, mostly i
> believe due to the fact that i do not have a rails framework installed
> nor a legitimate rackup config.ru

> my question is this: does it make any sense at all to use unicorn as a
> ruby cgi handler if i am not also using rails?

Yes, but perhaps Rainbows! (a sister project of unicorn) is better
<http://rainbows.rubyforge.org/> since it has less overhead when
waiting for a big CGI to run.  If performance/scalability isn't
an issue, then unicorn is fine for CGI.  unicorn is much easier
to configure as there's less documentation to read :)

> and if there is indeed
> some sense in this idea, how might i go about it? is there a simple
> rackup file that would work for a configuration such as this? i
> couldn't find any information on rackup configs of this sort, and not
> being familiar with rails the terrain simply became to steep at this
> point to continue without some guidance or assurances.

You can check out rack-legacy git://github.com/eric1234/rack-legacy

I've never used rack-legacy, as I've been running the bundled
Unicorn::App::ExecCGI before with cgit <http://git.zx2c4.com/cgit/>.
I haven't used it on anything but cgit, however.

I use the following for serving http://bogomips.org/unicorn.git

(I run this with Rainbows!, but it's fine with unicorn, too)
------------------------ config.ru ------------------------
require "unicorn/app/exec_cgi"
map("http://bogomips.org/") do
  repo = "/path/to/my/git/repos/on/bogomips.org"
  cgit = Unicorn::App::ExecCgi.new("#{repo}/cgit.cgi")

  # Attempts static file serving with Rack::File, first.
  # Fall back to calling cgit if the URL matches .git
  # Otherwise, just return a 404
  r404 = [ 404, [ %w(Content-Length 0), %w(Content-Type text/plain) ], [] ]
  cgit_wrap = lambda { |e| e["PATH_INFO"] =~ %r{\.git} ? cgit.call(e) : r404 }
  run Rack::Cascade.new([ Rack::File.new(repo), cgit_wrap ])
end
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: [PATCH] preload_app can take an optional block for warmup
  2013-09-21  8:49  6% ` Eric Wong
@ 2013-09-21 23:10  0%   ` Aman Gupta
  0 siblings, 0 replies; 200+ results
From: Aman Gupta @ 2013-09-21 23:10 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

> In particular, what benefit does this have over putting the same
> code in config.ru or config/initializer.rb (or similar?)

With my patch, preload_app yields a rack app object which includes the
middleware stack. AFAIK there's no way to do this in the context of
config.ru, since the app is still being built. My goal is to warm up
the final application that will be serving traffic, including all
middleware.

On Sat, Sep 21, 2013 at 1:49 AM, Eric Wong <normalperson@yhbt.net> wrote:
> Aman Gupta <aman@tmm1.net> wrote:
>
> Thanks for the patch!
>
> I expect a commit message body to describe why it is useful.
>
> In particular, what benefit does this have over putting the same
> code in config.ru or config/initializer.rb (or similar?)
>
> For user-visible config changes like these, it can be similar/identical
> to the added documentation.
>
> Anyways, I agree warming up the app is often necessary, but I'm not
> convinced it's necessary change unicorn for it.  It makes sense
> to warmup apps on servers other than unicorn, too.
>
>> --- a/lib/unicorn/http_server.rb
>> +++ b/lib/unicorn/http_server.rb
>> @@ -721,6 +721,9 @@ class Unicorn::HttpServer
>>          Gem.refresh
>>        end
>>        self.app = app.call
>> +      if preload_app.respond_to?(:call)
>> +        preload_app[app]
>> +      end
>
> Since you're testing for respond_to?(:call), it should be less confusing
> to use "preload_app.call(app)" here instead of "preload_app[app]"
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] preload_app can take an optional block for warmup
  @ 2013-09-21  8:49  6% ` Eric Wong
  2013-09-21 23:10  0%   ` Aman Gupta
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2013-09-21  8:49 UTC (permalink / raw)
  To: unicorn list; +Cc: Aman Gupta

Aman Gupta <aman@tmm1.net> wrote:

Thanks for the patch!

I expect a commit message body to describe why it is useful.

In particular, what benefit does this have over putting the same
code in config.ru or config/initializer.rb (or similar?)

For user-visible config changes like these, it can be similar/identical
to the added documentation.

Anyways, I agree warming up the app is often necessary, but I'm not
convinced it's necessary change unicorn for it.  It makes sense
to warmup apps on servers other than unicorn, too.

> --- a/lib/unicorn/http_server.rb
> +++ b/lib/unicorn/http_server.rb
> @@ -721,6 +721,9 @@ class Unicorn::HttpServer
>          Gem.refresh
>        end
>        self.app = app.call
> +      if preload_app.respond_to?(:call)
> +        preload_app[app]
> +      end

Since you're testing for respond_to?(:call), it should be less confusing
to use "preload_app.call(app)" here instead of "preload_app[app]"
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* [ANN] unicorn 4.6.3 - fix --no-default-middleware option
@ 2013-06-21  8:14  9% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2013-06-21  8:14 UTC (permalink / raw)
  To: mongrel-unicorn

Changes:

Thanks to Micah Chalmer for this fix.  There are also minor
documentation updates and internal cleanups.

Eric Wong (4):
      doc: update documentation for systemd + PrivateTmp users
      test_signals: increase delay between Process.kill
      HttpParser#next? becomes response_start_sent-aware
      unicorn 4.6.3 - fix --no-default-middleware option

Micah Chalmer (1):
      Make -N/--no-default-middleware option work

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml

/me yawns
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 9%]

* Re: Fedora Unix socket file location problems
  @ 2013-04-05 21:56  4% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2013-04-05 21:56 UTC (permalink / raw)
  To: unicorn list; +Cc: David Wilkins

David Wilkins <dwilkins@conecuh.com> wrote:
> Folks,
> 
> It seems that it's pretty common to use /tmp for the directory where
> you store the Unicorn unix: socket file.   I'm a Fedora user and our
> lovable systemd (by default) gives nginx a private /tmp directory (see
> "PrivateTmp=true" in system configuration file example below).
> That's the kind of thing that *could* take a while to figure out.
> 
> Could you put a note somewhere near the listen docs warning Fedora /
> systemd users to locate the socket file somewhere else?  I know it's
> not your problem, but I'll bet that more than a few Fedora users are
> using TCP sockets instead of unix sockets with Unicorn because of
> this.

Thanks, I'll queue up something like the following patch.
Comments/corrections greatly appreciated:

------------------------------8<-------------------------------
From: Eric Wong <normalperson@yhbt.net>
Subject: [PATCH] doc: update documentation for systemd + PrivateTmp users

The PrivateTmp feature of systemd breaks the usage of /tmp for the
shared Unix domain socket between nginx and unicorn, so discourage the
use of /tmp in that case.

While we're at it, use consistent paths for everything and use an
obviously intended-for-user-customization "/path/to" prefix instead
of "/tmp"

ML-Ref: CAKLVLx_t+9zWMhquMWDfStrxS7xrNoGmN0ZDsjSCUE=VxU+oyQ@mail.gmail.com
Reported-by: David Wilkins <dwilkins@conecuh.com>
---
 examples/nginx.conf         |  8 ++++----
 examples/unicorn.conf.rb    |  2 +-
 lib/unicorn/configurator.rb | 10 ++++++++--
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/examples/nginx.conf b/examples/nginx.conf
index 66ac0aa..a68fe6f 100644
--- a/examples/nginx.conf
+++ b/examples/nginx.conf
@@ -24,8 +24,8 @@ user nobody nogroup; # for systems with a "nogroup"
 # user nobody nobody; # for systems with "nobody" as a group instead
 
 # Feel free to change all paths to suite your needs here, of course
-pid /tmp/nginx.pid;
-error_log /tmp/nginx.error.log;
+pid /path/to/nginx.pid;
+error_log /path/to/nginx.error.log;
 
 events {
   worker_connections 1024; # increase if you have lots of clients
@@ -42,7 +42,7 @@ http {
   default_type application/octet-stream;
 
   # click tracking!
-  access_log /tmp/nginx.access.log combined;
+  access_log /path/to/nginx.access.log combined;
 
   # you generally want to serve static files with nginx since neither
   # Unicorn nor Rainbows! is optimized for it at the moment
@@ -74,7 +74,7 @@ http {
     # single worker for timing out).
 
     # for UNIX domain socket setups:
-    server unix:/tmp/.sock fail_timeout=0;
+    server unix:/path/to/.unicorn.sock fail_timeout=0;
 
     # for TCP setups, point these to your backend servers
     # server 192.168.0.7:8080 fail_timeout=0;
diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index 4042d9c..9dce58a 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -25,7 +25,7 @@
 
 # listen on both a Unix domain socket and a TCP port,
 # we use a shorter backlog for quicker failover when busy
-listen "/tmp/.sock", :backlog => 64
+listen "/path/to/.unicorn.sock", :backlog => 64
 listen 8080, :tcp_nopush => true
 
 # nuke workers after 30 seconds instead of 60 seconds (the default)
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 7651093..0d0eac7 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -188,7 +188,7 @@ def before_exec(*args, &block)
   #    # on nginx upstream configuration:
   #    upstream unicorn_backend {
   #      # for UNIX domain socket setups:
-  #      server unix:/path/to/unicorn.sock fail_timeout=0;
+  #      server unix:/path/to/.unicorn.sock fail_timeout=0;
   #
   #      # for TCP setups
   #      server 192.168.0.7:8080 fail_timeout=0;
@@ -229,9 +229,15 @@ def listeners(addresses) # :nodoc:
   #
   #   listen 3000 # listen to port 3000 on all TCP interfaces
   #   listen "127.0.0.1:3000"  # listen to port 3000 on the loopback interface
-  #   listen "/tmp/.unicorn.sock" # listen on the given Unix domain socket
+  #   listen "/path/to/.unicorn.sock" # listen on the given Unix domain socket
   #   listen "[::1]:3000" # listen to port 3000 on the IPv6 loopback interface
   #
+  # When using Unix domain sockets, be sure:
+  # 1) the path matches the one used by nginx
+  # 2) uses the same filesystem namespace as the nginx process
+  # For systemd users using PrivateTmp=true (for either nginx or unicorn),
+  # this means Unix domain sockets must not be placed in /tmp
+  #
   # The following options may be specified (but are generally not needed):
   #
   # [:backlog => number of clients]
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 4%]

* [PATCH] auto-generate Unicorn::Const::UNICORN_VERSION
  @ 2013-02-08 18:55  8% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2013-02-08 18:55 UTC (permalink / raw)
  To: unicorn list; +Cc: Maurizio De Santis

Maurizio De Santis <m.desantis@morganspa.com> wrote:
> Hello,
> 
> I want to report that unicorn-4.6.0/lib/unicorn/const.rb declares
> UNICORN_VERSION = "4.5.0", which I think should be "4.6.0".

Oops, I've been meaning to move that constant over to an auto-generated file
using GIT-VERSION-GEN.  This should work:

--------------------------------- 8< ------------------------------
>From cb0623f25db7f06660e563e8e746bfe0ae5ba9c5 Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Fri, 8 Feb 2013 18:50:07 +0000
Subject: [PATCH] auto-generate Unicorn::Const::UNICORN_VERSION

This DRYs out our code and prevents snafus like the 4.6.0
release where UNICORN_VERSION stayed at 4.5.0

Reported-by: Maurizio De Santis <m.desantis@morganspa.com>
---
 .gitignore           |  1 +
 GIT-VERSION-GEN      | 69 ++++++++++++++++++++++++++--------------------------
 GNUmakefile          |  2 +-
 lib/unicorn/const.rb |  4 +--
 4 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/.gitignore b/.gitignore
index 50c2736..19a82d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,4 @@ pkg/
 /man
 /tmp
 /LATEST
+/lib/unicorn/version.rb
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 56aef5f..e5d414a 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,40 +1,39 @@
-#!/bin/sh
-
-GVF=GIT-VERSION-FILE
-DEF_VER=v4.6.0
-
-LF='
-'
+#!/usr/bin/env ruby
+DEF_VER = "v4.6.0"
+CONSTANT = "Unicorn::Const::UNICORN_VERSION"
+RVF = "lib/unicorn/version.rb"
+GVF = "GIT-VERSION-FILE"
+vn = DEF_VER
 
 # First see if there is a version file (included in release tarballs),
 # then try git-describe, then default.
-if test -f version
-then
-	VN=$(cat version) || VN="$DEF_VER"
-elif test -d .git -o -f .git &&
-	VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
-	case "$VN" in
-	*$LF*) (exit 1) ;;
-	v[0-9]*)
-		git update-index -q --refresh
-		test -z "$(git diff-index --name-only HEAD --)" ||
-		VN="$VN-dirty" ;;
-	esac
-then
-	VN=$(echo "$VN" | sed -e 's/-/./g');
-else
-	VN="$DEF_VER"
-fi
+if File.exist?(".git")
+  describe = `git describe --abbrev=4 HEAD 2>/dev/null`.strip
+  case describe
+  when /\Av[0-9]*/
+    vn = describe
+    system(*%w(git update-index -q --refresh))
+    unless `git diff-index --name-only HEAD --`.chomp.empty?
+      vn << "-dirty"
+    end
+    vn.tr!('-', '.')
+  end
+end
+
+vn = vn.sub!(/\Av/, "")
+
+# generate the Ruby constant
+new_ruby_version = "#{CONSTANT} = '#{vn}'\n"
+cur_ruby_version = File.read(RVF) rescue nil
+if new_ruby_version != cur_ruby_version
+  File.open(RVF, "w") { |fp| fp.write(new_ruby_version) }
+end
 
-VN=$(expr "$VN" : v*'\(.*\)')
+# generate the makefile snippet
+new_make_version = "GIT_VERSION = #{vn}\n"
+cur_make_version = File.read(GVF) rescue nil
+if new_make_version != cur_make_version
+  File.open(GVF, "w") { |fp| fp.write(new_make_version) }
+end
 
-if test -r $GVF
-then
-	VC=$(sed -e 's/^GIT_VERSION = //' <$GVF)
-else
-	VC=unset
-fi
-test "$VN" = "$VC" || {
-	echo >&2 "GIT_VERSION = $VN"
-	echo "GIT_VERSION = $VN" >$GVF
-}
+puts vn if $0 == __FILE__
diff --git a/GNUmakefile b/GNUmakefile
index ea13486..34a2d95 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -155,7 +155,7 @@ clean:
 man html:
 	$(MAKE) -C Documentation install-$@
 
-pkg_extra := GIT-VERSION-FILE ChangeLog LATEST NEWS \
+pkg_extra := GIT-VERSION-FILE lib/unicorn/version.rb ChangeLog LATEST NEWS \
              $(ext)/unicorn_http.c $(man1_paths)
 
 ChangeLog: GIT-VERSION-FILE .wrongdoc.yml
diff --git a/lib/unicorn/const.rb b/lib/unicorn/const.rb
index fcc30c0..51d7394 100644
--- a/lib/unicorn/const.rb
+++ b/lib/unicorn/const.rb
@@ -7,9 +7,6 @@
 # improvement over using the strings directly.  Symbols did not really
 # improve things much compared to constants.
 module Unicorn::Const
-
-  UNICORN_VERSION = "4.5.0"
-
   # default TCP listen host address (0.0.0.0, all interfaces)
   DEFAULT_HOST = "0.0.0.0"
 
@@ -44,3 +41,4 @@ module Unicorn::Const
 
   # :startdoc:
 end
+require 'unicorn/version'
-- 
1.8.1.2.526.gf51a757
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 8%]

* [ANN] unicorn 4.6.0 - hijacking support
@ 2013-02-06 11:27  9% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2013-02-06 11:27 UTC (permalink / raw)
  To: mongrel-unicorn

Changes:

This pre-release adds hijacking support for Rack 1.5 users.
See Rack documentation for more information about hijacking.
There is also a new --no-default-middleware/-N option
for the `unicorn' command to ignore RACK_ENV within unicorn
thanks to Lin Jen-Shin.

There are only documentation and test-portability updates
since 4.6.0pre1, no code changes.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 9%]

* Re: [ANN] unicorn 4.6.0pre1 - hijacking support!
  2013-01-29 21:10  7% [ANN] unicorn 4.6.0pre1 - hijacking support! Eric Wong
  2013-01-29 21:23 30% ` [PATCH] manpage: update middleware-related documentation Eric Wong
@ 2013-02-04 13:40  5% ` Eric Wong
  1 sibling, 0 replies; 200+ results
From: Eric Wong @ 2013-02-04 13:40 UTC (permalink / raw)
  To: mongrel-unicorn

Anybody running 4.6.0pre1, yet?  I'm tempted to release 4.6.0 soon.

I just pushed out a couple of *BSD-related test fixes ported
over from rainbows.git (@ git://bogomips.org/rainbows.git )

  commit 9cd8554749a9f120b010c93933d09d2dd27b1280
  Author: Eric Wong <normalperson@yhbt.net>
  Date:   Mon Feb 4 12:39:09 2013 +0000

      tests: "wc -l" portability for *BSDs
      
      On FreeBSD 9.0, "wc -l" emits leading whitespace, so
      filter it through tr -d '[:space:]' to eliminate it.

  commit 2a2163594ea2b515e98fbe9f909bcf90e4c35fe8
  Author: Eric Wong <normalperson@yhbt.net>
  Date:   Mon Feb 4 12:29:00 2013 +0000

      tests: "wc -c" portability for *BSDs
      
      On FreeBSD 9.0, "wc -c" emits leading whitespace, so
      filter it through tr -d '[:space:]' to eliminate it.
      
      This is commit 8a6117a22a7d01eeb5adc63d3152acf435cd3176
      in rainbows.git

  commit 85223902e8229bd460ce0b4ad126f42b1db42a46
  Author: Eric Wong <normalperson@yhbt.net>
  Date:   Mon Feb 4 10:36:18 2013 +0000

      tests: replace non-portable "date +%s" with ruby equivalent
      
      "date +%s" is not in POSIX (it is in GNU, and at least FreeBSD
      9.0, possibly earlier).  The Ruby equivalent should be
      sufficiently portable between different Ruby versions.
      
      This change was automated via:
          perl -i -p -e 's/date \+%s/unix_time/' t/*.sh
      
      This is commit 0ba6fc3c30b9cf530faf7fcf5ce7be519ec13fe7
      in rainbows.git

  commit a09a622b4988b5eee819487c96a4563e71f753f7
  Author: Eric Wong <normalperson@yhbt.net>
  Date:   Mon Feb 4 10:30:25 2013 +0000

      tests: remove utee
      
      POSIX already stipulates tee(1) must be unbuffered.  I think my
      decision to use utee was due to my being misled by a bug in
      older curl where -N did not work as advertised (but --no-buffer
      did).
      
      N.B. we don't use tee in unicorn tests, this just matches
      commit cbff7b0892148b037581541184364e0e91d2a138 in rainbows

  commit 64765b95df06256d39daefdeebde97c874770131
  Author: Eric Wong <normalperson@yhbt.net>
  Date:   Tue Jan 29 21:19:22 2013 +0000

      manpage: update middleware-related documentation
      
      -N/--no-default-middleware needs a corresponding manpage entry.
      
      Additionally, the Rack::Chunked/ContentLength middleware comment
      is out-of-date as of unicorn v4.1.0

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 5%]

* [PATCH] manpage: update middleware-related documentation
  2013-01-29 21:10  7% [ANN] unicorn 4.6.0pre1 - hijacking support! Eric Wong
@ 2013-01-29 21:23 30% ` Eric Wong
  2013-02-04 13:40  5% ` [ANN] unicorn 4.6.0pre1 - hijacking support! Eric Wong
  1 sibling, 0 replies; 200+ results
From: Eric Wong @ 2013-01-29 21:23 UTC (permalink / raw)
  To: mongrel-unicorn

-N/--no-default-middleware needs a corresponding manpage entry.

Additionally, the Rack::Chunked/ContentLength middleware comment
is out-of-date as of unicorn v4.1.0
---
  Also just pushed this to master of git://bogomips.org/unicorn
  commit 64765b95df06256d39daefdeebde97c874770131

 Documentation/unicorn.1.txt | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index c20a570..a42dfff 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
@@ -61,6 +61,10 @@ with rackup(1) but strongly discouraged.
     For production deployments, specifying the "listen" directive in
     CONFIG_FILE is recommended as it allows fine-tuning of socket
     options.
+-N, \--no-default-middleware
+:   Disables loading middleware implied by RACK_ENV.  This bypasses the
+    configuration documented in the RACK ENVIRONMENT section, but still
+    allows RACK_ENV to be used for application/framework-specific purposes.
 
 # RACKUP COMPATIBILITY OPTIONS
 -o, \--host HOST
@@ -144,10 +148,10 @@ As of Unicorn 0.94.0, RACK_ENV is exported as a process-wide environment
 variable as well.  While not current a part of the Rack specification as
 of Rack 1.0.1, this has become a de facto standard in the Rack world.
 
-Note that the Rack::ContentLength and Rack::Chunked middlewares
-are never loaded by default.  If needed, they should be
-individually specified in the RACKUP_FILE, some frameworks do
-not require them.
+Note the Rack::ContentLength and Rack::Chunked middlewares are also
+loaded by "deployment" and "development", but no other values of
+RACK_ENV.  If needed, they must be individually specified in the
+RACKUP_FILE, some frameworks do not require them.
 
 # ENVIRONMENT VARIABLES
 
-- 
1.8.1.2.422.g08c0e7f

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 30%]

* [ANN] unicorn 4.6.0pre1 - hijacking support!
@ 2013-01-29 21:10  7% Eric Wong
  2013-01-29 21:23 30% ` [PATCH] manpage: update middleware-related documentation Eric Wong
  2013-02-04 13:40  5% ` [ANN] unicorn 4.6.0pre1 - hijacking support! Eric Wong
  0 siblings, 2 replies; 200+ results
From: Eric Wong @ 2013-01-29 21:10 UTC (permalink / raw)
  To: mongrel-unicorn

Installing from RubyGems.org: gem install --pre unicorn

>From db919d18e01f6b2339915cbd057fba9dc040988b Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Tue, 29 Jan 2013 21:02:55 +0000
Subject: [PATCH] unicorn 4.6.0pre1 - hijacking support

This pre-release adds hijacking support for Rack 1.5 users.
See Rack documentation for more information about hijacking.
There is also a new --no-default-middleware/-N option
for the `unicorn' command to ignore RACK_ENV within unicorn.
---
 GIT-VERSION-GEN | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 365df8d..46ef417 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v4.5.0
+DEF_VER=v4.6.0.pre1
 
 LF='
 '
-- 
1.8.1.1.253.g2934a48
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 7%]

* Re: [RFC/PATCH] check_client_connection: document local-only requirement
  @ 2012-11-29 23:47  7%                       ` Tom Burns
  0 siblings, 0 replies; 200+ results
From: Tom Burns @ 2012-11-29 23:47 UTC (permalink / raw)
  To: unicorn list

On Thu, Nov 29, 2012 at 4:55 PM, Eric Wong <normalperson@yhbt.net> wrote:
> In my testing, only dropped clients over Unix domain sockets or
> loopback TCP were detected with this option.  Since many
> nginx+unicorn combinations run on the same host, this is not a
> problem.
>
> Furthermore, tcp_nodelay:true appears to work over loopback,
> so remove the requirement for tcp_nodelay:false.

In production our configuration is same host / UNIX domain socket, so
I don't have any comment on the TCP changes.

It makes sense to me though, and the documentation looks better!

Cheers,
Tom
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: Combating nginx 499 HTTP responses during flash traffic scenario
  @ 2012-11-29 20:41  7%                   ` Eric Wong
    1 sibling, 0 replies; 200+ results
From: Eric Wong @ 2012-11-29 20:41 UTC (permalink / raw)
  To: unicorn list

Tom Burns <tom.burns@jadedpixel.com> wrote:
> So we just finished the US Black Friday / Cyber Monday weekend running
> unicorn forked with the last version of the patch I had sent you.  It
> worked splendidly and helped us handle huge flash sales without
> increased response time over the weekend.
> 
> Whereas in previous flash traffic scenarios we would see the number of
> HTTP 499 responses grow past the number of real HTTP 200 responses,
> over the weekend we saw no growth in 499s during flash sales.
> 
> Unexpectedly the patch also helped us ward off a DoS attack where the
> attackers were disconnecting immediately after making a request.

That is absolutely wonderful to hear.  I've amended your commit message
with the above quoted portion.

> I've attached the patch again, with your last comments addressed.  Let
> me know if there's anything else.
> 
> Thanks again for your help in this matter.

Thank _you_ for the patch, documentation and most importantly:
testing with real traffic.

I fixed up some minor line-wrapping, signed-off, and added your
quote above to the commit message.  Pushed as
commit 5c700fc2cf398848ddcf71a2aa3f0f2a6563e87b
to git://bogomips.org/unicorn.git

I'll tag and push a 4.5.0.preview1 gem soon
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] explicitly use escaped minus in man pages
  2012-10-17 15:33  0%   ` Hleb Valoshka
@ 2012-10-18  8:04  0%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-10-18  8:04 UTC (permalink / raw)
  To: unicorn list

Hleb Valoshka <375gnu@gmail.com> wrote:
> On 10/15/12, Eric Wong <normalperson@yhbt.net> wrote:
> > All the manpages are generated with pandoc.  Can you send a patch
> > for the Markdown files in Documentation/*.1.txt instead?  Thanks
> > in advance.
> 
> I'll try but I'm not sure that it's possible, it seems to be only
> groff-specific issue to treat minus as hyphen.
> 
> May be it's better to try to patch pandoc.

Yes, it is probably a bug in pandoc.

Btw, I'm not married to pandoc, either.  I'm open to migrating to ronn
(or similar) if somebody is willing to try it out.  ronn might be an
easier tool for Rubyists on various platforms to install, too, and I
likely would've chosen it if I had known about it back in the day...

> > I generate manpages using pandoc 1.5.1.1-5+b1 from Debian stable
> > using: make -C Documentation
> 
> I'll try it with pandoc 1.9.4.2-2 from sid, maybe it knows groff
> better than 1.5 :)

I have the same version on my wheezy machine, and it doesn't seem
to escape hyphens, either.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] explicitly use escaped minus in man pages
  2012-10-15 18:50  9% ` Eric Wong
@ 2012-10-17 15:33  0%   ` Hleb Valoshka
  2012-10-18  8:04  0%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Hleb Valoshka @ 2012-10-17 15:33 UTC (permalink / raw)
  To: unicorn list

On 10/15/12, Eric Wong <normalperson@yhbt.net> wrote:
> All the manpages are generated with pandoc.  Can you send a patch
> for the Markdown files in Documentation/*.1.txt instead?  Thanks
> in advance.

I'll try but I'm not sure that it's possible, it seems to be only
groff-specific issue to treat minus as hyphen.

May be it's better to try to patch pandoc.

> I generate manpages using pandoc 1.5.1.1-5+b1 from Debian stable
> using: make -C Documentation

I'll try it with pandoc 1.9.4.2-2 from sid, maybe it knows groff
better than 1.5 :)

> However, I think distributing your patch as-is with the Debian source
> package is fine to avoid an extra Build-Depends on pandoc+haskell until
> the next unicorn release.

I should agree with you.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] explicitly use escaped minus in man pages
  @ 2012-10-15 18:50  9% ` Eric Wong
  2012-10-17 15:33  0%   ` Hleb Valoshka
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2012-10-15 18:50 UTC (permalink / raw)
  To: unicorn list; +Cc: Hleb Valoshka

Hleb Valoshka <375gnu@gmail.com> wrote:

Hi, the commit message body needs to include the reasoning behind
this change.

Something along the lines of your second email would be good.
ref: mid.gmane.org/CAAB-Kckmf0AKGscbCr0y7w7RxWiPJw5_V700BEc3DTUqNfemYA@mail.gmail.com

> ---
>  man/man1/unicorn.1       |   32 ++++++++++++++++----------------
>  man/man1/unicorn_rails.1 |   34 +++++++++++++++++-----------------

All the manpages are generated with pandoc.  Can you send a patch
for the Markdown files in Documentation/*.1.txt instead?  Thanks
in advance.

I generate manpages using pandoc 1.5.1.1-5+b1 from Debian stable
using: make -C Documentation

However, I think distributing your patch as-is with the Debian source
package is fine to avoid an extra Build-Depends on pandoc+haskell until
the next unicorn release.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 9%]

* Re: Is a client uploading a file a slow client from unicorn's point of view?
  2012-10-09 20:03  6%     ` Eric Wong
@ 2012-10-09 23:06  0%       ` Laas Toom
  0 siblings, 0 replies; 200+ results
From: Laas Toom @ 2012-10-09 23:06 UTC (permalink / raw)
  To: unicorn list


On 09.10.2012, at 23:03, Eric Wong <normalperson@yhbt.net> wrote:

>> 2) make the upload progress available, so e.g. AJAX-powered upload forms can show progressbar, which is really neat. No need for Flash-based uploaders.
> 
> It does?  I'm not seeing it in the documentation, but I know there's
> a separate upload progress module, though:
> http://wiki.nginx.org/HttpUploadProgressModule

I must have mixed them up then. :-)

>> I have a Rails app that accepts media uploads. All the processing happens in background, front-end handles only the actual upload and stores it to disk.
>> But with uploads as large as 1.4 GB, I've seen Rails response times > 200 secs. This starts to give timeouts in weird places.
> 
> Yikes.  I assume you're constrained by disk I/O there?

Might be. Additionally, the disk is SAN, so network activity there too.

> For some of the large file situations under Linux, I find it beneficial
> to lower the dirty_*ratio/*bytes drastically to avoid large, sudden
> bursts of disk activity and instead favor smaller writes.  I get lower
> throughput, but more consistent performance.

I shall look into it when I get to fixing this issue.


>> Afterwards it will only handle out the file location and Rails can
>> complete it's work a lot faster, freeing up workers.
>> 
>> Unicorn won't even see the file and Rails has the responsibility to
>> delete the file if it's invalid.
> 
> I think the only problem with this approach is it won't work well on
> setups where nginx is on separate machines from unicorn.  Shared
> storage would be required, but that ends up adding to network I/O,
> too...

But won't (almost) the same network I/O be evident anyway, because of nginx transferring the data to Unicorn over network (as they are on different machines)?

Thanks for clarifying,
Laas

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: Is a client uploading a file a slow client from unicorn's point of view?
  @ 2012-10-09 20:03  6%     ` Eric Wong
  2012-10-09 23:06  0%       ` Laas Toom
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2012-10-09 20:03 UTC (permalink / raw)
  To: unicorn list

Laas Toom <laas@toom.ee> wrote:
> On 09.10.2012, at 4:58, Eric Wong <normalperson@yhbt.net> wrote:
> > I'm not familiar with the nginx upload module, but stock nginx will
> > already do full request buffering for you.  It looks like the nginx
> > upload module[1] is mostly meant for standalone apps written for
> > nginx, and not when nginx is used as a proxy for Rails app...
> 
> AFAIK the upload module will give you two things:
> 
> 1) handle the whole body parsing up to the point of storing the file
> to disk in correct place. Then it strips the file from POST request
> and replaces with reference to the location on disk.

That sounds awesome performance-wise.

> 2) make the upload progress available, so e.g. AJAX-powered upload forms can show progressbar, which is really neat. No need for Flash-based uploaders.

It does?  I'm not seeing it in the documentation, but I know there's
a separate upload progress module, though:
http://wiki.nginx.org/HttpUploadProgressModule

A side note on upload progress: I wrote upr[1] back in the day since I
wanted to share upload progress state via memcached for multi-machine
configurations:  http://upr.bogomips.org/

> I have a Rails app that accepts media uploads. All the processing happens in background, front-end handles only the actual upload and stores it to disk.
> But with uploads as large as 1.4 GB, I've seen Rails response times > 200 secs. This starts to give timeouts in weird places.

Yikes.  I assume you're constrained by disk I/O there?

For some of the large file situations under Linux, I find it beneficial
to lower the dirty_*ratio/*bytes drastically to avoid large, sudden
bursts of disk activity and instead favor smaller writes.  I get lower
throughput, but more consistent performance.

> Eric, correct me if I'm wrong, but doesn't Nginx-Unicorn-Rails stack
> write the whole file up to 3 times to disk:
> 
> 1) Nginx buffers the body (in encoded state)

Correct.

> 2) Unicorn parses the body and writes to TMP folder (as requested by Rails)

Rack does multipart parsing.  Unicorn itself doesn't do body parsing
other than handling Transfer-Encoding:chunked (which hardly anybody
sends).

> 3) if Rails accepts the file, it moves it to actual storage. But as /tmp is often different device from storage, this is actually a full copy.

Depends on the Rack/Rails app, but usually this is the case.

For my use, all uploads are PUT requests with "curl -T", so there's no
multipart parsing involved and much faster :)

> In such a situation the upload module would help out, because instead
> of simply buffering the body on disk, it actually parses the body. And
> it is implemented in C, which should make it faster.

Yep.

> Afterwards it will only handle out the file location and Rails can
> complete it's work a lot faster, freeing up workers.
> 
> Unicorn won't even see the file and Rails has the responsibility to
> delete the file if it's invalid.

I think the only problem with this approach is it won't work well on
setups where nginx is on separate machines from unicorn.  Shared
storage would be required, but that ends up adding to network I/O,
too...
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: after_fork - ActiveRecord::AdapterNotSpecified
  2012-08-31 11:38  4% after_fork - ActiveRecord::AdapterNotSpecified Frank Rennekamp
@ 2012-08-31 20:02  0% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-08-31 20:02 UTC (permalink / raw)
  To: unicorn list; +Cc: Frank Rennekamp

Frank Rennekamp <frank.rennekamp@dataroomservices.com> wrote:
> Hi all,
> 
> I'm fighting with the after_fork hook and my sinatra application. The Sinatra app is using active_record,
> In my unciron.rb file I'm using 
> preload_app true

<snip>

> I get the same error, when using different database adapter. On the
> other hand everything is working fine, when repeating the database
> configuration in after_fork hook, or completely remove database
> configuration from Sinatra app into after_fork hook. But this is not a
> solution for me. First I don't like to double code, second I need the
> database configuration in the Sinatra app for running tests .

I agree, none of those solutions seem good.

> My question is what am I doing wrong? All documentation says that 
>   defined?(ActiveRecord::Base) and
>     ActiveRecord::Base.establish_connection
>   end
> should work.

I'm not familiar with Rails nowadays, but from reading the Rails 3.2.6
source/docs, I believe calling ActiveRecord::Base.establish_connection
(without arguments) only works with a Rails environment.

Perhaps a Rails DB config file (config/database.yml) is all that's
needed, you could try that.

For the ultimate in DRY-ness, perhaps putting the logic in a before
block for your Sinatra app:
--------------------------------- 8< --------------------------------
# use a Mutex in case this gets used on a multi-threaded server
# (something other than unicorn)
db_lock = Mutex.new
db_connected = false

before do
  db_lock.synchronize do
    unless db_connected
      ActiveRecord::Base.establish_connection(
        :adapter => 'sqlite3',
        :database => '/tmp/dbfile'
      )
      db_connected = true
    end
  end
end
--------------------------------- 8< --------------------------------

The above example should work regardless of which Rack server you
choose, and I think the per-request overhead will be negligible.

I'd also be interested to hear anybody elses' experiences and
recommendations for combining Sinatra + ActiveRecord with unicorn.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* after_fork - ActiveRecord::AdapterNotSpecified
@ 2012-08-31 11:38  4% Frank Rennekamp
  2012-08-31 20:02  0% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Frank Rennekamp @ 2012-08-31 11:38 UTC (permalink / raw)
  To: mongrel-unicorn@rubyforge.org

Hi all,

I'm fighting with the after_fork hook and my sinatra application. The Sinatra app is using active_record,
In my unciron.rb file I'm using 
preload_app true
after_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
End

but I always get the error:
ERROR -- : ActiveRecord::AdapterNotSpecified (ActiveRecord::AdapterNotSpecified)

I'm using unicorn (4.3.1), sinatra (1.3.2), activerecord (3.2.6), ruby 1.9.3p194

The app (test.rb):
require 'rubygems'
require 'sinatra'
require 'active_record'

ActiveRecord::Base.establish_connection(
  :adapter => 'sqlite3',
  :database => '/tmp/dbfile'
)

class User < ActiveRecord::Base
end

get '/' do
  @users = User.all
  "This is a Sinatra test. We have #{@users.count} users."
end

The config.ru
require './test'
run Sinatra::Application
The config/unicorn.rb
@dir = '/home/frankr/tmp/sinatra/'
pidfile = " #{@dir}log/unicorn.pid"

worker_processes 3
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true

timeout 30
listen '/tmp/sinatra.socket', :backlog => 64
pid pidfile
stderr_path "#{@dir}log/unicorn.stderr.log"
stdout_path "#{@dir}log/unicorn.stdout.log"

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

when I start  unicorn
    unicorn -c config/unicorn.rb -E production -D -l 0.0.0.0:3001
the unicorn.stderr.log file is growing and growing and repeating the same error message:
.
E, [2012-08-31T07:18:39.232254 #29793] ERROR -- : ActiveRecord::AdapterNotSpecified (ActiveRecord::AdapterNotSpecified)
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/connection_specification.rb:22:in `spec'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/connection_specification.rb:127:in `establish_connection'
config/unicorn.rb:54:in `block in reload'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:565:in `call'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:565:in `init_worker_process'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:589:in `worker_loop'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:487:in `spawn_missing_workers'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:137:in `start'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/bin/unicorn:121:in `<top (required)>'
/home/frankr/.rbenv/versions/1.9.3-p194/bin/unicorn:23:in `load'
/home/frankr/.rbenv/versions/1.9.3-p194/bin/unicorn:23:in `<main>'
I, [2012-08-31T07:18:39.232514 #29790]  INFO -- : master process ready
E, [2012-08-31T07:18:39.232758 #29796] ERROR -- : ActiveRecord::AdapterNotSpecified (ActiveRecord::AdapterNotSpecified)
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/connection_specification.rb:22:in `spec'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/connection_specification.rb:127:in `establish_connection'
config/unicorn.rb:54:in `block in reload'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:565:in `call'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:565:in `init_worker_process'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:589:in `worker_loop'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:487:in `spawn_missing_workers'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:137:in `start'
/home/frankr/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/unicorn-4.3.1/bin/unicorn:121:in `<top (required)>'
/home/frankr/.rbenv/versions/1.9.3-p194/bin/unicorn:23:in `load'
/home/frankr/.rbenv/versions/1.9.3-p194/bin/unicorn:23:in `<main>'
E, [2012-08-31T07:18:39.232976 #29790] ERROR -- : reaped #<Process::Status: pid 29793 exit 1> worker=0
.


I get the same error, when using different database adapter. On the other hand everything is working fine, when repeating the database configuration in after_fork hook, or completely remove database configuration from Sinatra app into after_fork hook. But this is not a solution for me. First I don't like to double code, second I need the database configuration in the Sinatra app for running tests .

My question is what am I doing wrong? All documentation says that 
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
  end
should work.

Regards,
Frank

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 4%]

* Re: Any signal other than -9 causes full CPU utilization by master unicorn process on FreeBSD
  2012-07-17 11:56  0%   ` Mark Mccraw
@ 2012-07-17 21:23  0%     ` Mark Mccraw
  0 siblings, 0 replies; 200+ results
From: Mark Mccraw @ 2012-07-17 21:23 UTC (permalink / raw)
  To: unicorn list


On Jul 17, 2012, at 7:56 AM, Mark McCraw wrote:

> 
> On Jul 16, 2012, at 10:05 PM, Eric Wong wrote:
> 
>> Mark Mccraw <Mark.Mccraw@sas.com> wrote:
>>> Hi There!
>>> 
>>> I'm having a devil of a time figuring out a weird issue I'm running
>>> into.  I have unicorn configured to start 4 worker processes, and that
>>> works great.  However, when it's time to cycle the app, everything
>>> goes haywire. By trial and error, I have narrowed it down to this:
>>> sending any signal to the master process other than SIGKILL fails
>>> miserably.  No new master process is created, as described in the
>>> documentation, nothing happens to the existing workers, nothing gets
>>> written to any log, and if I run top -u, I can see that very quickly
>>> the master ramps up to 100% CPU utilization.  This happens if I run
>>> 'kill -HUP <master pid>', 'kill -USR2 <master pid>', even 'kill -QUIT
>>> <master pid>'.
>> 
>> This sounds like a Ruby/FreeBSD bug we've seen before.  My script
>> in http://mid.gmane.org/20120201181445.GA31624@dcvr.yhbt.net should
>> reproduce the issue w/o unicorn.
> 
> You are absolutely correct!  Your script replicates the problem perfectly.
> 
>>> ruby 1.9.3p0 (2011-10-30 revision 33570) [amd64-freebsd9]
>> 
>> I think this is a Ruby bug that was fixed in 1.9.3-p30 according to
>> naruse:
>> http://mid.gmane.org/CAK6HhsppWVPijWLyZMwcKueYDT5sZroGv6ADXkgreht3aLfR9A@mail.gmail.com
>> 
>> Since 1.9.3 p194 is the latest, can you try that out and confirm the
>> fix?  I don't remember the other bug reported confirmed this issue was
>> fixed by upgrading Ruby.
> 
> We're upgrading now to see what happens.  I'm so glad you knew about this.  
> There's no telling how long it would have taken me to question the ruby interpreter implementation, and
> since it's FreeBSD, I never would have found it by googling.
> Thanks for hours (days?) of my life back.
> 
> Mark
> 

Just to follow up and close out the thread - Eric's recollection was spot on. 
We upgraded ruby on our FreeBSD server to the latest thing, and the problem completely disappeared.  Thanks again!
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: Any signal other than -9 causes full CPU utilization by master unicorn process on FreeBSD
  2012-07-17  2:05  0% ` Eric Wong
@ 2012-07-17 11:56  0%   ` Mark Mccraw
  2012-07-17 21:23  0%     ` Mark Mccraw
  0 siblings, 1 reply; 200+ results
From: Mark Mccraw @ 2012-07-17 11:56 UTC (permalink / raw)
  To: unicorn list


On Jul 16, 2012, at 10:05 PM, Eric Wong wrote:

> Mark Mccraw <Mark.Mccraw@sas.com> wrote:
>> Hi There!
>> 
>> I'm having a devil of a time figuring out a weird issue I'm running
>> into.  I have unicorn configured to start 4 worker processes, and that
>> works great.  However, when it's time to cycle the app, everything
>> goes haywire. By trial and error, I have narrowed it down to this:
>> sending any signal to the master process other than SIGKILL fails
>> miserably.  No new master process is created, as described in the
>> documentation, nothing happens to the existing workers, nothing gets
>> written to any log, and if I run top -u, I can see that very quickly
>> the master ramps up to 100% CPU utilization.  This happens if I run
>> 'kill -HUP <master pid>', 'kill -USR2 <master pid>', even 'kill -QUIT
>> <master pid>'.
> 
> This sounds like a Ruby/FreeBSD bug we've seen before.  My script
> in http://mid.gmane.org/20120201181445.GA31624@dcvr.yhbt.net should
> reproduce the issue w/o unicorn.

You are absolutely correct!  Your script replicates the problem perfectly.

>> ruby 1.9.3p0 (2011-10-30 revision 33570) [amd64-freebsd9]
> 
> I think this is a Ruby bug that was fixed in 1.9.3-p30 according to
> naruse:
> http://mid.gmane.org/CAK6HhsppWVPijWLyZMwcKueYDT5sZroGv6ADXkgreht3aLfR9A@mail.gmail.com
> 
> Since 1.9.3 p194 is the latest, can you try that out and confirm the
> fix?  I don't remember the other bug reported confirmed this issue was
> fixed by upgrading Ruby.

We're upgrading now to see what happens.  I'm so glad you knew about this.  
There's no telling how long it would have taken me to question the ruby interpreter implementation, and
since it's FreeBSD, I never would have found it by googling.
Thanks for hours (days?) of my life back.

Mark


_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: Any signal other than -9 causes full CPU utilization by master unicorn process on FreeBSD
  2012-07-17  0:33  4% Any signal other than -9 causes full CPU utilization by master unicorn process on FreeBSD Mark Mccraw
@ 2012-07-17  2:05  0% ` Eric Wong
  2012-07-17 11:56  0%   ` Mark Mccraw
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2012-07-17  2:05 UTC (permalink / raw)
  To: unicorn list

Mark Mccraw <Mark.Mccraw@sas.com> wrote:
> Hi There!
> 
> I'm having a devil of a time figuring out a weird issue I'm running
> into.  I have unicorn configured to start 4 worker processes, and that
> works great.  However, when it's time to cycle the app, everything
> goes haywire. By trial and error, I have narrowed it down to this:
> sending any signal to the master process other than SIGKILL fails
> miserably.  No new master process is created, as described in the
> documentation, nothing happens to the existing workers, nothing gets
> written to any log, and if I run top -u, I can see that very quickly
> the master ramps up to 100% CPU utilization.  This happens if I run
> 'kill -HUP <master pid>', 'kill -USR2 <master pid>', even 'kill -QUIT
> <master pid>'.

This sounds like a Ruby/FreeBSD bug we've seen before.  My script
in http://mid.gmane.org/20120201181445.GA31624@dcvr.yhbt.net should
reproduce the issue w/o unicorn.

> ruby 1.9.3p0 (2011-10-30 revision 33570) [amd64-freebsd9]

I think this is a Ruby bug that was fixed in 1.9.3-p30 according to
naruse:
http://mid.gmane.org/CAK6HhsppWVPijWLyZMwcKueYDT5sZroGv6ADXkgreht3aLfR9A@mail.gmail.com

Since 1.9.3 p194 is the latest, can you try that out and confirm the
fix?  I don't remember the other bug reported confirmed this issue was
fixed by upgrading Ruby.

Thanks.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Any signal other than -9 causes full CPU utilization by master unicorn process on FreeBSD
@ 2012-07-17  0:33  4% Mark Mccraw
  2012-07-17  2:05  0% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Mark Mccraw @ 2012-07-17  0:33 UTC (permalink / raw)
  To: mongrel-unicorn@rubyforge.org

Hi There!

I'm having a devil of a time figuring out a weird issue I'm running into.  I have unicorn configured to start 4 worker processes, and that works great.  However, when it's time to cycle the app, everything goes haywire. By trial and error, I have narrowed it down to this:  sending any signal to the master process other than SIGKILL fails miserably.  No new master process is created, as described in the documentation, nothing happens to the existing workers, nothing gets written to any log, and if I run top -u, I can see that very quickly the master ramps up to 100% CPU utilization.  This happens if I run 'kill -HUP <master pid>', 'kill -USR2 <master pid>', even 'kill -QUIT <master pid>'.

Here's what I'm running on:

uname -a
FreeBSD bb20web04.unx.sas.com 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 2012     root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64

ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [amd64-freebsd9]

gem list | grep unicorn
unicorn (4.3.1)

My unicorn.rb file is pasted at the bottom.  It should be noted that I have tried every permutation of this I can think of to narrow out the problematic part (set preload_app to false, comment out preload_app), comment out before_exec, before_fork, after_fork, comment out the START_CTX[0] bit, etc), but things always fail the same way, so I'm guessing it's not the config, but I'm open to anything.  

Any suggestions at all are greatly appreciated.  I'd love to know how to interrupt the master process when it's slamming the CPU and get a stack trace, but I have no idea how in ruby.  Any thoughts?

Thanks!
Mark


APP_ROOT="/usr/local/rails/partsdb/current"
working_directory APP_ROOT
pid "#{APP_ROOT}/tmp/pids/unicorn.pid"
stderr_path "#{APP_ROOT}/log/unicorn.log"
stdout_path "#{APP_ROOT}/log/unicorn.log"
Unicorn::HttpServer::START_CTX[0] = "#{APP_ROOT}/bin/unicorn"
rails_env = ENV['RAILS_ENV'] || 'production'
worker_processes 4
timeout 120

# Speed up worker spawn times
preload_app true

listen "/tmp/unicorn.sock", :backlog => 10
listen "bb20web04:8080", :backlog => 1024

before_exec do |server|
  ENV["BUNDLE_GEMFILE"] = "#{APP_ROOT}/Gemfile"
end

before_fork do |server, worker|
  ##
  # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
  # immediately start loading up a new version of itself (loaded with a new
  # version of our app). When this new Unicorn is completely loaded
  # it will begin spawning workers. The first worker spawned will check to
  # see if an .oldbin pidfile exists. If so, this means we've just booted up
  # a new Unicorn and need to tell the old one that it can now die. To do so
  # we send it a QUIT.
  #
  # Using this method we get 0 downtime deploys.
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
  end
  old_pid = APP_ROOT + '/tmp/pids/unicorn.pid.oldbin'
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end


after_fork do |server, worker|
  ##
  # Unicorn master loads the app then forks off workers - because of the way
  # Unix forking works, we need to make sure we aren't using any of the parent's
  # sockets, e.g. db connection
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
  end
  # Redis and Memcached would go here but their connections are established
  # on demand, so the master never opens a socket
end


_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 4%]

* [Suggestion] Add upstream param to listen statement
@ 2012-05-23 13:29  7% Manuel Valente
  0 siblings, 0 replies; 200+ results
From: Manuel Valente @ 2012-05-23 13:29 UTC (permalink / raw)
  To: mongrel-unicorn

Hi,

It would be nice to be able to reject all incoming requests to unicorn 
if they do not originate from our upstream http server.

An additional parameter to the listen statement is perhaps the best way 
to achieve this :

server.listen(addr, :tries => -1, :delay => 5, :backlog => 128, 
:upstream => '10.0.0.1')

This param could be a string or an array of IP addresses.

I read the documentation but did not find any way to achieve this.

Best regards,

-- 
Manuel Valente
prixing.fr

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: [raindrops] testers on 32-bit FreeBSD wanted
  @ 2012-05-12  6:05  6% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-05-12  6:05 UTC (permalink / raw)
  To: mongrel-unicorn

Eric Wong <normalperson@yhbt.net> wrote:
> Since unicorn users are raindrops users, I'd appreciate it if
> 32-bit FreeBSD users can give this a try.  Thanks!

I've tested on a i386 FreeBSD 9.0 install I made and seems fine.
Not sure about FreeBSD 7.0, though, but that's pretty ancient...

Anyways, raindrops 0.8.1 is out.

Changes:

This release fixes a build problem found under a current SmartOS.  This
release also runs successfully on FreeBSD 9.0 under both x86-64 and
i386.

There are also documentation updates from Aman Gupta and a test suite
fix from Jeremy Evans for OpenBSD.

raindrops fully supports unicorn on recent versions of FreeBSD, OpenBSD,
SmartOS, and possibly other Free Software systems.  Portability reports
and fixes for Free Software systems is greatly appreciated at
raindrops@librelist.org

Non-Free systems will never be supported.

raindrops requires the Linux 2.6.18 or later for full functionality
(which unicorn does not require).  Future releases will take advantage
of the unix_diag functionality found in the Linux 3.3 (and later)
kernels.

* http://raindrops.bogomips.org/
* raindrops@librelist.org
* git://bogomips.org/raindrops.git
* http://raindrops.bogomips.org/NEWS.atom.xml
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: An Issue with max request uri length
  @ 2012-05-08 19:13  8% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-05-08 19:13 UTC (permalink / raw)
  To: unicorn list

Vladislav Shub <vlad@yotpo.com> wrote:
> Hi,
> I have a unicorn server that receives a long http GET request and i
> got 414 Request-URI Too Long.
> After looking around I have found that it's hard coded to 15k (
> global_variables.h:65   DEF_MAX_LENGTH(REQUEST_URI, 1024 * 15);) the
> question is what is the main reason for this restriction

This restriction reduces vectors for attacks (hash collision, memory
exhaustion/fragmentation and most importantly: things we have yet to
think of).

> and can it be overwritten by some configuration and if not can you
> please patch it to work with a configuration?

I'm against adding configuration parameters hardly anybody needs or
uses.  Its more things in the documentation (too much
documentation/options is confusing for users).  This restriction has
been in more widely deployed servers (e.g.  mongrel/thin) for many years
before unicorn and hardly anybody has an issue with it.

Why do you need to such a long URI?  Do you expect users to follow such
long URLs?  How often do you actually see such long URLs from other
applications, perhaps your app is doing something wrong?

Given the prevalence/popularity of URL shorteners, perhaps using shorter
URLs in the first place is a good idea :)
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 8%]

* Re: unicorn + sleep = long wake up loading time
  2012-04-28  2:46  6% unicorn + sleep = long wake up loading time adam k
@ 2012-04-28  4:40  0% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-04-28  4:40 UTC (permalink / raw)
  To: unicorn list

adam k <adam.ffa@gmail.com> wrote:
> I'm running unicorn behind nginx. If the site isn't accessed for a
> long period of time, the next access of the site is loads very slowly,
> sometimes even a 404 error shows. Subsequent requests have a normal
> loading time until the site isn't accessed for a long period of time
> again. How do I stop this behavior?

unicorn is likely getting swapped out or a backend connection
(e.g. database connection) is getting timed out due to
inactivity.

* How much memory (RSS) is each worker using when the site is active?
* Is RSS noticeably lower when the site's been idle for a long time?
* How many unicorn worker processes?

(the above 3 questions also apply to nginx, but nginx usually uses
 much less memory than unicorn)

* How much physical RAM do you have?
* What is the timeout value of unicorn? (default is 60s)
* What else is running on the machine?
* Anything mentioned in the unicorn stderr logs, or your application logs?

The updatedb cronjob is one major culprit of causing apps to swap out,
but it could be any number of things (backup jobs, rootkit scanners,
prelink, ...).

Try setting up a cronjob run curl to hit an endpoint of your app
every few minutes.  Make sure that endpoint exercises whatever
non-local dependencies (hits the DB, etc...) your app has.

> I looked at the code for unicorn and it seems to happen when unicorn
> is looking to kill "lazy" workers and then if it chooses not to, it
> creates a sleep period based on a timeout + 1. I also read the
> documentation and searched the mailing list starting from 2011.

I think you're looking at the master process, which shouldn't
affect performance of the workers.  The workers wake up whenever
there's socket activity, but it can take longer if they're swapped
out.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* unicorn + sleep = long wake up loading time
@ 2012-04-28  2:46  6% adam k
  2012-04-28  4:40  0% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: adam k @ 2012-04-28  2:46 UTC (permalink / raw)
  To: mongrel-unicorn

Hey,

I'm running unicorn behind nginx. If the site isn't accessed for a
long period of time, the next access of the site is loads very slowly,
sometimes even a 404 error shows. Subsequent requests have a normal
loading time until the site isn't accessed for a long period of time
again. How do I stop this behavior?

I looked at the code for unicorn and it seems to happen when unicorn
is looking to kill "lazy" workers and then if it chooses not to, it
creates a sleep period based on a timeout + 1. I also read the
documentation and searched the mailing list starting from 2011.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: Request-URI Too Long from mongrel-unicorn
  @ 2012-04-12  3:52  7%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-04-12  3:52 UTC (permalink / raw)
  To: unicorn list; +Cc: Nuo Yan

Nuo Yan <yan.nuo@gmail.com> wrote:
> On Apr 11, 2012, at 1:30 PM, Eric Wong wrote:
> > I will consider upping REQUEST_PATH to 4096 (and REQUEST_URI to 15K)
> > since 4096 is a common filesystem PATH_MAX on modern systems.
> 
> 4k makes sense to me. When do you think you can cut a gem on this?

I might wait a week for others to chime in before making an official
release.  However, packaging your own gem should be relatively easy
and it is documented in the HACKING file.

> Also, what do you think about making these values configurable in the
> conf file? I understand these were hard coded by design to protect the
> server. However, I think it would be nice if it defaults to these
> small values and can be configured flexibly. 

I'm against adding too many configuration variables as it's difficult to
support (needs documentation, testing, including testing for corner
cases, error handling, etc...).  Too many exposed configuration values
scares off new users.

Given how few people have an issue with these values, I don't think it's
worth the effort.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: Problem restarting Unicorn
  2012-04-05 11:34  7% ` Michael Guterl
@ 2012-04-10  8:52  7%   ` Andrew Stewart
  0 siblings, 0 replies; 200+ results
From: Andrew Stewart @ 2012-04-10  8:52 UTC (permalink / raw)
  To: unicorn list


On 5 Apr 2012, at 13:34, Michael Guterl wrote:
> On Thu, Apr 5, 2012 at 3:21 AM, Andrew Stewart <boss@airbladesoftware.com> wrote:
>> I just had a problem where a bundled gem wasn't being seen by the Unicorn processes, even though app code I introduced at the same time was being served by the Unicorn processes.  I had restarted Unicorn numerous times using `bundle exec cap deploy:restart` (see the code below), which I thought was the right way to do zero-downtime restarts, but my problem was only solved by doing a hard restart of Unicorn with `bundle exec cap deploy:hard_restart`.
> 
> You probably want to check out the Sandbox documentation here:
> http://unicorn.bogomips.org/Sandbox.html

Thanks for the pointer to the Sandbox documentation, the one page on the Unicorn website I hadn't read.  The section on BUNDLE_GEMFILE for Capistrano users was what I needed.

Yours,
Andy Stewart
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: Problem restarting Unicorn
  @ 2012-04-05 11:34  7% ` Michael Guterl
  2012-04-10  8:52  7%   ` Andrew Stewart
  0 siblings, 1 reply; 200+ results
From: Michael Guterl @ 2012-04-05 11:34 UTC (permalink / raw)
  To: unicorn list

On Thu, Apr 5, 2012 at 3:21 AM, Andrew Stewart
<boss@airbladesoftware.com> wrote:
> Hello,
>
> I seem to be confused about how to restart Unicorn when deploying updates to a Rails app via Capistrano.
>
> I just had a problem where a bundled gem wasn't being seen by the Unicorn processes, even though app code I introduced at the same time was being served by the Unicorn processes.  I had restarted Unicorn numerous times using `bundle exec cap deploy:restart` (see the code below), which I thought was the right way to do zero-downtime restarts, but my problem was only solved by doing a hard restart of Unicorn with `bundle exec cap deploy:hard_restart`.
>
> With each "normal" restart I tailed the stderr log to check everything was ok; everything appeared fine, with gems refreshed etc.
>
> Please could somebody explain what I'm doing wrong with my normal restarts?
>
> config/deploy.rb:
>
>    set :unicorn_config, "#{current_path}/config/unicorn.rb"
>    set :unicorn_pid,    "#{shared_path}/pids/unicorn.pid"
>
>    namespace :deploy do
>      task :start, :roles => :app, :except => { :no_release => true } do
>        run "cd #{current_path} && #{sudo_workaround} bundle exec unicorn -c #{unicorn_config} -E #{rails_env} -D"
>      end
>      task :stop, :roles => :app, :except => { :no_release => true } do
>        run "#{sudo_workaround} kill -s QUIT `cat #{unicorn_pid}`"
>      end
>      task :hard_stop, :roles => :app, :except => { :no_release => true } do
>        run "#{sudo_workaround} kill `cat #{unicorn_pid}`"
>      end
>      task :restart, :roles => :app, :except => { :no_release => true } do
>        run "#{sudo_workaround} kill -s USR2 `cat #{unicorn_pid}`"
>      end
>      task :hard_restart, :roles => :app, :except => { :no_release => true } do
>        hard_stop
>        start
>      end
>    end
>
>    # Works around Ubuntu changing the PATH when you use sudo.
>    # sudo's path can find common commands like echo but not much else.
>    def sudo_workaround
>      "sudo env PATH=$PATH"
>    end
>
>
> config/unicorn.rb:
>
>    APP_PATH = '/var/www/apps/sparkle'
>    worker_processes 4
>    user 'rails', 'rails'
>    working_directory "#{APP_PATH}/current"
>    listen "/tmp/unicorn_sparkle.sock", :backlog => 64
>    timeout 30
>    pid "#{APP_PATH}/shared/pids/unicorn.pid"
>    stderr_path "#{APP_PATH}/shared/log/unicorn.stderr.log"
>    stdout_path "#{APP_PATH}/shared/log/unicorn.stdout.log"
>    preload_app true
>    GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
>
>    before_fork do |server, worker|
>      defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
>
>      old_pid = "#{server.config[:pid]}.oldbin"
>      if old_pid != server.pid
>        begin
>          sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
>          Process.kill(sig, File.read(old_pid).to_i)
>        rescue Errno::ENOENT, Errno::ESRCH
>        end
>      end
>    end
>
>    after_fork do |server, worker|
>      defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
>    end
>
> This is all with Unicorn 4.2.0 and Rails 3.0.11.
>
> Many thanks in advance,
>

You probably want to check out the Sandbox documentation here:
http://unicorn.bogomips.org/Sandbox.html

The section that I think is most relevant is related to setting the START_CTX:

Unicorn::HttpServer::START_CTX[0] = "/some/path/to/bin/unicorn"

Hope that helps.

Best,
Michael Guterl
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* unicorn 4.2.1 release soon?
@ 2012-03-22  6:30  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-03-22  6:30 UTC (permalink / raw)
  To: mongrel-unicorn

There's not much going on in unicorn.git nowadays, everything's
stabilized nicely over the past few years.

This release would mainly be for for Graham's EPERM fix/workaround for
stale pid files and some documentation fixes improvements.

Shortlog below:

  Eric Wong (4):
        examples/nginx.conf: remove redundant word
        examples/nginx.conf: use $scheme instead of hard-coded "https"
        KNOWN_ISSUES: document signal conflicts in libs/apps
        log EPERM errors from invalid pid files

  Graham Bleach (1):
        Start the server if another user has a PID matching our stale pidfile.

$ git clone git://bogomips.org/unicorn.git


I'm also going on vacation soon, so I'll have almost no Internet access
for a few weeks.  Help each other out when I'm away, thanks :)
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* [ANN] unicorn 4.2.0 - minor fixes and improvements
@ 2012-01-28  9:25  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2012-01-28  9:25 UTC (permalink / raw)
  To: mongrel-unicorn

Changes:

The GPLv3 is now an option to the Unicorn license.  The existing GPLv2
and Ruby-only terms will always remain options, but the GPLv3 is
preferred.

Daemonization is correctly detected on all terminals for development
use (Brian P O'Rourke).

Unicorn::OobGC respects applications that disable GC entirely
during application dispatch (Yuichi Tateno).

Many test fixes for OpenBSD, which may help other *BSDs, too.
(Jeremy Evans).

There is now _optional_ SSL support (via the "kgio-monkey"
RubyGem).  On fast, secure LANs, SSL is only intended for
detecting data corruption that weak TCP checksums cannot detect.
Our SSL support is remains unaudited by security experts.

There are also some minor bugfixes and documentation
improvements.

Ruby 2.0.0dev also has a copy-on-write friendly GC which can save memory
when combined with "preload_app true", so if you're in the mood, start
testing Unicorn with the latest Ruby!

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: Default Socket Location
  2012-01-20 15:35  6% Default Socket Location Steven Garcia
@ 2012-01-20 17:22  0% ` Devin Ben-Hur
  0 siblings, 0 replies; 200+ results
From: Devin Ben-Hur @ 2012-01-20 17:22 UTC (permalink / raw)
  To: mongrel-unicorn

On 01/20/2012 07:35 AM, Steven Garcia wrote:
> I am collaborating on a Rails app with a very minimal unicorn config
> (the socket dir is not specified)
>
> I have booted up the app and created the necessary nginx server config
> for it, but it does not seem to be finding the socket file (502 error)
>
> Was just wondering where this file would be by default. Looking at
> unicorn's documentation I had expected it to be living in the /tmp
> directory, but no such luck.
>
> For good measure I also checked my app's tmp/sockets folder but no dice either

You could use `sudo lsof -p <unicorn-PID>` to see all the open files of 
a running unicorn.  This will show you shared objects, files, pipes, 
sockets, etc.

> Since this app is a joint effort, specifying the socket location in
> the config is not an option

Unicorn defaults to listening on TCP 0.0.0.0:8080 unless you tell it 
something else. It wont listen on a unix domain socket unless you 
configure it to.

You can use --listen with the unicorn startup script 
<http://unicorn.bogomips.org/unicorn_1.html> or the 
listen(address,options) method in your unicorn.conf 
<http://unicorn.bogomips.org/Unicorn/Configurator.html> to change this.

I don't see how being a collaborator on a joint effort means you can't 
change config, it just means you need to discuss and agree on the common 
configuration.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Default Socket Location
@ 2012-01-20 15:35  6% Steven Garcia
  2012-01-20 17:22  0% ` Devin Ben-Hur
  0 siblings, 1 reply; 200+ results
From: Steven Garcia @ 2012-01-20 15:35 UTC (permalink / raw)
  To: mongrel-unicorn

I am collaborating on a Rails app with a very minimal unicorn config
(the socket dir is not specified)

I have booted up the app and created the necessary nginx server config
for it, but it does not seem to be finding the socket file (502 error)

Was just wondering where this file would be by default. Looking at
unicorn's documentation I had expected it to be living in the /tmp
directory, but no such luck.

For good measure I also checked my app's tmp/sockets folder but no dice either

Since this app is a joint effort, specifying the socket location in
the config is not an option

Any idea?
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* [PATCH] doc: add Application Timeouts document
@ 2011-08-25  1:02  9% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-08-25  1:02 UTC (permalink / raw)
  To: mongrel-unicorn

Hopefully this leads to fewer worker processes being killed.
---
 I just pushed this out to the website:
   http://unicorn.bogomips.org/Application_Timeouts.html

 Comments/feedback/corrections greatly appreciated.

 .document            |    1 +
 Application_Timeouts |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 0 deletions(-)
 create mode 100644 Application_Timeouts

diff --git a/.document b/.document
index a3d7605..4092597 100644
--- a/.document
+++ b/.document
@@ -26,3 +26,4 @@ unicorn_rails_1
 ISSUES
 Sandbox
 Links
+Application_Timeouts
diff --git a/Application_Timeouts b/Application_Timeouts
new file mode 100644
index 0000000..5f0370d
--- /dev/null
+++ b/Application_Timeouts
@@ -0,0 +1,77 @@
+= Application Timeouts
+
+This article focuses on _application_ setup for Rack applications, but
+can be expanded to all applications that connect to external resources
+and expect short response times.
+
+This article is not specific to \Unicorn, but exists to discourage
+the overuse of the built-in
+{timeout}[link:Unicorn/Configurator.html#method-i-timeout] directive
+in \Unicorn.
+
+== ALL External Resources Are Considered Unreliable
+
+Network reliability can _never_ be guaranteed.  Network failures cannot
+be detected reliably by the client (Rack application) in a reasonable
+timeframe, not even on a LAN.
+
+Thus, application authors must configure timeouts when interacting with
+external resources.
+
+Most database adapters allow configurable timeouts.
+
+Net::HTTP and Net::SMTP in the Ruby standard library allow
+configurable timeouts.
+
+Even for things as fast as {memcached}[http://memcached.org/],
+{dalli}[http://rubygems.org/gems/dalli],
+{memcached}[http://rubygems.org/gems/memcached] and
+{memcache-client}[http://rubygems.org/gems/memcache-client] RubyGems all
+offer configurable timeouts.
+
+Consult the relevant documentation for the libraries you use on
+how to configure these timeouts.
+
+== Rolling Your Own Socket Code
+
+Use non-blocking I/O and IO.select with a timeout to wait on sockets.
+
+== Timeout module in the Ruby standard library
+
+Ruby offers a Timeout module in its standard library.  It has several
+caveats and is not always reliable:
+
+* /Some/ Ruby C extensions are not interrupted/timed-out gracefully by
+  this module (report these bugs to extension authors, please) but
+  pure-Ruby components should be.
+
+* Long-running tasks may run inside `ensure' clauses after timeout
+  fires, causing the timeout to be ineffective.
+
+The Timeout module is a second-to-last-resort solution, timeouts using
+IO.select (or similar) are more reliable.  If you depend on libraries
+that do not offer timeouts when connecting to external resources, kindly
+ask those library authors to provide configurable timeouts.
+
+=== A Note About Filesystems
+
+Most operations to regular files on POSIX filesystems are NOT
+interruptable.  Thus, the "timeout" module in the Ruby standard library
+can not reliably timeout systems with massive amounts of iowait.
+
+If your app relies on the filesystem, ensure all the data your
+application works with is small enough to fit in the kernel page cache.
+Otherwise increase the amount of physical memory you have to match, or
+employ a fast, low-latency storage system (solid state).
+
+Volumes mounted over NFS (and thus a potentially unreliable network)
+must be mounted with timeouts and applications must be prepared to
+handle network/server failures.
+
+== The Last Line Of Defense
+
+The {timeout}[link:Unicorn/Configurator.html#method-i-timeout] mechanism
+in \Unicorn is an extreme solution that should be avoided whenever
+possible.  It will help catch bugs in your application where and when
+your application forgets to use timeouts, but it is expensive as it
+kills and respawns a worker process.
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 9%]

* [ANN] unicorn 3.7.0 - minor feature update
@ 2011-06-09 20:55  7% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-06-09 20:55 UTC (permalink / raw)
  To: mongrel-unicorn

Changes:

* miscellaneous documentation improvements
* return 414 (instead of 400) for Request-URI Too Long
* strip leading and trailing linear whitespace in header values

User-visible improvements meant for Rainbows! users:

* add :ipv6only "listen" option (same as nginx)
---
* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://bogomips.org/unicorn.git

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* [PATCH] configurator: add :ipv6only directive
  @ 2011-06-07 21:05  6% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-06-07 21:05 UTC (permalink / raw)
  To: mongrel-unicorn

Eric Wong <normalperson@yhbt.net> wrote:
> Unicorn itself supports IPv6, too, but nobody uses/needs it.
> I'll add :ipv6only support shortly (probably tomorrow).

Pushed to unicorn.git (c3880bb0cc00821d1715a7dd94b0b76a03a7ace0)

Documentation below:

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index b6ad022..0b84d53 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -281,6 +281,22 @@ class Unicorn::Configurator
   #
   #   Default: +true+ in \Unicorn 3.4+, +false+ in Rainbows!
   #
+  # [:ipv6only => true or false]
+  #
+  #   This option makes IPv6-capable TCP listeners IPv6-only and unable
+  #   to receive IPv4 queries on dual-stack systems.  A separate IPv4-only
+  #   listener is required if this is true.
+  #
+  #   This option is only available for Ruby 1.9.2 and later.
+  #
+  #   Enabling this option for the IPv6-only listener and having a
+  #   separate IPv4 listener is recommended if you wish to support IPv6
+  #   on the same TCP port.  Otherwise, the value of \env[\"REMOTE_ADDR\"]
+  #   will appear as an ugly IPv4-mapped-IPv6 address for IPv4 clients
+  #   (e.g ":ffff:10.0.0.1" instead of just "10.0.0.1").
+  #
+  #   Default: Operating-system dependent
+  #
   # [:tries => Integer]
   #
   #   Times to retry binding a socket if it is already in use
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 6%]

* Re: [PATCH] Ensure that 'make gem' builds the documentation too.
  2011-06-07 15:11 12%   ` Hongli Lai
@ 2011-06-07 17:06 12%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-06-07 17:06 UTC (permalink / raw)
  To: unicorn list

Hongli Lai <hongli@phusion.nl> wrote:
> On Mon, Jun 6, 2011 at 7:51 PM, Eric Wong <normalperson@yhbt.net> wrote:
> > Oops, this was a regression introduced when I switched to wrongdoc
> > in f62ef19a4aa3d3e4ce1aa37a499907ff776a8964
> >
> > Perhaps this is better?  It'll also affect the tgz target and not
> > just the gem target.
> 
> I'm fine with it if it works. :)

Pushed out with the following commit message:

From 0dc56fd03ea478ae054e3d0398703f43e017723b Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Tue, 7 Jun 2011 09:56:30 -0700
Subject: [PATCH] build: ensure gem and tgz targets build manpages

Original patch by Hongli Lai <hongli@phusion.nl>:

> >From bfefc2cf0efb0913a42862886363b3140dcdbb2a Mon Sep 17 00:00:00 2001
> From: Hongli Lai (Phusion) <hongli@phusion.nl>
> Date: Mon, 6 Jun 2011 13:39:00 +0200
> Subject: [PATCH] Ensure that 'make gem' builds the documentation too.
>
> If autogenerated documentation files, like man pages, don't exist then
> 'make gem' will fail, complaining that some files are not found. By
> depending the 'gem' target on the 'doc' target we ensure that 'make gem'
> always works.
>
> Signed-off-by: Hongli Lai (Phusion) <hongli@phusion.nl>

ref: http://mid.gmane.org/4DED0EE2.7040400@phusion.nl
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 12%]

* Re: [PATCH] Ensure that 'make gem' builds the documentation too.
  2011-06-06 17:51 12% ` Eric Wong
@ 2011-06-07 15:11 12%   ` Hongli Lai
  2011-06-07 17:06 12%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Hongli Lai @ 2011-06-07 15:11 UTC (permalink / raw)
  To: unicorn list

On Mon, Jun 6, 2011 at 7:51 PM, Eric Wong <normalperson@yhbt.net> wrote:
> Oops, this was a regression introduced when I switched to wrongdoc
> in f62ef19a4aa3d3e4ce1aa37a499907ff776a8964
>
> Perhaps this is better?  It'll also affect the tgz target and not
> just the gem target.

I'm fine with it if it works. :)

-- 
Phusion | Ruby & Rails deployment, scaling and tuning solutions

Web: http://www.phusion.nl/
E-mail: info@phusion.nl
Chamber of commerce no: 08173483 (The Netherlands)
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 12%]

* Re: [PATCH] Ensure that 'make gem' builds the documentation too.
  2011-06-06 17:31 20% [PATCH] Ensure that 'make gem' builds the documentation too Hongli Lai
@ 2011-06-06 17:51 12% ` Eric Wong
  2011-06-07 15:11 12%   ` Hongli Lai
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2011-06-06 17:51 UTC (permalink / raw)
  To: unicorn list

Hongli Lai <hongli@phusion.nl> wrote:
> >From bfefc2cf0efb0913a42862886363b3140dcdbb2a Mon Sep 17 00:00:00 2001
> From: Hongli Lai (Phusion) <hongli@phusion.nl>
> Date: Mon, 6 Jun 2011 13:39:00 +0200
> Subject: [PATCH] Ensure that 'make gem' builds the documentation too.
> 
> If autogenerated documentation files, like man pages, don't exist then
> 'make gem' will fail, complaining that some files are not found. By
> depending the 'gem' target on the 'doc' target we ensure that 'make gem'
> always works.
> 
> Signed-off-by: Hongli Lai (Phusion) <hongli@phusion.nl>

Oops, this was a regression introduced when I switched to wrongdoc
in f62ef19a4aa3d3e4ce1aa37a499907ff776a8964

Perhaps this is better?  It'll also affect the tgz target and not
just the gem target.

diff --git a/GNUmakefile b/GNUmakefile
index da55052..61fb739 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -164,7 +164,7 @@ pkg_extra := GIT-VERSION-FILE ChangeLog LATEST NEWS \
 ChangeLog: GIT-VERSION-FILE .wrongdoc.yml
 	wrongdoc prepare
 
-.manifest: ChangeLog $(ext)/unicorn_http.c
+.manifest: ChangeLog $(ext)/unicorn_http.c man
 	(git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
 	  LC_ALL=C sort > $@+
 	cmp $@+ $@ || mv $@+ $@
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 12%]

* [PATCH] Ensure that 'make gem' builds the documentation too.
@ 2011-06-06 17:31 20% Hongli Lai
  2011-06-06 17:51 12% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Hongli Lai @ 2011-06-06 17:31 UTC (permalink / raw)
  To: unicorn list

>From bfefc2cf0efb0913a42862886363b3140dcdbb2a Mon Sep 17 00:00:00 2001
From: Hongli Lai (Phusion) <hongli@phusion.nl>
Date: Mon, 6 Jun 2011 13:39:00 +0200
Subject: [PATCH] Ensure that 'make gem' builds the documentation too.

If autogenerated documentation files, like man pages, don't exist then
'make gem' will fail, complaining that some files are not found. By
depending the 'gem' target on the 'doc' target we ensure that 'make gem'
always works.

Signed-off-by: Hongli Lai (Phusion) <hongli@phusion.nl>
---
 GNUmakefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile
index 4072826..90cc451 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -257,7 +257,7 @@ gem: $(pkggem)
 install-gem: $(pkggem)
 	gem install $(CURDIR)/$<

-$(pkggem): .manifest fix-perms
+$(pkggem): .manifest fix-perms doc
 	gem build $(rfpackage).gemspec
 	mkdir -p pkg
 	mv $(@F) $@
-- 
1.7.5

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 20%]

* Re: [PATCH] Document the method for building the Unicorn gem
  2011-06-06 16:58  0% ` Eric Wong
@ 2011-06-06 17:06  9%   ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-06-06 17:06 UTC (permalink / raw)
  To: unicorn list

Eric Wong <normalperson@yhbt.net> wrote:
> Can somebody confirm ronn doesn't introduce any JavaScript? (or can made
> to be JS-free easily).

Actually, the wrongdoc documentation already uses ronn and wrongdoc
documentation is definitely JavaScript-free :)

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 9%]

* Re: [PATCH] Document the method for building the Unicorn gem
  2011-06-06 11:44  6% [PATCH] Document the method for building the Unicorn gem Hongli Lai
@ 2011-06-06 16:58  0% ` Eric Wong
  2011-06-06 17:06  9%   ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2011-06-06 16:58 UTC (permalink / raw)
  To: unicorn list

Hongli Lai <hongli@phusion.nl> wrote:
> >From dcd47a609f4489bb37ce33ea1ce975bb2b3ab160 Mon Sep 17 00:00:00 2001
> From: Hongli Lai (Phusion) <hongli@phusion.nl>
> Date: Mon, 6 Jun 2011 13:36:57 +0200
> Subject: [PATCH] Document the method for building the Unicorn gem.
> 
> Signed-off-by: Hongli Lai (Phusion) <hongli@phusion.nl>

Thanks, applied and pushed.

> index 781c4ca..38f2f2a 100644
> --- a/HACKING
> +++ b/HACKING
> @@ -107,6 +107,17 @@ git itself.  See the
> Documentation/SubmittingPatches document

The patch got line-wrapped there.  If your MUA of choice can't be taught
to leave lines unwrapped, try "git send-email".

> + * pandoc

If anybody has spare cycles to make this work with ronn instead of
pandoc, please send patches.  ronn should be an easier-to-install
for Rubyists since it doesn't depend on Haskell.

Can somebody confirm ronn doesn't introduce any JavaScript? (or can made
to be JS-free easily).

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* [PATCH] Document the method for building the Unicorn gem
@ 2011-06-06 11:44  6% Hongli Lai
  2011-06-06 16:58  0% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Hongli Lai @ 2011-06-06 11:44 UTC (permalink / raw)
  To: unicorn list

>From dcd47a609f4489bb37ce33ea1ce975bb2b3ab160 Mon Sep 17 00:00:00 2001
From: Hongli Lai (Phusion) <hongli@phusion.nl>
Date: Mon, 6 Jun 2011 13:36:57 +0200
Subject: [PATCH] Document the method for building the Unicorn gem.

Signed-off-by: Hongli Lai (Phusion) <hongli@phusion.nl>
---
 HACKING |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/HACKING b/HACKING
index 781c4ca..38f2f2a 100644
--- a/HACKING
+++ b/HACKING
@@ -107,6 +107,17 @@ git itself.  See the
Documentation/SubmittingPatches document
 distributed with git on on patch submission guidelines to follow.  Just
 don't email the git mailing list or maintainer with Unicorn patches :)

+== Building a Gem
+
+In order to build the gem, you must install the following components:
+
+ * wrongdoc
+ * pandoc
+
+You can build the Unicorn gem with the following command:
+
+  gmake gem
+
 == Running Development Versions

 It is easy to install the contents of your git working directory:
-- 
1.7.5

-- 
Phusion | Ruby & Rails deployment, scaling and tuning solutions

Web: http://www.phusion.nl/
E-mail: info@phusion.nl
Chamber of commerce no: 08173483 (The Netherlands)
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 6%]

* [ANN] unicorn 3.6.2 (and 1.1.7) - fix Unicorn::OobGC module
@ 2011-04-30  6:45  7% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-04-30  6:45 UTC (permalink / raw)
  To: mongrel-unicorn

Changes:

The optional Unicorn::OobGC module is reimplemented to fix
breakage that appeared in v3.3.1.  There are also minor
documentation updates, but no code changes as of 3.6.1 for
non-OobGC users.

There is also a v1.1.7 release to fix the same OobGC breakage
that appeared for 1.1.x users in the v1.1.6 release.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://bogomips.org/unicorn.git

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* Re: Struggling with logrotate and unicorn
  2011-04-12 18:59  6%     ` Eric Wong
@ 2011-04-12 22:38  0%       ` Emmanuel Gomez
  2011-04-12 22:51  0%         ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Emmanuel Gomez @ 2011-04-12 22:38 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

On Apr 12, 2011, at 11:59 AM, Eric Wong wrote:
> I'll make that more robust and release
> 3.6.0 sometime this week with (hopefully) a few other minor
> improvements.

Great. This is apparently an infrequent circumstance (uncommon configuration?), but there will be a next person who does this (or comparable silliness).

>> Thanks for your reply, I'm off to comment on the GitHub blog post to
>> try to warn others to use Unicorn::Worker#user instead of the example
>> code in after_fork.
> 
> Thanks, that seems to be a general problem with people relying on
> blog/mailing list posts instead of consistently updated documentation.

Indeed, but I read most of the unicorn docs, and examples/unicorn.conf.rb in 3.3.1 doesn't mention Unicorn::Worker#user, so I remained unaware until I read through worker.rb. 

Hey, I can help here. Here's a patch:


>From de3178d98c81de3c8765cebd579ef3f7dd4b2d64 Mon Sep 17 00:00:00 2001
From: Emmanuel Gomez <emmanuel.gomez@gmail.com>
Date: Tue, 12 Apr 2011 15:36:36 -0700
Subject: [PATCH] Document Unicorn::Worker#user in example unicorn conf.

---
 examples/unicorn.conf.rb |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index 28a9e65..8b7ad47 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -84,4 +84,8 @@ after_fork do |server, worker|
   # and Redis.  TokyoCabinet file handles are safe to reuse
   # between any number of forked children (assuming your kernel
   # correctly implements pread()/pwrite() system calls)
+
+  # if running the master process as root and the workers as an unprivileged
+  # user, do this to switch euid/egid in the workers (also chowns logs):
+  # worker.user("unprivileged_user", "unprivileged_group")
 end
-- 
1.7.3.4

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 0%]

* Re: Struggling with logrotate and unicorn
  2011-04-12 22:38  0%       ` Emmanuel Gomez
@ 2011-04-12 22:51  0%         ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-04-12 22:51 UTC (permalink / raw)
  To: unicorn list; +Cc: Emmanuel Gomez

Emmanuel Gomez <emmanuel.gomez@gmail.com> wrote:
> On Apr 12, 2011, at 11:59 AM, Eric Wong wrote:
> > I'll make that more robust and release 3.6.0 sometime this week with
> > (hopefully) a few other minor improvements.
> 
> Great. This is apparently an infrequent circumstance (uncommon
> configuration?), but there will be a next person who does this (or
> comparable silliness).

Yes, I think most people still deploy and start as non-root
(Capistrano/Vlad).  But I also distribute init scripts and those
are usually run as root :x

> >> Thanks for your reply, I'm off to comment on the GitHub blog post
> >> to try to warn others to use Unicorn::Worker#user instead of the
> >> example code in after_fork.
> > 
> > Thanks, that seems to be a general problem with people relying on
> > blog/mailing list posts instead of consistently updated
> > documentation.
> 
> Indeed, but I read most of the unicorn docs, and
> examples/unicorn.conf.rb in 3.3.1 doesn't mention
> Unicorn::Worker#user, so I remained unaware until I read through
> worker.rb.

Actually the (usually) user-visible one should be
Unicorn::Configurator#user which should be in the top-level.
Worker#user is just the internal call.

> Hey, I can help here. Here's a patch:

Perhaps this is better? I added a blurb discouraging people from
running as root in the first place.  You'll still get credit :)

>From c4d3cd7d7b32ed133e25e3740c8e7a3493592eec Mon Sep 17 00:00:00 2001
From: Emmanuel Gomez <emmanuel.gomez@gmail.com>
Date: Tue, 12 Apr 2011 15:36:36 -0700
Subject: [PATCH] Document "user" directive in example unicorn conf

---
 examples/unicorn.conf.rb |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index 28a9e65..61f0b4b 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -12,6 +12,13 @@
 # more will usually help for _short_ waits on databases/caches.
 worker_processes 4
 
+# Since Unicorn is never exposed to outside clients, it does not need to
+# run on the standard HTTP port (80), there is no reason to start Unicorn
+# as root unless it's from system init scripts.
+# If running the master process as root and the workers as an unprivileged
+# user, do this to switch euid/egid in the workers (also chowns logs):
+# user "unprivileged_user", "unprivileged_group"
+
 # Help ensure your application will always spawn in the symlinked
 # "current" directory that Capistrano sets up.
 working_directory "/path/to/app/current" # available in 0.94.0+
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 0%]

* Re: Struggling with logrotate and unicorn
  @ 2011-04-12 18:59  6%     ` Eric Wong
  2011-04-12 22:38  0%       ` Emmanuel Gomez
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2011-04-12 18:59 UTC (permalink / raw)
  To: unicorn list; +Cc: Emmanuel Gomez

Emmanuel Gomez <emmanuel.gomez@gmail.com> wrote:
> On Apr 12, 2011, at 10:58 AM, Eric Wong wrote:
> > Emmanuel Gomez <emmanuel.gomez@gmail.com> wrote:
> >> I have confirmed that logrotate creates the logs with a 0600 umask
> >> and the uid/gid of my unprivileged user (per my logrotate config,
> >> loosely based on the example logrotate.conf from 3.4 or 3.5). 
> > 
> > Did the permissions of the old (rotated) log files change?
> 
> No, they remained owned by root.

Remained owned by root?  Yes that sounds like the problem.

> >> The problem occurs when I send a USR1 signal to the master process
> >> (as root, because the master is running as root) after the logs
> >> have been rotated. As near as I can tell, after that the Unicorn
> >> master chowns the logs to root ownership. Then, the workers attempt
> >> to chown the logs back to ownership by the unprivileged user, which
> >> repeatedly fails, spewing megabytes of errors that look like:
> > 
> > The rotation error handling should probably just exit! the worker
> > and rely on the master to restart it...
> 
> That would probably be better behavior, although in this specific case
> the worker would immediately die on respawn because the log is still
> owned by root and unwriteable by my unprivileged user.
> 
> I did find a resolution: in the after_fork block, I had copied the
> code to switch users from the GitHub blog post on unicorn
> (https://github.com/blog/517-unicorn). I didn't see
> Unicorn::Worker#user, which implements the same code with the addition
> of a call to Unicorn::Util.chown_logs. When I replace the inline
> GitHub-blog-derived code with a call to Unicorn::Worker#user, it
> works. 

Yes, the old versions of Unicorn didn't change users at all.

I always knew user-switching is a pain in the ass to deal with due to
issues like this.   Due to work on Rainbows! (designed to run on port
80) and users starting as root anyways (due to init scripts), I needed
add this feature.

> My understanding is that this (after_fork/Unicorn::Util.chown_logs)
> shouldn't be executed on USR1; I don't see how the
> Unicorn::Util.chown_logs call on after_fork (startup) would make a
> difference w/r/t rotation (much later), but my understanding is
> obviously incomplete, because it works.

It's the rotation that attempts to chown since it thinks (incorrectly)
that it's in the master process.  I'll make that more robust and release
3.6.0 sometime this week with (hopefully) a few other minor
improvements.

> Thanks for your reply, I'm off to comment on the GitHub blog post to
> try to warn others to use Unicorn::Worker#user instead of the example
> code in after_fork.

Thanks, that seems to be a general problem with people relying on
blog/mailing list posts instead of consistently updated documentation.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 6%]

* Re: [RFC/PATCH] Bundler/Sandbox documentation updates
  2011-03-10  3:30 12%     ` Lawrence Pit
@ 2011-03-10 21:29 11%       ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-03-10 21:29 UTC (permalink / raw)
  To: unicorn list

Lawrence Pit <lawrence.pit@gmail.com> wrote:
> Eric Wong <normalperson@yhbt.net> wrote:
>> I've tried this a few times, and everytime I get something like this:
>>> https://gist.github.com/331b0decab62fd58483c
>> Yikes, it looks like the UNICORN_FD env is getting clobbered somehow.
>> Not sure what could be causing that.
>>
>>> If I revert back to setting the GEM_HOME, GEM_PATH and PATH in the
>>> before_exec it works fine.

> >  Which Bundler version is this with?
>
> Bundler 1.0.10

Odd, I actually used this in my Rainbows! config file to switch an
Isolate deploy to Bundler (1.0.10) yesterday.   Everything for Rainbows!
applies to Unicorn, too).

  # switching from Isolate to Bundler:
  if ENV["GEM_HOME"] =~ %r{/isolate/}
    ENV.delete "GEM_HOME"
    ENV.delete "GEM_PATH"
    # don't need anything else in $PATH for a web server
    ENV["PATH"] = "/home/ew/ruby-1.9.2/bin"

    # START_CTX is considered a stable interface in Unicorn
    start_ctx = Unicorn::HttpServer::START_CTX
    start_ctx[0] = "bundle"

    # it's even possible to use USR2 to switch between Unicorn and
    # Rainbows! without any downtime :)
    start_ctx[:argv] = %w(exec rainbows).concat(start_ctx[:argv])
  end

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 11%]

* Re: [RFC/PATCH] Bundler/Sandbox documentation updates
  2011-03-10  0:52 12%   ` Eric Wong
@ 2011-03-10  3:30 12%     ` Lawrence Pit
  2011-03-10 21:29 11%       ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Lawrence Pit @ 2011-03-10  3:30 UTC (permalink / raw)
  To: unicorn list


 >  Which Bundler version is this with?

Bundler 1.0.10


Cheers,
Lawrence

> I've tried this a few times, and everytime I get something like this:
>> https://gist.github.com/331b0decab62fd58483c
> Yikes, it looks like the UNICORN_FD env is getting clobbered somehow.
> Not sure what could be causing that.
>
>> If I revert back to setting the GEM_HOME, GEM_PATH and PATH in the
>> before_exec it works fine.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 12%]

* Re: [RFC/PATCH] Bundler/Sandbox documentation updates
  2011-03-09 10:39 12% ` Lawrence Pit
@ 2011-03-10  0:52 12%   ` Eric Wong
  2011-03-10  3:30 12%     ` Lawrence Pit
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2011-03-10  0:52 UTC (permalink / raw)
  To: unicorn list

Lawrence Pit <lawrence.pit@gmail.com> wrote:
> Hi Eric,
>
> I tested this out:

Thanks for taking your time to test.

> - in the before_exec and after_fork I log PATH GEM_HOME GEM_PATH  
> BUNDLE_GEMFILE for inspection after deployment
>
> - deploy latest release, make sure to shutdown unicorn, then start cleanly
>
> - prune all releases, except the last one
>
> - deploy latest release again (which only sets the BUNDLE_GEMFILE env var)
>
> I've tried this a few times, and everytime I get something like this:
>
> https://gist.github.com/331b0decab62fd58483c

Yikes, it looks like the UNICORN_FD env is getting clobbered somehow.
Not sure what could be causing that.

> If I revert back to setting the GEM_HOME, GEM_PATH and PATH in the  
> before_exec it works fine.

Which Bundler version is this with?

> PS. When deploying I use USR2 followed by QUIT
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 12%]

* Re: [RFC/PATCH] Bundler/Sandbox documentation updates
  2011-03-08 14:22 12% ` Justin Giancola
@ 2011-03-10  0:49 12%   ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2011-03-10  0:49 UTC (permalink / raw)
  To: unicorn list

Justin Giancola <justin.giancola@gmail.com> wrote:
> Setting BUNDLE_GEMFILE in the before_exec hook is the only
> Bundler-related Unicorn config I've needed for Bundler >= 1.0.3

Thanks, that seems to match my observations, too.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 12%]

* Re: [RFC/PATCH] Bundler/Sandbox documentation updates
  2011-03-08  4:40 10% [RFC/PATCH] Bundler/Sandbox documentation updates Eric Wong
  2011-03-08 14:22 12% ` Justin Giancola
@ 2011-03-09 10:39 12% ` Lawrence Pit
  2011-03-10  0:52 12%   ` Eric Wong
  1 sibling, 1 reply; 200+ results
From: Lawrence Pit @ 2011-03-09 10:39 UTC (permalink / raw)
  To: unicorn list

Hi Eric,

I tested this out:

- in the before_exec and after_fork I log PATH GEM_HOME GEM_PATH 
BUNDLE_GEMFILE for inspection after deployment

- deploy latest release, make sure to shutdown unicorn, then start cleanly

- prune all releases, except the last one

- deploy latest release again (which only sets the BUNDLE_GEMFILE env var)

I've tried this a few times, and everytime I get something like this:

https://gist.github.com/331b0decab62fd58483c

If I revert back to setting the GEM_HOME, GEM_PATH and PATH in the 
before_exec it works fine.


PS. When deploying I use USR2 followed by QUIT


Cheers,
Lawrence

> I started playing around with Bundler 1.0.10 today and noticed it's
> quite different than previous versions (based on my limited experiences)
> and the out-of-the-box experience is pretty good regarding (lack of)
> ENV pollution.
>
> Can any more experienced Bundler (and possibly Capistrano) users
> comment on the below changes and see if they make sense?
>
> Thanks in advance!
>
> diff --git a/Sandbox b/Sandbox
> index d101106..46dfb91 100644
> --- a/Sandbox
> +++ b/Sandbox
> @@ -45,11 +45,20 @@ This is no longer be an issue as of bundler 0.9.17
>
>   ref: http://mid.gmane.org/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com
>
> +=== BUNDLE_GEMFILE for Capistrano users
> +
> +You may need to set or reset the BUNDLE_GEMFILE environment variable in
> +the before_exec hook:
> +
> +        before_exec do |server|
> +          ENV["BUNDLE_GEMFILE"] = "/path/to/app/current/Gemfile"
> +        end
> +
>   === Other ENV pollution issues
>
> -You may need to set or reset BUNDLE_GEMFILE, GEM_HOME, GEM_PATH and PATH
> -environment variables in the before_exec hook as illustrated by
> -http://gist.github.com/534668
> +If you're using an older Bundler version (0.9.x), you may need to set or
> +reset GEM_HOME, GEM_PATH and PATH environment variables in the
> +before_exec hook as illustrated by http://gist.github.com/534668
>
>   == Isolate
>

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 12%]

* Re: [RFC/PATCH] Bundler/Sandbox documentation updates
  2011-03-08  4:40 10% [RFC/PATCH] Bundler/Sandbox documentation updates Eric Wong
@ 2011-03-08 14:22 12% ` Justin Giancola
  2011-03-10  0:49 12%   ` Eric Wong
  2011-03-09 10:39 12% ` Lawrence Pit
  1 sibling, 1 reply; 200+ results
From: Justin Giancola @ 2011-03-08 14:22 UTC (permalink / raw)
  To: unicorn list

Setting BUNDLE_GEMFILE in the before_exec hook is the only
Bundler-related Unicorn config I've needed for Bundler >= 1.0.3

For <= 1.0.2 not even this was necessary because the template
executables Bundler generates didn't fully resolve the BUNDLE_GEMFILE
path until 1.0.3


Justin

On Mon, Mar 7, 2011 at 11:40 PM, Eric Wong <normalperson@yhbt.net> wrote:
> I started playing around with Bundler 1.0.10 today and noticed it's
> quite different than previous versions (based on my limited experiences)
> and the out-of-the-box experience is pretty good regarding (lack of)
> ENV pollution.
>
> Can any more experienced Bundler (and possibly Capistrano) users
> comment on the below changes and see if they make sense?
>
> Thanks in advance!
>
> diff --git a/Sandbox b/Sandbox
> index d101106..46dfb91 100644
> --- a/Sandbox
> +++ b/Sandbox
> @@ -45,11 +45,20 @@ This is no longer be an issue as of bundler 0.9.17
>
>  ref: http://mid.gmane.org/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com
>
> +=== BUNDLE_GEMFILE for Capistrano users
> +
> +You may need to set or reset the BUNDLE_GEMFILE environment variable in
> +the before_exec hook:
> +
> +        before_exec do |server|
> +          ENV["BUNDLE_GEMFILE"] = "/path/to/app/current/Gemfile"
> +        end
> +
>  === Other ENV pollution issues
>
> -You may need to set or reset BUNDLE_GEMFILE, GEM_HOME, GEM_PATH and PATH
> -environment variables in the before_exec hook as illustrated by
> -http://gist.github.com/534668
> +If you're using an older Bundler version (0.9.x), you may need to set or
> +reset GEM_HOME, GEM_PATH and PATH environment variables in the
> +before_exec hook as illustrated by http://gist.github.com/534668
>
>  == Isolate
>
> --
> Eric Wong
> _______________________________________________
> Unicorn mailing list - mongrel-unicorn@rubyforge.org
> http://rubyforge.org/mailman/listinfo/mongrel-unicorn
> Do not quote signatures (like this one) or top post when replying
>
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 12%]

* [RFC/PATCH] Bundler/Sandbox documentation updates
@ 2011-03-08  4:40 10% Eric Wong
  2011-03-08 14:22 12% ` Justin Giancola
  2011-03-09 10:39 12% ` Lawrence Pit
  0 siblings, 2 replies; 200+ results
From: Eric Wong @ 2011-03-08  4:40 UTC (permalink / raw)
  To: mongrel-unicorn

I started playing around with Bundler 1.0.10 today and noticed it's
quite different than previous versions (based on my limited experiences)
and the out-of-the-box experience is pretty good regarding (lack of)
ENV pollution.

Can any more experienced Bundler (and possibly Capistrano) users
comment on the below changes and see if they make sense?

Thanks in advance!

diff --git a/Sandbox b/Sandbox
index d101106..46dfb91 100644
--- a/Sandbox
+++ b/Sandbox
@@ -45,11 +45,20 @@ This is no longer be an issue as of bundler 0.9.17
 
 ref: http://mid.gmane.org/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com
 
+=== BUNDLE_GEMFILE for Capistrano users
+
+You may need to set or reset the BUNDLE_GEMFILE environment variable in
+the before_exec hook:
+
+        before_exec do |server|
+          ENV["BUNDLE_GEMFILE"] = "/path/to/app/current/Gemfile"
+        end
+
 === Other ENV pollution issues
 
-You may need to set or reset BUNDLE_GEMFILE, GEM_HOME, GEM_PATH and PATH
-environment variables in the before_exec hook as illustrated by
-http://gist.github.com/534668
+If you're using an older Bundler version (0.9.x), you may need to set or
+reset GEM_HOME, GEM_PATH and PATH environment variables in the
+before_exec hook as illustrated by http://gist.github.com/534668
 
 == Isolate
 
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 10%]

* [ANN] unicorn 3.2.1 - parser improvements for Rainbows!
@ 2010-12-26  8:29  7% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-12-26  8:29 UTC (permalink / raw)
  To: mongrel-unicorn

There are numerous improvements in the HTTP parser for
Rainbows!, none of which affect Unicorn-only users.

The kgio dependency is incremented to 2.1: this should avoid
ENOSYS errors for folks building binaries on newer Linux
kernels and then deploying to older ones.

There are also minor documentation improvements, the website
is now JavaScript-free!

(Ignore the 3.2.0 release, I fat-fingered some packaging things)

Expect a new Rainbows! release in the next day or two with
the improved HTTP parser and Cool.io support.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* error when HUP'ing unicorn
@ 2010-11-12 20:51  3% Grant Heffernan
  0 siblings, 0 replies; 200+ results
From: Grant Heffernan @ 2010-11-12 20:51 UTC (permalink / raw)
  To: mongrel-unicorn

Anyone come across this one before?

Refreshing Gem list
error reloading config_file=/data/servers/patch-fe-apache/conf/unicorn.rb: TypeError can't convert Hash into Integer /opt/bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:89:in `read'/opt/bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:89:in `load_specification'/opt/bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:153:in `load_gems_in'/opt/bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:152:in `each'/opt/bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:152:in `load_gems_in'/opt/bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:149:in `reverse_each'/opt/bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:149:in `load_gems_in'/opt/bcs/packages/ruby-
 gems-1.8/lib/site_ruby/1.8/rubygems/source_index.rb:345:in `refresh!'/opt/bcs/packages/ruby-1.8.6/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/rails/vendor_gem_source_index.rb:34:in `refresh!'/opt
 /bcs/packages/ruby-gems-1.8/lib/site_ruby/1.8/rubygems.rb:746:in `refresh'/opt/bcs/packages/ruby-1.8.6/lib/ruby/gems/1.8/gems/unicorn-2.0.0/lib/unicorn/http_server.rb:673:in `build_app!'/opt/bcs/packages/ruby-1.8.6/lib/ruby/gems/1.8/gems/unicorn-2.0.0/lib/unicorn/http_server.rb:656:in `load_config!'/opt/bcs/packages/ruby-1.8.6/lib/ruby/gems/1.8/gems/unicorn-2.0.0/lib/unicorn/http_server.rb:330:in `join'/opt/bcs/packages/ruby-1.8.6/lib/ruby/gems/1.8/gems/unicorn-2.0.0/lib/unicorn.rb:13:in `run'/opt/bcs/packages/ruby-1.8.6/lib/ruby/gems/1.8/gems/unicorn-2.0.0/bin/unicorn_rails:208/opt/bcs/packages/ruby/bin/unicorn_rails:19:in `load'/opt/bcs/packages/ruby/bin/unicorn_rails:19


It appears our app isn't restarting when issuing a HUP, and I'm suspecting the above as the culprit. Unicorn restarts all workers without issue (other than the above error).


This is our basic config:

# Sample verbose configuration file for Unicorn (not Rack)
#
# This configuration file documents many features of Unicorn
# that may not be needed for some applications. See
# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
# for a much simpler configuration file.
#
# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
# documentation.

# Use at least one worker per core if you're on a dedicated server,
# more will usually help for _short_ waits on databases/caches.
worker_processes 30

# Help ensure your application will always spawn in the symlinked
# "current" directory that Capistrano sets up.
working_directory "/data/servers/app/current"

# listen on both a Unix domain socket and a TCP port,
# we use a shorter backlog for quicker failover when busy
#listen "/data/servers/patch-fe-apache/logs/.unicorn_sock", :backlog => 64
listen 8080

# nuke workers after 30 seconds instead of 60 seconds (the default)
timeout 30

# feel free to point this anywhere accessible on the filesystem
pid "/data/servers/app/logs/unicorn.pid"

# By default, the Unicorn logger will write to stderr.
# Additionally, ome applications/frameworks log to stderr or stdout,
# so prevent them from going to /dev/null when daemonized here:
stderr_path "/data/servers/app/logs/unicorn_error.log"
stdout_path "/data/servers/app/logs/unicorn_out.log"

# combine REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true

before_fork do |server, worker|
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!

  # The following is only recommended for memory/DB-constrained
  # installations.  It is not needed if your system can house
  # twice as many worker_processes as you have configured.
  #
  # # This allows a new master process to incrementally
  # # phase out the old master process with SIGTTOU to avoid a
  # # thundering herd (especially in the "preload_app false" case)
  # # when doing a transparent upgrade.  The last worker spawned
  # # will then kill off the old master process with a SIGQUIT.
  # old_pid = "#{server.config[:pid]}.oldbin"
  # if old_pid != server.pid
  #   begin
  #     sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
  #     Process.kill(sig, File.read(old_pid).to_i)
  #   rescue Errno::ENOENT, Errno::ESRCH
  #   end
  # end
  #
  # Throttle the master from forking too quickly by sleeping.  Due
  # to the implementation of standard Unix signal handlers, this
  # helps (but does not completely) prevent identical, repeated signals
  # from being lost when the receiving process is busy.
  # sleep 1
end

after_fork do |server, worker|
  # per-process listener ports for debugging/admin/migrations
  # addr = "127.0.0.1:#{9293 + worker.nr}"
  # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)

  # the following is *required* for Rails + "preload_app true",
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection

  # if preload_app is true, then you may also want to check and
  # restart any other shared sockets/descriptors such as Memcached,
  # and Redis.  TokyoCabinet file handles are safe to reuse
  # between any number of forked children (assuming your kernel
  # correctly implements pread()/pwrite() system calls)
end


--
Grant Heffernan

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 3%]

* [ANN] unicorn 1.1.4 - small bug fix and doc updates
@ 2010-10-04 20:37  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-10-04 20:37 UTC (permalink / raw)
  To: mongrel-unicorn

Changes:

We no longer unlinking actively listening sockets upon startup
(but continue to unlink dead ones).  This bug could trigger
downtime and nginx failures if a user makes an error and
attempts to start Unicorn while it is already running.

Thanks to Jordan Ritter for the detailed bug report leading to
this fix.

ref: http://mid.gmane.org/8D95A44B-A098-43BE-B532-7D74BD957F31@darkridge.com

There are also minor documentation and test updates pulled in
from master.  This is hopefully the last bugfix release of the
1.1.x series.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 6%]

* Re: Unicorn fails to restart gracefully on capistrano deploy
  @ 2010-09-15 21:52  8% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-09-15 21:52 UTC (permalink / raw)
  To: unicorn list

Eirik Dentz Sinclair <eirik@efficiency20.com> wrote:
> Lawrence, Jamie
> 
> Thanks very much for your responses.
> 
> The before_exec block in Lawrence's gist was just what was needed. Not sure how many others are using Capistrano and bundler, but seems like that before_exec block would be a good addition to this page: http://unicorn.bogomips.org/Sandbox.html
> 
> Thanks again for the help.

Thanks for confirming the fix.  I've updated the Sandbox document
with the following patch.

Patches/pull-requests to the mailing list for documentation are very
much appreciated, especially for Bundler and maybe other things I don't
use myself.  Lets try to treat the in-source documentation much like a
wiki, except anybody who grabs the source also has the latest up-to-date
docs ready for offline reading (and readable without a web browser :)

>From 1a75966a5d1a1f6307ed3386e2f91a28bbb72ca0 Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Wed, 15 Sep 2010 14:42:54 -0700
Subject: [PATCH] doc: update Sandbox document for Bundler

Thanks to Lawrence Pit, Jamie Wilkinson, and Eirik Dentz Sinclair.

ref: mid.gmane.org/4C8986DA.7090603@gmail.com
ref: mid.gmane.org/5F1A02DB-CBDA-4302-9E26-8050C2D72433@efficiency20.com
---
 Sandbox |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/Sandbox b/Sandbox
index d2f7590..d101106 100644
--- a/Sandbox
+++ b/Sandbox
@@ -24,6 +24,9 @@ this:
 Then use HUP to reload, and then continue with the USR2+QUIT upgrade
 sequence.
 
+Environment variable pollution when exec-ing a new process (with USR2)
+is the primary issue with sandboxing tools such as Bundler and Isolate.
+
 == Bundler
 
 === Running
@@ -42,6 +45,12 @@ This is no longer be an issue as of bundler 0.9.17
 
 ref: http://mid.gmane.org/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com
 
+=== Other ENV pollution issues
+
+You may need to set or reset BUNDLE_GEMFILE, GEM_HOME, GEM_PATH and PATH
+environment variables in the before_exec hook as illustrated by
+http://gist.github.com/534668
+
 == Isolate
 
 === Running
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 8%]

* Re: Hello excellent friends
  @ 2010-08-31  6:17  7% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-08-31  6:17 UTC (permalink / raw)
  To: unicorn list

Curtis <curtis.schofield@gmail.com> wrote:
> I have read your tun in article and I have tried to make sysctl
> changes - the benchmarks are not very significant. I love how well the
> signals are laid out and how excellently unicorn responds to them - I
> am hoping to get back to mongrel like performance . We were using
> nginx to haproxy to 32 mongrels
> 
> No I have set up a unix domain socket with 2mb send and receive buffer
> and a backlog of 2048 - I didn't see a change with the send receive
> buffer tuning and I have yet to try a smaller backlog to see. If that
> helps. Any info?

Hi, I'm not sure what size of requests and responses you get, but 2mb
seems like a lot, especially for requests (unless you handle a lot of
big uploads).

Even with large requests/responses, huge buffers means more pressure on
the kernel allocator and you're also hurting CPU cache locality.  So
larger buffers can hurt performance as well as help, I'll make a note of
that in the documentation.

The backlog shouldn't change performance much.  A larger one can let you
withstand short traffic bursts and increase reliability while
benchmarking.

> I am tuning for osx in dev and centos5 in production. Thank you for
> your great work cleaning mongrel into a first class unix friend.

You're welcome!

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* [ANN] 1.9 users: socket_dontwait - MSG_DONTWAIT socket methods
@ 2010-08-09 22:54  4% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-08-09 22:54 UTC (permalink / raw)
  To: mongrel-unicorn

Hi all,

I initially announced[1] this on the Rainbows! mailing list since
Rainbows! is more experimental in nature, but I've been running this for
a few days with real traffic (with Rainbows!) and it seems safe enough
for less crazy people to use :)

If you're using Ruby 1.9.1, then this library includes a fix for
errno getting zeroed and hitting rb_bug() during rb_sys_fail()
This is fixed in Ruby trunk r27401, but 1.9.1 doesn't have this.

This library is a drop-in replacement that reimplements several IO
methods with replacements using MSG_DONTWAIT for BasicSocket.  This
allows us to avoid unnecessary system calls and GVL bouncing.

[1] - http://mid.gmane.org/20100803091847.GC3255@dcvr.yhbt.net

The rest of the README below:

We've reimplemented the +readpartial+, +read_nonblock+,
+write_nonblock+, +read+ and +write+ instance methods normally inherited
from the IO class directly into BasicSocket with socket-specific system
calls and flags.

This library is only intended for Ruby 1.9 and will not build with other
versions of Ruby.  This only supports operating systems with the
non-POSIX MSG_DONTWAIT flag for send(2) and recv(2) syscalls.

This library is considered EXPERIMENTAL.  If successful, we'll see about
getting them integrated into the standard Ruby socket library.

== Features

* Avoid use of fcntl(2) to set O_NONBLOCK in favor of MSG_DONTWAIT when
  using non-blocking I/O.  We _unset_ O_NONBLOCK if we need to block
  and release the GVL instead of relying on select(2).

* Avoids select(2) entirely in favor of blocking I/O when the
  GVL is released.  This allows using file descriptor numbers higher
  than 1023 without overflowing select(2) buffers.

* BasicSocket#read uses recv(2) with MSG_WAITALL to avoid extra system
  calls for larger reads.

* Thread and signal-safe, releases the GVL for all blocking operations
  and retries if system calls are interrupted.

* Includes a 1.9.1-specific workaround to preserve errno after reacquiring
  the GVL.  This is
  {fixed}[http://redmine.ruby-lang.org/repositories/diff/ruby-19?rev=27401]
  in newer versions of Ruby.

* Falls back to line-buffered IO if needed (not recommended).

== Bugs/Caveats

* We ignore taint/$SAFE checks, we'll support it if there's demand,
  but we doubt there is...

* Does not support 1.9 encoding filters.  1.9 defaults all sockets to
  Encoding::BINARY anyways, so this should not be noticeable to code
  that leaves socket encodings untouched.

* Does not support write buffering in userspace.  Ruby defaults all
  sockets to "IO#sync = true", anyways so this does not affect code
  that leaves the default setting untouched.

* Avoid using line-buffered IO on sockets (IO#gets, IO#each_line),
  nearly all of the features of this library are cancelled out when
  the line-buffering fallback is used.

== Install

If you're using a packaged Ruby distribution, make sure you have a C
compiler and the matching Ruby development libraries and headers.
You need Ruby 1.9 to install socket_dontwait.  Previous versions of
Ruby will NOT be supported.

If you use RubyGems:

    gem install socket_dontwait

Otherwise grab the latest tarball from:

http://bogomips.org/socket_dontwait/files/

Unpack it, and run "ruby setup.rb"

== Development

You can get the latest source via git from the following locations:

  git://git.bogomips.org/socket_dontwait.git
  git://repo.or.cz/socket_dontwait.git (mirror)

You may browse the code from the web and download the latest snapshot
tarballs here:

* http://git.bogomips.org/cgit/socket_dontwait.git (cgit)
* http://repo.or.cz/w/socket_dontwait.git (gitweb)

Inline patches (from "git format-patch") to the mailing list are
preferred because they allow code review and comments in the reply to
the patch.

We will adhere to mostly the same conventions for patch submissions as
git itself.  See the Documentation/SubmittingPatches document
distributed with git on on patch submission guidelines to follow.  Just
don't email the git mailing list or maintainer with socket_dontwait
patches.

== Contact/Bug Reports/Feedback/Patches/Pull-Requests

This was originally created for the Rainbows! project (but may be used by
others), so we'll reuse their mailing list at
{rainbows-talk@rubyforge.org}[mailto:rainbows-talk@rubyforge.org].

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 4%]

* Re: SIGWINCH
  @ 2010-07-13  8:24  7% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-07-13  8:24 UTC (permalink / raw)
  To: unicorn list

Lawrence Pit <lawrence.pit@gmail.com> wrote:
> Hi,
>
> I followed the procedure to replace a running unicorn. Works fine,  
> except for one thing: after I decide to back out, ie I send a HUP to the  
> old master followed by a QUIT to the new master, then:

Ah, ok.  I can reproduce it.  The problem is the HUP by the old
master tries to reset the pid file to the non-"oldbin" version
which the new master is still holding on to.

You could QUIT the new master first and then HUP, but this is _far_ from
ideal because it leaves you with a window without running workers (and
also it contradicts our documentation).  It's also difficult to avoid
race conditions this way.

I'm looking for a better way to go about this, pid files are nasty :x

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* Re: Setting app name for process list
  2010-07-09  5:09  0%     ` Paul Dlug
@ 2010-07-09  5:44  0%       ` Jeremy Evans
  0 siblings, 0 replies; 200+ results
From: Jeremy Evans @ 2010-07-09  5:44 UTC (permalink / raw)
  To: unicorn list

On Thu, Jul 8, 2010 at 10:09 PM, Paul Dlug <paul.dlug@gmail.com> wrote:
> On Thu, Jul 8, 2010 at 5:42 PM, Eric Wong <normalperson@yhbt.net> wrote:
>> Devin Ben-Hur <dbenhur@whitepages.com> wrote:
>>> On 7/8/10 1:55 PM, Paul Dlug wrote:
>>>> Is there a way to set an application name for unicorn processes?
>>>> Basically an arbitrary name which would then show up in the process
>>>> list to identify unicorn processes, like what thin does with --tag.
>>>
>>> A patch to do something like that was recently rejected. Instead the
>>> documentation was updated with Eric's recommendated solution to instance
>>> identification:
>>> http://rubyforge.org/pipermail/mongrel-unicorn/2010-July/000620.html
>>>
>>> +    Using an absolute path for for CONFIG_FILE is recommended as it
>>> +    makes multiple instances of Unicorn easily distinguishable when
>>> +    viewing ps(1) output.
>>
>> Lawrence Pit also recommends running each app as a separate user,
>> which is also a great idea (IMHO, though some ops people I know
>> dislike this):
>>
>>   http://mid.gmane.org/4C32926D.5080400@gmail.com
>
> I think both of these solutions are undesirable, relying on the config
> file path is not ideal and running with different users is practical
> in my environment. Both these point out the need for some feature to
> distinguish running applications, I think adding a configurable
> application name/tag would be very useful, not sure how much work it
> would be but I can look at adding a patch if there is interest.

The patch was already submitted and rejected.  If you want this
feature, you can implement it yourself in the config file with the
following code:

class Unicorn::HttpServer
  def proc_name(tag)
    $0 = ([ File.basename(START_CTX[0]), "application name/tag",
            tag ]).concat(START_CTX[:argv]).join(' ')
  end
end

Jeremy
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: Setting app name for process list
  2010-07-08 21:42  0%   ` Eric Wong
@ 2010-07-09  5:09  0%     ` Paul Dlug
  2010-07-09  5:44  0%       ` Jeremy Evans
  0 siblings, 1 reply; 200+ results
From: Paul Dlug @ 2010-07-09  5:09 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

On Thu, Jul 8, 2010 at 5:42 PM, Eric Wong <normalperson@yhbt.net> wrote:
> Devin Ben-Hur <dbenhur@whitepages.com> wrote:
>> On 7/8/10 1:55 PM, Paul Dlug wrote:
>>> Is there a way to set an application name for unicorn processes?
>>> Basically an arbitrary name which would then show up in the process
>>> list to identify unicorn processes, like what thin does with --tag.
>>
>> A patch to do something like that was recently rejected. Instead the
>> documentation was updated with Eric's recommendated solution to instance
>> identification:
>> http://rubyforge.org/pipermail/mongrel-unicorn/2010-July/000620.html
>>
>> +    Using an absolute path for for CONFIG_FILE is recommended as it
>> +    makes multiple instances of Unicorn easily distinguishable when
>> +    viewing ps(1) output.
>
> Lawrence Pit also recommends running each app as a separate user,
> which is also a great idea (IMHO, though some ops people I know
> dislike this):
>
>   http://mid.gmane.org/4C32926D.5080400@gmail.com

I think both of these solutions are undesirable, relying on the config
file path is not ideal and running with different users is practical
in my environment. Both these point out the need for some feature to
distinguish running applications, I think adding a configurable
application name/tag would be very useful, not sure how much work it
would be but I can look at adding a patch if there is interest.


--Paul
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: Setting app name for process list
  2010-07-08 21:22  7% ` Devin Ben-Hur
@ 2010-07-08 21:42  0%   ` Eric Wong
  2010-07-09  5:09  0%     ` Paul Dlug
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2010-07-08 21:42 UTC (permalink / raw)
  To: unicorn list; +Cc: Paul Dlug

Devin Ben-Hur <dbenhur@whitepages.com> wrote:
> On 7/8/10 1:55 PM, Paul Dlug wrote:
>> Is there a way to set an application name for unicorn processes?
>> Basically an arbitrary name which would then show up in the process
>> list to identify unicorn processes, like what thin does with --tag.
>
> A patch to do something like that was recently rejected. Instead the  
> documentation was updated with Eric's recommendated solution to instance  
> identification:
> http://rubyforge.org/pipermail/mongrel-unicorn/2010-July/000620.html
>
> +    Using an absolute path for for CONFIG_FILE is recommended as it
> +    makes multiple instances of Unicorn easily distinguishable when
> +    viewing ps(1) output.

Lawrence Pit also recommends running each app as a separate user,
which is also a great idea (IMHO, though some ops people I know
dislike this):

   http://mid.gmane.org/4C32926D.5080400@gmail.com

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: Setting app name for process list
  @ 2010-07-08 21:22  7% ` Devin Ben-Hur
  2010-07-08 21:42  0%   ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Devin Ben-Hur @ 2010-07-08 21:22 UTC (permalink / raw)
  To: unicorn list, Paul Dlug

On 7/8/10 1:55 PM, Paul Dlug wrote:
> Is there a way to set an application name for unicorn processes?
> Basically an arbitrary name which would then show up in the process
> list to identify unicorn processes, like what thin does with --tag.

A patch to do something like that was recently rejected. Instead the 
documentation was updated with Eric's recommendated solution to instance 
identification:
http://rubyforge.org/pipermail/mongrel-unicorn/2010-July/000620.html

+    Using an absolute path for for CONFIG_FILE is recommended as it
+    makes multiple instances of Unicorn easily distinguishable when
+    viewing ps(1) output.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 1.1.0 - small changes and cleanups
@ 2010-07-08  8:04  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-07-08  8:04 UTC (permalink / raw)
  To: unicorn list

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

Changes:

This is a small, incremental feature release with some internal
changes to better support upcoming versions of the Rainbows! and
Zbatery web servers.  There is no need to upgrade if you're
happy with 1.0.0, but also little danger in upgrading.

There is one pedantic bugfix which shouldn't affect anyone
and small documentation updates as well.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 6%]

* Re: [PATCH] Show the current working directory in the proc title
  2010-07-05 23:34 25%     ` Eric Wong
@ 2010-07-06  2:18  0%       ` Lawrence Pit
  0 siblings, 0 replies; 200+ results
From: Lawrence Pit @ 2010-07-06  2:18 UTC (permalink / raw)
  To: unicorn list


The +after_fork+ doc mentions "generally there's no reason to start 
Unicorn as a priviledged user".

"generally" that may be true, I'd still recommend to run each app as a 
dedicated user.

The added bonus is that it makes it most obvious in ps(1) listings which 
app a unicorn process belongs to as 'user' is usually mentioned first. 
On small terminals the value of --config-file could easily be cut off at 
the right, still leaving you in the dark.



Lawrence

> Jeremy Evans <jeremyevans0@gmail.com> wrote:
>   
>> I see in the NEWS entry for 0.95.1 that you do recommend an absolute
>> path for the -c/--config-file option, but it may be beneficial to
>> mention this in the man page or other parts of the documentation.
>>     
>
> Agreed, thanks Jeremy!
>
> >From d7695c25c5e3b1c90e63bf15a5c5fdf68bfd0c34 Mon Sep 17 00:00:00 2001
> From: Eric Wong <normalperson@yhbt.net>
> Date: Mon, 5 Jul 2010 23:14:40 +0000
> Subject: [PATCH] doc: recommend absolute paths for -c/--config-file
>
> Suggested-by: Jeremy Evans
> ref: http://mid.gmane.org/AANLkTintT4vHGEdueuG45_RwJqFCToHi5pm2-WKDSUMz@mail.gmail.com
> ---
>  Documentation/unicorn.1.txt       |    3 +++
>  Documentation/unicorn_rails.1.txt |    7 +++++--
>  2 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
> index 24df7ab..c20a570 100644
> --- a/Documentation/unicorn.1.txt
> +++ b/Documentation/unicorn.1.txt
> @@ -36,6 +36,9 @@ with rackup(1) but strongly discouraged.
>      implemented as a Ruby DSL, so Ruby code may executed.
>      See the RDoc/ri for the *Unicorn::Configurator* class for the full
>      list of directives available from the DSL.
> +    Using an absolute path for for CONFIG_FILE is recommended as it
> +    makes multiple instances of Unicorn easily distinguishable when
> +    viewing ps(1) output.
>  
>  -D, \--daemonize
>  :   Run daemonized in the background.  The process is detached from
> diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt
> index 267e425..f426b07 100644
> --- a/Documentation/unicorn_rails.1.txt
> +++ b/Documentation/unicorn_rails.1.txt
> @@ -34,8 +34,11 @@ as much as possible.
>  -c, \--config-file CONFIG_FILE
>  :   Path to the Unicorn-specific config file.  The config file is
>      implemented as a Ruby DSL, so Ruby code may executed.
> -    See the RDoc/ri for the *Unicorn::Configurator* class for the
> -    full list of directives available from the DSL.
> +    See the RDoc/ri for the *Unicorn::Configurator* class for the full
> +    list of directives available from the DSL.
> +    Using an absolute path for for CONFIG_FILE is recommended as it
> +    makes multiple instances of Unicorn easily distinguishable when
> +    viewing ps(1) output.
>  
>  -D, \--daemonize
>  :   Run daemonized in the background.  The process is detached from
>   

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] Show the current working directory in the proc title
  2010-07-02 22:50  6%   ` Jeremy Evans
@ 2010-07-05 23:34 25%     ` Eric Wong
  2010-07-06  2:18  0%       ` Lawrence Pit
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2010-07-05 23:34 UTC (permalink / raw)
  To: unicorn list

Jeremy Evans <jeremyevans0@gmail.com> wrote:
> I see in the NEWS entry for 0.95.1 that you do recommend an absolute
> path for the -c/--config-file option, but it may be beneficial to
> mention this in the man page or other parts of the documentation.

Agreed, thanks Jeremy!

>From d7695c25c5e3b1c90e63bf15a5c5fdf68bfd0c34 Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Mon, 5 Jul 2010 23:14:40 +0000
Subject: [PATCH] doc: recommend absolute paths for -c/--config-file

Suggested-by: Jeremy Evans
ref: http://mid.gmane.org/AANLkTintT4vHGEdueuG45_RwJqFCToHi5pm2-WKDSUMz@mail.gmail.com
---
 Documentation/unicorn.1.txt       |    3 +++
 Documentation/unicorn_rails.1.txt |    7 +++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt
index 24df7ab..c20a570 100644
--- a/Documentation/unicorn.1.txt
+++ b/Documentation/unicorn.1.txt
@@ -36,6 +36,9 @@ with rackup(1) but strongly discouraged.
     implemented as a Ruby DSL, so Ruby code may executed.
     See the RDoc/ri for the *Unicorn::Configurator* class for the full
     list of directives available from the DSL.
+    Using an absolute path for for CONFIG_FILE is recommended as it
+    makes multiple instances of Unicorn easily distinguishable when
+    viewing ps(1) output.
 
 -D, \--daemonize
 :   Run daemonized in the background.  The process is detached from
diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt
index 267e425..f426b07 100644
--- a/Documentation/unicorn_rails.1.txt
+++ b/Documentation/unicorn_rails.1.txt
@@ -34,8 +34,11 @@ as much as possible.
 -c, \--config-file CONFIG_FILE
 :   Path to the Unicorn-specific config file.  The config file is
     implemented as a Ruby DSL, so Ruby code may executed.
-    See the RDoc/ri for the *Unicorn::Configurator* class for the
-    full list of directives available from the DSL.
+    See the RDoc/ri for the *Unicorn::Configurator* class for the full
+    list of directives available from the DSL.
+    Using an absolute path for for CONFIG_FILE is recommended as it
+    makes multiple instances of Unicorn easily distinguishable when
+    viewing ps(1) output.
 
 -D, \--daemonize
 :   Run daemonized in the background.  The process is detached from
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 25%]

* Re: [PATCH] Show the current working directory in the proc title
  @ 2010-07-02 22:50  6%   ` Jeremy Evans
  2010-07-05 23:34 25%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Jeremy Evans @ 2010-07-02 22:50 UTC (permalink / raw)
  To: unicorn list

On Fri, Jul 2, 2010 at 3:29 PM, Eric Wong <normalperson@yhbt.net> wrote:
> Jeremy Evans <code@jeremyevans.net> wrote:
>> This is helpful if you run a server with many web apps in separate
>> directories all running unicorn, as it allows you to easily see
>> which processes are tied to which app.
>
> Hi Jeremy,
>
> I recommend using absolute paths with -c/--config-file and allowing
> users to opt-in to it (everybody should be using a Unicorn config
> file in production).
>
> Having an extra working directory path in there hurts people on smaller
> terminals[1].  With -c, users have more control of what their
> command-line looks like without having something forced on them.
>
> I can't see myself accepting this patch right now for the above reasons.
> On the other hand, I don't see any reason to alter the way proc_name is
> used in the future, so monkey patching here is fine.
>
> I'm sure there'll always be folks that will want something different in
> $0 (as evidenced by Rack::Contrib::ProcTitle and like).
>
>
> [1] - I try to be considerate of on-call folks working from mobile
>      phones or netbooks and/or bad net connections.  There's even
>      a test in test_exec.rb to ensure the help output text can fit
>      in standard 80x24 ANSI terminals.  Personally, I refuse to use
>      a terminals wider than 80 columns (actually, I would've
>      preferred the world standardized on a 64-column wrap)

Fair enough, I realize the patch wasn't for everyone.  I usually
change to the directory first and call unicorn with a relative path,
but that's probably just a bad habit.  It's fairly easy to monkey
patch it in the configuration file if you need it:

class Unicorn::HttpServer
  def proc_name(tag)
    $0 = ([ File.basename(START_CTX[0]), File.basename(START_CTX[:cwd]),
            tag ]).concat(START_CTX[:argv]).join(' ')
  end
end

I see in the NEWS entry for 0.95.1 that you do recommend an absolute
path for the -c/--config-file option, but it may be beneficial to
mention this in the man page or other parts of the documentation.

Thanks,
Jeremy
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 6%]

* anything left before 1.0?
@ 2010-06-16  0:09  8% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-06-16  0:09 UTC (permalink / raw)
  To: mongrel-unicorn

Hi all,

Since some folks have been running Unicorn in production for a while,
we might as well call the next release 1.0.

I have a couple of minor fixes in unicorn.git on top of 0.991.0.

Mainly, there are small compatibility fixes for the future (MRI 1.9.2
and Rubinius) and the past (MRI 1.8.6(!)).

There are also some documentation updates for Rack 1.2, but we should be
compatible with everything from Rack 0.9 (possibly earlier) to the
latest Rack 1.2.

Shortlog since 0.991.0:

Eric Wong (8):
      doc: cleanup rdoc escaping in title, hopefully
      cleanup: use modules were applicable
      t0005: Ruby 1.9.2 $LOAD_PATH fix
      http: fix rb_str_set_len() define for 1.8.6
      app/exec_cgi: rack.input may not respond to #size
      local.mk.sample: add 1.8.6-p114 to "full-test"
      tee_input: update documentation for Rack 1.2
      FAQ: help folks help themselves for processes dying in a loop

Let us know if there's anything else missing, pipe up within the next 24
hours or so...

You can always email me privately if you don't want your address on the
public mailing list.  Don't send HTML mail, though.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 8%]

* Re: [ANN] unicorn 0.990.0 - inching towards 1.0
  2010-06-11  1:27  0%           ` Eric Wong
@ 2010-06-11 18:00  0%             ` Alexander Simonov
  0 siblings, 0 replies; 200+ results
From: Alexander Simonov @ 2010-06-11 18:00 UTC (permalink / raw)
  To: unicorn list



On Jun 11, 2010, at 4:27 AM, Eric Wong wrote:

> Alexander Simonov <alex@simonov.me> wrote:
>> On Jun 10, 2010, at 10:38 AM, Eric Wong wrote:
>>> And again (I seem to remember saying this months ago), any time you're
>>> deploying, you should be paying extra attention to the app anyways.
>>> That means testing with actual HTTP requests, not just seeing of the
>>> process is up.  Just having a running process serving error pages is
>>> equally worthless as not running the server at all.
>> 
>> Hm.. It's makes sense.
>> But much better if it will be writing in the documentation for the future.
> 
> Here's what I've pushed out, let me know if everything makes
> sense.  I think I'll release 0.991.0 in a little bit.

Ok! Thank you!
Good. After release I will update golden_brindle too :)


> 
>> From f9baab18705218dae4c37c2c92d1ceea151bba8e Mon Sep 17 00:00:00 2001
> From: Eric Wong <normalperson@yhbt.net>
> Date: Thu, 10 Jun 2010 17:57:08 -0700
> Subject: [PATCH] docs: hopefully clarify preload_app=false behavior
> 
> While we're at it, inform people of why they might use
> a symlink

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* [ANN] unicorn 0.991.0 - startup improvements
@ 2010-06-11  2:31  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-06-11  2:31 UTC (permalink / raw)
  To: ruby-talk ML, mongrel-unicorn

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

Changes:

The "working_directory" configuration parameter is now handled
before config.ru.  That means "unicorn" and "unicorn_rails" no
longer barfs when initially started outside of the configured
"working_directory" where a config.ru is required.  A huge
thanks to Pierre Baillet for catching this ugly UI inconsistency
before the big 1.0 release

Thanks to Hongli Lai, out-of-the-box Rails 3 (beta) support
should be improved for deployments lacking a config.ru

There are more new integration tests, cleanups and some
documentation improvements.

-- 
Eric Wong



^ permalink raw reply	[relevance 6%]

* Re: [ANN] unicorn 0.990.0 - inching towards 1.0
  2010-06-10  8:46  7%         ` Alexander Simonov
@ 2010-06-11  1:27  0%           ` Eric Wong
  2010-06-11 18:00  0%             ` Alexander Simonov
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2010-06-11  1:27 UTC (permalink / raw)
  To: unicorn list

Alexander Simonov <alex@simonov.me> wrote:
> On Jun 10, 2010, at 10:38 AM, Eric Wong wrote:
> > And again (I seem to remember saying this months ago), any time you're
> > deploying, you should be paying extra attention to the app anyways.
> > That means testing with actual HTTP requests, not just seeing of the
> > process is up.  Just having a running process serving error pages is
> > equally worthless as not running the server at all.
> 
> Hm.. It's makes sense.
> But much better if it will be writing in the documentation for the future.

Here's what I've pushed out, let me know if everything makes
sense.  I think I'll release 0.991.0 in a little bit.

>From f9baab18705218dae4c37c2c92d1ceea151bba8e Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Thu, 10 Jun 2010 17:57:08 -0700
Subject: [PATCH] docs: hopefully clarify preload_app=false behavior

While we're at it, inform people of why they might use
a symlink
---
 SIGNALS                     |    7 ++++++-
 lib/unicorn/configurator.rb |   21 ++++++++++++++++++---
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/SIGNALS b/SIGNALS
index be96892..8851775 100644
--- a/SIGNALS
+++ b/SIGNALS
@@ -14,7 +14,12 @@ Unicorn and nginx.
   will also pick up any application code changes when restarted.  If
   "preload_app" is true, then application code changes will have no
   effect; USR2 + QUIT (see below) must be used to load newer code in
-  this case.
+  this case.  When reloading the application, +Gem.refresh+ will
+  be called so updated code for your application can pick up newly
+  installed RubyGems.  It is not recommended that you uninstall
+  libraries your application depends on while Unicorn is running,
+  as respawned workers may enter a spawn loop when they fail to
+  load an uninstalled dependency.
 
 * INT/TERM - quick shutdown, kills all workers immediately
 
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 71c7a8a..533e0ed 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -311,7 +311,22 @@ module Unicorn
     #
     # In addition to reloading the unicorn-specific config settings,
     # SIGHUP will reload application code in the working
-    # directory/symlink when workers are gracefully restarted.
+    # directory/symlink when workers are gracefully restarted when
+    # preload_app=false (the default).  As reloading the application
+    # sometimes requires RubyGems updates, +Gem.refresh+ is always
+    # called before the application is loaded (for RubyGems users).
+    #
+    # During deployments, care should _always_ be taken to ensure your
+    # applications are properly deployed and running.  Using
+    # preload_app=false (the default) means you _must_ check if
+    # your application is responding properly after a deployment.
+    # Improperly deployed applications can go into a spawn loop
+    # if the application fails to load.  While your children are
+    # in a spawn loop, it is is possible to fix an application
+    # by properly deploying all required code and dependencies.
+    # Using preload_app=true means any application load error will
+    # cause the master process to exit with an error.
+
     def preload_app(bool)
       case bool
       when TrueClass, FalseClass
@@ -344,9 +359,9 @@ module Unicorn
       set_path(:stdout_path, path)
     end
 
-    # sets the working directory for Unicorn.  This ensures USR2 will
+    # sets the working directory for Unicorn.  This ensures SIGUSR2 will
     # start a new instance of Unicorn in this directory.  This may be
-    # a symlink.
+    # a symlink, a common scenario for Capistrano users.
     def working_directory(path)
       # just let chdir raise errors
       path = File.expand_path(path)
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 0%]

* Re: [ANN] unicorn 0.990.0 - inching towards 1.0
  @ 2010-06-10  8:46  7%         ` Alexander Simonov
  2010-06-11  1:27  0%           ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Alexander Simonov @ 2010-06-10  8:46 UTC (permalink / raw)
  To: unicorn list


On Jun 10, 2010, at 10:38 AM, Eric Wong wrote:

> It'd have to be a time-aware counter, because sometimes slightly broken
> _will_ exit/die 10 times over the period of an hour.  But the site can
> still be making enough money with 99.8% successful service and not
> care about spending time/resources fixing the last 0.2% :)
> 
> But even with a proper time-aware counter, the app is still broken at
> deploy time.  So I don't believe there is much point in adding more code
> just to exit the process when the proper solution is for the user to
> _fix_ the app.
> 
> And again (I seem to remember saying this months ago), any time you're
> deploying, you should be paying extra attention to the app anyways.
> That means testing with actual HTTP requests, not just seeing of the
> process is up.  Just having a running process serving error pages is
> equally worthless as not running the server at all.

Hm.. It's makes sense.
But much better if it will be writing in the documentation for the future.

Thank you!

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* [PATCH] doc: emphasize the importance of stderr_path
  2010-06-04 20:06  7% ` Eric Wong
@ 2010-06-04 20:47 15%   ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-06-04 20:47 UTC (permalink / raw)
  To: unicorn list

Eric Wong <normalperson@yhbt.net> wrote:
> I shall emphasize the importance of stderr_path if you're using the
> default logger configuration in the documentation.

I've just pushed the following out to unicorn.git and website.

Comments/grammar/speling korections welcome as always.

>From 2d5a4b075801493a85c6e8d2dbdf0c95002e046d Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Fri, 4 Jun 2010 13:42:34 -0700
Subject: [PATCH] doc: emphasize the importance of stderr_path

While second nature to myself, stderr_path may be an
overlooked configuration parameter for some users.  Also,
add a minimal sample configuration file that is shorter
and hopefully less intimidating to new users.
---
 examples/unicorn.conf.minimal.rb |   13 +++++++++++++
 examples/unicorn.conf.rb         |   12 +++++++++---
 lib/unicorn/configurator.rb      |   22 ++++++++++++++++++----
 3 files changed, 40 insertions(+), 7 deletions(-)
 create mode 100644 examples/unicorn.conf.minimal.rb

diff --git a/examples/unicorn.conf.minimal.rb b/examples/unicorn.conf.minimal.rb
new file mode 100644
index 0000000..2a47910
--- /dev/null
+++ b/examples/unicorn.conf.minimal.rb
@@ -0,0 +1,13 @@
+# Minimal sample configuration file for Unicorn (not Rack) when used
+# with daemonization (unicorn -D) started in your working directory.
+#
+# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
+# documentation.
+# See also http://unicorn.bogomips.org/examples/unicorn.conf.rb for
+# a more verbose configuration using more features.
+
+listen 2007 # by default Unicorn listens on port 8080
+worker_processes 2 # this should be >= nr_cpus
+pid "/path/to/app/shared/pids/unicorn.pid"
+stderr_path "/path/to/app/shared/log/unicorn.log"
+stdout_path "/path/to/app/shared/log/unicorn.log"
diff --git a/examples/unicorn.conf.rb b/examples/unicorn.conf.rb
index e209894..37c3e81 100644
--- a/examples/unicorn.conf.rb
+++ b/examples/unicorn.conf.rb
@@ -1,4 +1,9 @@
-# Sample configuration file for Unicorn (not Rack)
+# Sample verbose configuration file for Unicorn (not Rack)
+#
+# This configuration file documents many features of Unicorn
+# that may not be needed for some applications. See
+# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
+# for a much simpler configuration file.
 #
 # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
 # documentation.
@@ -22,8 +27,9 @@ timeout 30
 # feel free to point this anywhere accessible on the filesystem
 pid "/path/to/app/shared/pids/unicorn.pid"
 
-# some applications/frameworks log to stderr or stdout, so prevent
-# them from going to /dev/null when daemonized here:
+# By default, the Unicorn logger will write to stderr.
+# Additionally, ome applications/frameworks log to stderr or stdout,
+# so prevent them from going to /dev/null when daemonized here:
 stderr_path "/path/to/app/shared/log/unicorn.stderr.log"
 stdout_path "/path/to/app/shared/log/unicorn.stdout.log"
 
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 64a25e3..4fa745d 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -7,9 +7,11 @@ module Unicorn
 
   # Implements a simple DSL for configuring a Unicorn server.
   #
-  # See http://unicorn.bogomips.org/examples/unicorn.conf.rb for an
-  # example config file.  An example config file for use with nginx is
-  # also available at http://unicorn.bogomips.org/examples/nginx.conf
+  # See http://unicorn.bogomips.org/examples/unicorn.conf.rb and
+  # http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
+  # example configuration files.  An example config file for use with
+  # nginx is also available at
+  # http://unicorn.bogomips.org/examples/nginx.conf
   class Configurator < Struct.new(:set, :config_file, :after_reload)
 
     # Default settings for Unicorn
@@ -78,6 +80,10 @@ module Unicorn
     # sets object to the +new+ Logger-like object.  The new logger-like
     # object must respond to the following methods:
     #  +debug+, +info+, +warn+, +error+, +fatal+, +close+
+    # The default Logger will log its output to the path specified
+    # by +stderr_path+.  If you're running Unicorn daemonized, then
+    # you must specify a path to prevent error messages from going
+    # to /dev/null.
     def logger(new)
       %w(debug info warn error fatal close).each do |m|
         new.respond_to?(m) and next
@@ -310,11 +316,19 @@ module Unicorn
     # file will be opened with the File::APPEND flag and writes
     # synchronized to the kernel (but not necessarily to _disk_) so
     # multiple processes can safely append to it.
+    #
+    # If you are daemonizing and using the default +logger+, it is important
+    # to specify this as errors will otherwise be lost to /dev/null.
+    # Some applications/libraries may also triggering warnings that go to
+    # stderr, and they will end up here.
     def stderr_path(path)
       set_path(:stderr_path, path)
     end
 
-    # Same as stderr_path, except for $stdout
+    # Same as stderr_path, except for $stdout.  Not many Rack applications
+    # write to $stdout, but any that do will have their output written here.
+    # It is safe to point this to the same location a stderr_path.
+    # Like stderr_path, this defaults to /dev/null when daemonized.
     def stdout_path(path)
       set_path(:stdout_path, path)
     end
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 15%]

* Re: Logging errors from Unicorn
  @ 2010-06-04 20:06  7% ` Eric Wong
  2010-06-04 20:47 15%   ` [PATCH] doc: emphasize the importance of stderr_path Eric Wong
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2010-06-04 20:06 UTC (permalink / raw)
  To: unicorn list

Peter Kieltyka <peter.kieltyka@nulayer.com> wrote:
> Hey guys,
> 
> I'm running a Rails 3 beta3 application using Ruby 1.9.2-preview3 and
> it has been running fairly well, however every now and then (usually
> when under high load), I see error messages like:
> 
> 2010/06/04 14:34:29 [error] 1884#0: *8844 upstream prematurely closed
> connection while reading response header from upstream, client:
> 119.235.237.93, server: portal.crowdreel.com, request: "GET
> /post/18Vmy HTTP/1.1", upstream:
> "http://unix:/home/app/crowdreel-portal/tmp/sockets/unicorn.sock:/post/18Vmy",
> host: "crowdreel.com"
> 
> ... a lot of these messages.. this is a pretty heavy duty server with
> lots of ram.
> 
> I have a setup similar to what I read up on github's blog as in: nginx
> -> unicorns via a socket upstream.
> 
> My unicorn.rb file looks like:
> 
> --------
> 
> # 16 workers and 1 master
> worker_processes 16
> 
> # Load the app into the master before forking workers for super-fast worker spawn times
> preload_app false
> 
> # Restart any workers that haven't responded in 30 seconds
> timeout 45
> 
> # Listen on a Unix data socket
> listen File.expand_path(File.dirname(__FILE__)+'/../tmp/sockets/unicorn.sock'), :backlog => 2048
> 
> ----------

> I don't preload the app because I start running into annoying issues
> where my workers use the same db connection, so instead I just have
> them load their own instance, its very fast to start up anyways.
> 
> I've read everything I could on this issue and exhausted Google, which
> leaves me to think the only thing left is some incompatibilities with
> 1.9.2. So I was wondering, how can I get logs from unicorn's
> workers/master to know what is happening to these workers, perhaps
> something is segfaulting?

Hi Peter,

Set stderr_path in your unicorn config file so Unicorn can log
its errors to a file.  Otherwise Unicorn will send all errors to
/dev/null when daemonized.

I shall emphasize the importance of stderr_path if you're using the
default logger configuration in the documentation.

Any chance the "/post/18Vmy" request is hitting your timeout?  The only
way you can know is if Unicorn logged its errors.  You might also want
to check your Rails log for exceptions, too, as some uncaught errors
may show up there.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 0.98.0 - Rack HTTP server for fast clients and Unix
@ 2010-05-05  1:09  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-05-05  1:09 UTC (permalink / raw)
  To: mongrel-unicorn

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

Changes:

Deployments that suspend or hibernate servers should no longer
have workers killed off (and restarted) upon resuming.

For Linux users of {raindrops}[http://raindrops.bogomips.org/]
(v0.2.0+) configuration is easier as raindrops can now
automatically detect the active listeners on the server
via the new Unicorn.listener_names singleton method.

For the pedantic, chunked request bodies without trailers are no
longer allowed to omit the final CRLF.  This shouldn't affect
any real and RFC-compliant clients out there.  Chunked requests
with trailers have always worked and continue to work the same
way.

The rest are mostly small internal cleanups and documentation
fixes.  See the commit logs for full details.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 6%]

* [ANN] raindrops - real-time stats for preforking Rack servers
@ 2010-04-09  2:37  4% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-04-09  2:37 UTC (permalink / raw)
  To: mongrel-unicorn

(I announced this yesterday on ruby-talk, but I realized it would
be wise to actually announce it on the list of a server it was
designed for :)

Raindrops is a real time stats package to show statistics for Rack HTTP
servers.  It is designed for preforking servers such as Rainbows! and
Unicorn, but should support any Rack HTTP server under Ruby 1.9, 1.8 and
possibly Rubinius (untested) on platforms supporting POSIX shared memory
and compiled with GCC (for atomic builtins).

Raindrops includes a Struct-like Raindrops::Struct class that may be used
standalone to create atomic counters shared across any number of forked
processes under SMP.

* http://raindrops.bogomips.org/
* raindrops@librelist.com
* git://git.bogomips.org/raindrops.git

== Features

* counters are shared across all forked children and lock-free

* counters are kept on separate cache lines to reduce contention under SMP

* may expose server statistics as a Rack Middleware endpoint
  (default: "/_raindrops")

* middleware displays the number of actively processing and writing
  clients from a single request regardless of which worker process
  it hits.

== Linux-only Extra Features!

* Middleware response includes extra stats for bound TCP and
  Unix domain sockets (configurable, it can include stats from
  other TCP or UNIX domain socket servers).

* TCP socket stats use efficient inet_diag facilities via netlink
  instead of parsing /proc/net/tcp to minimize overhead.
  This was fun to discover and write.

== Install

raindrops requires GCC 4.x (or compatible) or later to support the
atomic builtins (__sync_{add,sub}_and_fetch()).  Atomic operations on
other compilers may be supported if there is demand.

If you're using a packaged Ruby distribution, make sure you have a C
compiler and the matching Ruby development libraries and headers.

If you use RubyGems:

    gem install raindrops

Otherwise grab the latest tarball from:

http://raindrops.bogomips.org/files/

Unpack it, and run "ruby setup.rb"

== Usage (Rainbows!/Unicorn preload_app=false)

If you're using preload_app=false (the default) in your Rainbows!/Unicorn
config file, you'll need to create the global Stats object before
forking.

        require 'raindrops'
        $stats ||= Raindrops::Middleware::Stats.new

In your Rack config.ru:

        use Raindrops::Middleware, :stats => $stats

== Usage (Rainbows!/Unicorn preload_app=true)

If you're using preload_app=true in your Rainbows!/Unicorn
config file, just add the middleware to your stack:

In your Rack config.ru:

        use Raindrops::Middleware

== Usage (Linux-extras)

To get bound listener statistics under Linux, you need to specify the
listener names for your server.  You can even include listen sockets for
*other* servers on the same machine.  This can be handy for monitoring
your nginx proxy as well.

In your Rack config.ru, just pass the :listeners argument as an array of
strings (along with any other arguments).  You can specify any
combination of TCP or Unix domain socket names:

        use Raindrops::Middleware, :listeners => %w(0.0.0.0:80 /tmp/.sock)

See the tests/ and examples/ directory for more examples

== Development

You can get the latest source via git from the following locations:

  git://git.bogomips.org/raindrops.git
  git://repo.or.cz/raindrops.git (mirror)

You may browse the code from the web and download the latest snapshot
tarballs here:

* http://git.bogomips.org/cgit/raindrops.git (cgit)
* http://repo.or.cz/w/raindrops.git (gitweb)

Inline patches (from "git format-patch") to the mailing list are
preferred because they allow code review and comments in the reply to
the patch.

We will adhere to mostly the same conventions for patch submissions as
git itself.  See the Documentation/SubmittingPatches document
distributed with git on on patch submission guidelines to follow.  Just
don't email the git mailing list or maintainer with raindrops patches.

== Contact

All feedback (bug reports, user/development discussion, patches, pull
requests) go to the mailing list: mailto:raindrops@librelist.com

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 4%]

* Re: Unicorn 0.97.0 old master is never dying
  @ 2010-03-19  8:55  5%       ` ghazel
  0 siblings, 0 replies; 200+ results
From: ghazel @ 2010-03-19  8:55 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

>> Here is the entire config file: http://codepad.org/v6lUsuzD
>
> Ugh.  I can't even get to that file right now.  I actually prefer
> to have config files inline so:
>
> a) I can comment easily on them
> b) I don't have to be online when reading them
>   (I sync my mail to a local machine and lose connectivity often)

We're still working on that internet that works when you're not
online. In the meantime:


# Sample configuration file for Unicorn (not Rack)
#
# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
# documentation.

require '/data/myapp/current/config/unicorn_constants'

# Use at least one worker per core if you're on a dedicated server,
# more will usually help for _short_ waits on databases/caches.
worker_processes UnicornConstants::NUM_WORKERS

# Help ensure your application will always spawn in the symlinked
# "current" directory that Capistrano sets up.
working_directory "/data/myapp/current" # available in 0.94.0+

# listen on both a Unix domain socket and a TCP port,
# we use a shorter backlog for quicker failover when busy
listen "/tmp/unicorn.sock", :backlog => 64
listen 8080, :tcp_nopush => true, :tries => -1

# nuke workers after X seconds instead of (60 seconds default)
timeout 300

# feel free to point this anywhere accessible on the filesystem
pid "/data/myapp/shared/pids/unicorn.pid"

# some applications/frameworks log to stderr or stdout, so prevent
# them from going to /dev/null when daemonized here:
stderr_path "/data/myapp/shared/log/unicorn.stderr.log"
stdout_path "/data/myapp/shared/log/unicorn.stdout.log"

# combine REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true

before_fork do |server, worker|
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!

  # The following is only recommended for memory/DB-constrained
  # installations.  It is not needed if your system can house
  # twice as many worker_processes as you have configured.
  #
  # This allows a new master process to incrementally
  # phase out the old master process with SIGTTOU to avoid a
  # thundering herd (especially in the "preload_app false" case)
  # when doing a transparent upgrade.  The last worker spawned
  # will then kill off the old master process with a SIGQUIT.
  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

after_fork do |server, worker|
  # per-process listener ports for debugging/admin/migrations
  addr = "127.0.0.1:#{9000 + worker.nr}"
  server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)

  # the following is *required* for Rails + "preload_app true",
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection

  # if preload_app is true, then you may also want to check and
  # restart any other shared sockets/descriptors such as Memcached,
  # and Redis.  TokyoCabinet file handles are safe to reuse
  # between any number of forked children (assuming your kernel
  # correctly implements pread()/pwrite() system calls)
end



-Greg
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 5%]

* Re: Monit configuration
  @ 2010-03-08 22:12  7%   ` Florian Munz
  0 siblings, 0 replies; 200+ results
From: Florian Munz @ 2010-03-08 22:12 UTC (permalink / raw)
  To: mongrel-unicorn

Iñaki Baz Castillo <ibc@aliax.net> wrote:
> Why do you say that? I use monit to monitorize some forking servers and it
> takes into accoutn of the child processes. The "trick" is telling monit to
> inspect the master process pid (that present unde /var/lib/SERVER.pid).

Interesting. From the documentation I can't figure out how you can
monitor the children individually though.

I can test for the memory of the master process and I can test the
memory size of master plus all children. But want I want to do is
basically: Sent a QUIT to the child process if its memory size is
greater than 300MB.


- Florian

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 0.96.1 - leak fix for Rainbows!/Zbatery
@ 2010-02-13 10:34  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2010-02-13 10:34 UTC (permalink / raw)
  To: ruby-talk ML, mongrel-unicorn, rainbows-talk

First off, this memory leak doesn't affect Unicorn itself at all
(but it doesn't hurt, either).

Unicorn itself always allocates the HttpParser once and always reuses it
in every sequential request.

This leak only affects applications that repeatedly allocate a new HTTP
parser.  Thus this bug affects _all_ deployments of Rainbows! and
Zbatery.  These servers allocate a new parser for every client
connection to serve clients concurrently, but due to a bug in Unicorn,
never allows the Ruby GC to properly free the memory allocated.

Here's what happened:

  I misread the Data_Make_Struct()/Data_Wrap_Struct()
  documentation and ended up passing NULL as the "free" argument
  instead of -1, causing the memory to never be freed.

  From README.EXT in the MRI source which I misread:
  > The free argument is the function to free the pointer
  > allocation.  If this is -1, the pointer will be just freed.
  > The functions mark and free will be called from garbage
  > collector.

Yes, I suck at reading and can't write code properly as a result.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

-- 
Eric Wong



^ permalink raw reply	[relevance 6%]

* Re: Suggestion for reload action (USR2)
  2010-01-20 20:58  7%     ` Eric Wong
@ 2010-01-21 11:20  0%       ` Iñaki Baz Castillo
  0 siblings, 0 replies; 200+ results
From: Iñaki Baz Castillo @ 2010-01-21 11:20 UTC (permalink / raw)
  To: unicorn list

El Miércoles, 20 de Enero de 2010, Eric Wong escribió:
> Iñaki Baz Castillo <ibc@aliax.net> wrote:
> > El Miércoles, 20 de Enero de 2010, Eric Wong escribió:
> > > While the patch was not needed for this case, inline patches are
> > > strongly preferred here.  Inline patches are far easier to read,
> > > reply-to and apply than attachments.
> >
> > Sure but what about the fixed 80 columns of a mail?
> > Of course I can generate the mail without such constrain, but it doesn't
> > look very cool :)
> 
> For mail, the soft limit is actually closer/around to 72 columns because
> we take quoting into consideration.  But properly configured mailers
> shouldn't care nor enforce this (git-send-email(1) does not).
> 
> http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatch
> es has some good notes on various mailers (I usually use mutt to send
>  one-off patches and git send-email for a series).
> 

KMail
-----

This should help you to submit patches inline using KMail.

1) Prepare the patch as a text file.

2) Click on New Mail.

3) Go under "Options" in the Composer window and be sure that
"Word wrap" is not set.

4) Use Message -> Insert file... and insert the patch.

5) Back in the compose window: add whatever other text you wish to the
  514 message, complete the addressing and subject fields, and press send.


:)


-- 
Iñaki Baz Castillo <ibc@aliax.net>
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: Suggestion for reload action (USR2)
  @ 2010-01-20 20:58  7%     ` Eric Wong
  2010-01-21 11:20  0%       ` Iñaki Baz Castillo
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2010-01-20 20:58 UTC (permalink / raw)
  To: unicorn list

Iñaki Baz Castillo <ibc@aliax.net> wrote:
> El Miércoles, 20 de Enero de 2010, Eric Wong escribió:
> > While the patch was not needed for this case, inline patches are strongly
> > preferred here.  Inline patches are far easier to read, reply-to and
> > apply than attachments.
> 
> Sure but what about the fixed 80 columns of a mail?
> Of course I can generate the mail without such constrain, but it doesn't look 
> very cool :)

For mail, the soft limit is actually closer/around to 72 columns because
we take quoting into consideration.  But properly configured mailers
shouldn't care nor enforce this (git-send-email(1) does not).

http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatches
has some good notes on various mailers (I usually use mutt to send
one-off patches and git send-email for a series).

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* Re: Unicorn, Rails and Memcached
  2010-01-05 22:34  0% ` Eric Wong
@ 2010-01-05 22:47  0%   ` Stefan Maier
  0 siblings, 0 replies; 200+ results
From: Stefan Maier @ 2010-01-05 22:47 UTC (permalink / raw)
  To: unicorn list

Am 1/5/10 11:34 PM, schrieb Eric Wong:
> Stefan Maier <stefanmaier@gmail.com> wrote:
>> Hi,
>>
>> I am running unicorn with rails and memcached. The combination usually
>> works flawlessly but sometimes when I retrieve an item from memcached i
>> get a different, unrelated item.
>>
>> At the moment I'm more or less investigating in all directions and after
>> reading
>> http://www.modrails.com/documentation/Users%20guide.html#%5Fexample%5F1%5Fmemcached%5Fconnection%5Fsharing%5Fharmful
>> I thought that maybe the forking nature of unicorn has something to do
>> with it.
> 
> Hi Stefan,
> 
> If you're using "preload_app true" in your config file, then all the
> gotchas from Passenger with sharing memcached sockets across processes
> apply to Unicorn as well.
> 
>> So, are there any steps you have to take to ensure unicorn works with
>> memcached?
> 
> Which memcached library are you using?
> 
> I believe some memcached libraries will delay opening a socket until
> it's actually needed (inside the worker processes), but if you use
> memcached in your app initialization code, then the socket will be
> opened in the master process (which is bad).
> 
> So the safe thing would be to reconnect to your memcached servers in the
> after_fork hook.
> 


This is what i thought and lsof also confirms that the workers have
their own connections.
So it's not a unicorn problem,
At the moment it seems like memcached gets confused by a malformed key.

Thanks for the quick reply,

Stefan
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: Unicorn, Rails and Memcached
  2010-01-05 22:12  7% Unicorn, Rails and Memcached Stefan Maier
@ 2010-01-05 22:34  0% ` Eric Wong
  2010-01-05 22:47  0%   ` Stefan Maier
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2010-01-05 22:34 UTC (permalink / raw)
  To: unicorn list

Stefan Maier <stefanmaier@gmail.com> wrote:
> Hi,
> 
> I am running unicorn with rails and memcached. The combination usually
> works flawlessly but sometimes when I retrieve an item from memcached i
> get a different, unrelated item.
> 
> At the moment I'm more or less investigating in all directions and after
> reading
> http://www.modrails.com/documentation/Users%20guide.html#%5Fexample%5F1%5Fmemcached%5Fconnection%5Fsharing%5Fharmful
> I thought that maybe the forking nature of unicorn has something to do
> with it.

Hi Stefan,

If you're using "preload_app true" in your config file, then all the
gotchas from Passenger with sharing memcached sockets across processes
apply to Unicorn as well.

> So, are there any steps you have to take to ensure unicorn works with
> memcached?

Which memcached library are you using?

I believe some memcached libraries will delay opening a socket until
it's actually needed (inside the worker processes), but if you use
memcached in your app initialization code, then the socket will be
opened in the master process (which is bad).

So the safe thing would be to reconnect to your memcached servers in the
after_fork hook.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Unicorn, Rails and Memcached
@ 2010-01-05 22:12  7% Stefan Maier
  2010-01-05 22:34  0% ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Stefan Maier @ 2010-01-05 22:12 UTC (permalink / raw)
  To: mongrel-unicorn

Hi,

I am running unicorn with rails and memcached. The combination usually
works flawlessly but sometimes when I retrieve an item from memcached i
get a different, unrelated item.

At the moment I'm more or less investigating in all directions and after
reading
http://www.modrails.com/documentation/Users%20guide.html#%5Fexample%5F1%5Fmemcached%5Fconnection%5Fsharing%5Fharmful
I thought that maybe the forking nature of unicorn has something to do
with it.

So, are there any steps you have to take to ensure unicorn works with
memcached?


Thanks in advance,
Stefan Maier
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* Re: "unicorn -D" always returns 0 "success" (even when failed to load)
  2009-12-29  0:17  7%       ` Eric Wong
@ 2009-12-29  0:32  0%         ` Iñaki Baz Castillo
  0 siblings, 0 replies; 200+ results
From: Iñaki Baz Castillo @ 2009-12-29  0:32 UTC (permalink / raw)
  To: mongrel-unicorn

El Martes, 29 de Diciembre de 2009, Eric Wong escribió:
> Thanks, applied with your name and pushed out to both ready_pipe and
> master in unicorn.git

Thanks a lot :)

 
> > --- unicorn.rb.orig     2009-12-28 21:02:47.000000000 +0100
> > +++ unicorn.rb  2009-12-28 21:11:12.000000000 +0100
> 
> It should be easier to make a commit using git and then just
> "git format-patch -M" to output it, proposed commit message and all.
> 
> In the HACKING doc, I've been recommending people follow the
> SubmittingPatches document distributed with git when submitting
> patches to Unicorn:
> 
>  http://git.bogomips.org/cgit/mirrors/git.git/tree/Documentation/Submitting
> Patches

Ok, I'll read it.
Thanks againg. 


-- 
Iñaki Baz Castillo <ibc@aliax.net>
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: "unicorn -D" always returns 0 "success" (even when failed to load)
  @ 2009-12-29  0:17  7%       ` Eric Wong
  2009-12-29  0:32  0%         ` Iñaki Baz Castillo
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2009-12-29  0:17 UTC (permalink / raw)
  To: unicorn list

Iñaki Baz Castillo <ibc@aliax.net> wrote:
> El Lunes, 28 de Diciembre de 2009, Eric Wong escribió:
> > Iñaki Baz Castillo <ibc@aliax.net> wrote:
> > > El Lunes, 28 de Diciembre de 2009, Eric Wong escribió:
> > > > > As a suggestion, could the grandparent rescue such exception and
> > > > > display some  kind of error message?:
> > > > >
> > > > >   "The master couldn't be started. Inspect the log error or run in
> > > > > foreground"
> > > >
> > > > Thanks, pushed out to the ready_pipe branch of unicorn.git
> > >
> > > Hi, I attach a minor patch to make the error more verbose when Unicorn
> > > cannot listen in a socket.
> > 
> > Hi, it seems like you didn't attach the patch.
> 
> Ops, usually my mail client (Kmail) warns me when I write tha word "attach" 
> but attach nothing... not sure why it didn't it this time.
> 
> > Attaching patches is
> > strongly discouraged, though, inline patches are far easier to
> > review/edit/apply.
> 
> Ok, here it's (note that it's done over 'ready_pipe' branch):

Thanks, applied with your name and pushed out to both ready_pipe and
master in unicorn.git

> --- unicorn.rb.orig     2009-12-28 21:02:47.000000000 +0100
> +++ unicorn.rb  2009-12-28 21:11:12.000000000 +0100

It should be easier to make a commit using git and then just
"git format-patch -M" to output it, proposed commit message and all.

In the HACKING doc, I've been recommending people follow the
SubmittingPatches document distributed with git when submitting
patches to Unicorn:

 http://git.bogomips.org/cgit/mirrors/git.git/tree/Documentation/SubmittingPatches

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 0.95.3 - userinfo in absoluteURIs
@ 2009-12-21 22:21  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2009-12-21 22:21 UTC (permalink / raw)
  To: mongrel-unicorn, ruby-talk

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

Changes:

The HTTP parser now allows (but does not parse) the userinfo
component in the very rare requests that send absoluteURIs.
Thanks to Scott Chacon for reporting and submitting a test case
for this fix.

There are also minor documentation updates and tiny cleanups.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 6%]

* Re: Usernames in the http_URL
  @ 2009-12-19 10:04  7%       ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2009-12-19 10:04 UTC (permalink / raw)
  To: unicorn list

John-Paul Bader <hukl@berlin.ccc.de> wrote:
> Hey guys,
> 
> I think the <resource_type>://<username>:<password>@<host>/<path>
> scheme is not "illegal". There are examples of this in the URL RFC,
> just no explicit HTTP example.
> 
> This probably a vague area. Its not in the http rfc and its not
> explicitly mentioned in the http auth rfc either but in combination
> with the URL RFC there is at least room for it. I haven't found the
> paragraph yet which says: no username:password stuff allowed in http
> urls. But I was just searching through these things … there are good
> chances I missed it.

Hi,

Yes, I've come to the same conclusion.  rfc2616 just seems to defer
to rfc2396 (which superceded rfc1738 and is superceded by rfc3986).

> http://en.wikipedia.org/wiki/URI_scheme
> http://tools.ietf.org/html/rfc2617
> http://www.ietf.org/rfc/rfc1738.txt
> 
> Anyway, I came across such urls a lot. Often I use them for giving
> people easy access to an otherwise basic authed resource - in  a chat
> conversation for example. I know apache and nginx support this - IIS
> does not. 
> 
> Hrm - tough call ;)

Yup, definitely precedence for supporting it (along with Mongrel).  I've
updated the Ragel parser with everything URI.parse("http://..") supports
and pushed out the change.

I've been meaning to make a few more small documentation updates and do
a 0.95.3 release tomorrow when I'm more awake.

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 0.95.2 - small HTTP parser fixes
@ 2009-12-07 10:01  6% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2009-12-07 10:01 UTC (permalink / raw)
  To: ruby-talk ML, mongrel-unicorn

Unicorn is an HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* email: mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git
* finger: unicorn@bogomips.org

Changes:

Small fixes to our HTTP parser to allows semicolons in PATH_INFO
as allowed by RFC 2396, section 3.3.  This is low impact for
existing apps as semicolons are rarely seen in URIs.  Our HTTP
parser runs properly under Rubinius 0.13.0 and 1.0.0-rc1 again
(though not yet the rest of the server since we rely heavily on
signals).

Another round of small documentation tweaks and minor cleanups.

-- 
Eric Wong



^ permalink raw reply	[relevance 6%]

* Re: feature request - when_ready() hook
  2009-11-26 19:05  5%   ` Suraj Kurapati
@ 2009-11-26 19:53  0%     ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2009-11-26 19:53 UTC (permalink / raw)
  To: unicorn list

Suraj Kurapati <sunaku@gmail.com> wrote:
> On Wed, Nov 25, 2009 at 10:05 PM, Eric Wong <normalperson@yhbt.net> wrote:
> > Suraj Kurapati <sunaku@gmail.com> wrote:
> >> * before_fork() -- approx. 2 minute downtime
> >> * after_fork() -- approx. 2 minute downtime
> >> * storing the old-master-killing logic inside a lambda in after_fork()
> >> (for the last worker only) and later executing that lambda in Rails'
> >> config.after_initialize() hook -- approx. 20 second downtime
> >
> > I'm looking at those times and can't help but wonder if there's
> > something very weird/broken with your setup..  20 seconds is already an
> > eternity (even with preload_app=false), but 2 minutes?(!).
> 
> Yes, I am using preload_app=false.  These delays mainly come from
> establishing DB connections and loading XML datasets into the Rails
> app.  Our production DBs are pretty slow to give out new connections.
> The startup time is much faster in development, where I use SQLite.

Yikes.  Is there some sort of misconfiguration in the DBs?  Perhaps
they're trying to do reverse DNS on every client connection, that
can really ruin your day if your app servers don't have reverse DNS.

> Please note that the reported downtimes are shocking only because they
> were *visible* downtimes, where the last worker of the new Unicorn
> master killed the old Unicorn master too soon.  IMHO, it doesn't
> matter how long it takes for the Rails app to become ready, so long as
> the old Unicorn master + workers continue to exist & service requests
> until the new Unicorn master + workers take over.

<snip>

> > Are you using preload_app?  It should be faster if you do, but there
> > really appears to be something else wrong based on those times.
> 
> I was for a few weeks, but I stopped because the XML dataset loading
> (see above) kept increasing the master's (and the new set of workers')
> memory footprint by 1.5x every time Unicorn was restarted via SIGUSR2.

Side problem, but another thing that makes me go "Huh?"

Did the new master's footprint increase?  Are you mmap()-ing the XML
dataset?  Is RSS increasing or just VmSize?  Unicorn sets FD_CLOEXEC on
the first 1024 (non-listener) file descriptors, so combined with exec(),
that should give the new master (and subsequent workers) a clean memory
footprint.

> >> As you can see, the more I delayed the execution of that "killing the
> >> old master" logic, the closer I got to zero downtime deploys.  In this
> >> manner, I request the addition of a when_ready() hook which is
> >> executed just after Unicorn prints "worker=# ready!" to its error log
> >> inside Unicorn::HttpServer#worker_loop().
> >
> > At this stage, maybe even implementing something as middleware and
> > making it hook into request processing (that way you really know the
> > worker is really responding to requests) is the way to go...
> 
> Hmm, but that would incur a penalty on each request (check if I've
> already killed the old master and do it if necessary).  I'm pretty
> confident that killing the old master in the when_ready() hook will be
> Good Enough for my setup (at most I expect to see 1-2 second
> "down"time).  Let me try this out and I'll tell you the results &
> submit a patch.

I don't think a runtime condition would be any more expensive than all
the routing/filters/checks that any Rails app already does and you can
cache the result into a global variable.

As you may have noticed, I'm quite hesitant to add new features,
especially for uncommon/rare cases.  Things like supporting the
"working_directory" directive and user-switching took *months* of
debating with myself before they were finally added.

> >> my unicorn setup does not run very close to the memory limit of
> >> its host; instead, the amount of free memory is more than double of
> >> the current unicorn memory footprint, so I can safely spawn a second
> >> set of Unicorn master + workers (via SIGUSR2) without worrying about
> >> the SIGTTOU before_fork() strategy shown in the Unicorn configuration
> >> example.)
> >
> > Given your memory availability, I wouldn't even worry about the
> > automated killing of the old workers.
> >
> > Automatically killing old workers means you need a redeploy to roll back
> > changes, whereas if you SIGWINCH the old set away, you can HUP the old
> > master to bring them back in case the new set is having problems.
> 
> Wow this is cool.  Perhaps this strategy could be mentioned in the
> documentation?

It's already at the bottom of the SIGNALS
(http://unicorn.bogomips.org/SIGNALS.html) document

> Thanks for your consideration.

No problem, let us know if it's the DB doing reverse DNS because
I've seen that to be a problem in a lot of cases.

-- 
Eric Wong

^ permalink raw reply	[relevance 0%]

* Re: feature request - when_ready() hook
  @ 2009-11-26 19:05  5%   ` Suraj Kurapati
  2009-11-26 19:53  0%     ` Eric Wong
  0 siblings, 1 reply; 200+ results
From: Suraj Kurapati @ 2009-11-26 19:05 UTC (permalink / raw)
  To: unicorn list

On Wed, Nov 25, 2009 at 10:05 PM, Eric Wong <normalperson@yhbt.net> wrote:
> Suraj Kurapati <sunaku@gmail.com> wrote:
>> * before_fork() -- approx. 2 minute downtime
>> * after_fork() -- approx. 2 minute downtime
>> * storing the old-master-killing logic inside a lambda in after_fork()
>> (for the last worker only) and later executing that lambda in Rails'
>> config.after_initialize() hook -- approx. 20 second downtime
>
> I'm looking at those times and can't help but wonder if there's
> something very weird/broken with your setup..  20 seconds is already an
> eternity (even with preload_app=false), but 2 minutes?(!).

Yes, I am using preload_app=false.  These delays mainly come from
establishing DB connections and loading XML datasets into the Rails
app.  Our production DBs are pretty slow to give out new connections.
The startup time is much faster in development, where I use SQLite.

Please note that the reported downtimes are shocking only because they
were *visible* downtimes, where the last worker of the new Unicorn
master killed the old Unicorn master too soon.  IMHO, it doesn't
matter how long it takes for the Rails app to become ready, so long as
the old Unicorn master + workers continue to exist & service requests
until the new Unicorn master + workers take over.

> Are you doing per-process listeners and retrying?  The new ones could be
> fighting for a port held by the old workers...  Other than that...

No, I have one listen() call (on a UNIX socket) at the top level of my
Unicorn configuration file.  Nothing fancy.

> I have many questions, because those times look extremely scary to me
> and I wonder if such a hook would only be masking the symptoms of
> a bigger problem.
>
> What kind of software/hardware stack are you running?
> (please don't say NSLU2 :)

The hardware is some kind of VM running on a VM server farm, running CentOS 4.

The software is Ruby 1.9.1-p243 with Rails 2.3.3, running on Unicorn
0.95.1, behind Nginx, behind M$ IIS.

> How many workers?

Three.

> How heavy is traffic on the site when you're deploying?

About 15 to 20 users.

> How long does it take for a single worker to get ready and start
> serving requests?

Approximately 2 minutes.

> Are you using preload_app?  It should be faster if you do, but there
> really appears to be something else wrong based on those times.

I was for a few weeks, but I stopped because the XML dataset loading
(see above) kept increasing the master's (and the new set of workers')
memory footprint by 1.5x every time Unicorn was restarted via SIGUSR2.

>> As you can see, the more I delayed the execution of that "killing the
>> old master" logic, the closer I got to zero downtime deploys.  In this
>> manner, I request the addition of a when_ready() hook which is
>> executed just after Unicorn prints "worker=# ready!" to its error log
>> inside Unicorn::HttpServer#worker_loop().
>
> At this stage, maybe even implementing something as middleware and
> making it hook into request processing (that way you really know the
> worker is really responding to requests) is the way to go...

Hmm, but that would incur a penalty on each request (check if I've
already killed the old master and do it if necessary).  I'm pretty
confident that killing the old master in the when_ready() hook will be
Good Enough for my setup (at most I expect to see 1-2 second
"down"time).  Let me try this out and I'll tell you the results &
submit a patch.

>> my unicorn setup does not run very close to the memory limit of
>> its host; instead, the amount of free memory is more than double of
>> the current unicorn memory footprint, so I can safely spawn a second
>> set of Unicorn master + workers (via SIGUSR2) without worrying about
>> the SIGTTOU before_fork() strategy shown in the Unicorn configuration
>> example.)
>
> Given your memory availability, I wouldn't even worry about the
> automated killing of the old workers.
>
> Automatically killing old workers means you need a redeploy to roll back
> changes, whereas if you SIGWINCH the old set away, you can HUP the old
> master to bring them back in case the new set is having problems.

Wow this is cool.  Perhaps this strategy could be mentioned in the
documentation?

Thanks for your consideration.
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[relevance 5%]

* Re: Nginx Conf
  2009-11-22 22:53  6% ` Nginx Conf Eric Wong
@ 2009-11-23  3:57  0%   ` Dylan Stamat
  0 siblings, 0 replies; 200+ results
From: Dylan Stamat @ 2009-11-23  3:57 UTC (permalink / raw)
  To: unicorn list


On Nov 22, 2009, at 2:53 PM, Eric Wong wrote:

> huet bartels <hbartels@i-neda.com> wrote:
>> Thank you all very much for you time.  
>> 
>> I will have a look at the configuration  examples today.
> 
> Sorry for the late reply, I forgot about this thread (and I'm lazy
> about following links).
> 
> One general thing about the nginx configs I've seen is that they're
> missing the fail_timeout=0 directive in the "server" lines.
> 
> I highly recommend setting it since it's a low cost to try an upstream
> for nginx, and you can avoid 502 errors in case there's a bug in your
> app that causes a Unicorn worker to not send a valid HTTP response
> (including hitting the app timeout).
> 
> I actually have this in the Configurator documentation[1]:
> 
>    #    # See http://wiki.nginx.org/NginxHttpUpstreamModule for more details
>    #    # on nginx upstream configuration:
>    #    upstream unicorn_backend {
>    #      # for UNIX domain socket setups:
>    #      server unix:/path/to/unicorn.sock fail_timeout=0;
>    #
>    #      # for TCP setups
>    #      server 192.168.0.7:8080 fail_timeout=0;
>    #      server 192.168.0.8:8080 fail_timeout=0;
>    #      server 192.168.0.9:8080 fail_timeout=0;
>    #    }
> 
> [1] - http://unicorn.bogomips.org/Unicorn/Configurator.html
> 
> We've had fail_timeout=0 deployed to several places (many non-Unicorn
> servers) here and there and have experienced no negative effects
> (we're pretty good about keeping our backends up :)
> 
> If anybody can recommend a better place in the Unicorn docs to put this,
> that'd be great, too...  Maybe I'll drop something in the examples/
> directory.
> 
> -- 
> Eric Wong
> _______________________________________________
> mongrel-unicorn mailing list
> mongrel-unicorn@rubyforge.org
> http://rubyforge.org/mailman/listinfo/mongrel-unicorn

Hey Eric,

Yeah, an nginx.conf in examples/ would be great.
It's probably going to be the most widely used front for Unicorn/Rainbows!, so
a sample config with some explanations here and there would be awesome.
It was great setting up Unicorn and being able to just grab the init.sh out of there!

In terms of the fail_timeout, I haven't seen a nginx.conf with that entry yet!
Maybe I'm looking at configuration files on the wrong projects ;)
So, since the upstream attempts are cheap, the combination of a max_fail of 1
and fail_timeout of 0 is ideal?  If the fail_timeout was at 10, and all the
upstreams timed out, wouldn't it restart at the beginning of the round-robin, and
not block... or... would it actually not retry on any due to the inoperable state?

Thanks!
==
Dylan Stamat

ELC Technologies (TM)
1921 State Street
Santa Barbara, CA 93101
dstamat@elctech.com

(866)863-7365 Tel
(866)893-1902 Fax

+44 (0)20 7504 1346 Tel - London Office
+44 (0)20 7504 1347 Fax - London Office

http://www.elctech.com

^ permalink raw reply	[relevance 0%]

* Re: Nginx Conf
  @ 2009-11-22 22:53  6% ` Eric Wong
  2009-11-23  3:57  0%   ` Dylan Stamat
  0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2009-11-22 22:53 UTC (permalink / raw)
  To: unicorn list

huet bartels <hbartels@i-neda.com> wrote:
> Thank you all very much for you time.  
> 
> I will have a look at the configuration  examples today.

Sorry for the late reply, I forgot about this thread (and I'm lazy
about following links).

One general thing about the nginx configs I've seen is that they're
missing the fail_timeout=0 directive in the "server" lines.

I highly recommend setting it since it's a low cost to try an upstream
for nginx, and you can avoid 502 errors in case there's a bug in your
app that causes a Unicorn worker to not send a valid HTTP response
(including hitting the app timeout).

I actually have this in the Configurator documentation[1]:

    #    # See http://wiki.nginx.org/NginxHttpUpstreamModule for more details
    #    # on nginx upstream configuration:
    #    upstream unicorn_backend {
    #      # for UNIX domain socket setups:
    #      server unix:/path/to/unicorn.sock fail_timeout=0;
    #
    #      # for TCP setups
    #      server 192.168.0.7:8080 fail_timeout=0;
    #      server 192.168.0.8:8080 fail_timeout=0;
    #      server 192.168.0.9:8080 fail_timeout=0;
    #    }

[1] - http://unicorn.bogomips.org/Unicorn/Configurator.html

We've had fail_timeout=0 deployed to several places (many non-Unicorn
servers) here and there and have experienced no negative effects
(we're pretty good about keeping our backends up :)

If anybody can recommend a better place in the Unicorn docs to put this,
that'd be great, too...  Maybe I'll drop something in the examples/
directory.

-- 
Eric Wong

^ permalink raw reply	[relevance 6%]

* [ANN] unicorn 0.95.0 - we <3 Rainbows! and ponies too
@ 2009-11-15 22:34  5% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2009-11-15 22:34 UTC (permalink / raw)
  To: ruby-talk ML, mongrel-unicorn; +Cc: ruby-talk

Unicorn is a HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

Changes:

Mostly internal cleanups and documentation updates.  Irrelevant
stacktraces from client disconnects/errors while reading
"rack.input" are now cleared to avoid unnecessary noise.  If
user switching in workers is used, ownership of logs is now
preserved when reopening worker logs (send USR1 only to the the
master in this case).  The timeout config no longer affects long
after_fork hooks or application startups.

New features include the addition of the :umask option for the
"listen" config directive and error reporting for non-portable
socket options.

No ponies have ever been harmed in our development.

Eric Wong (28):
      unicorn.1: document RACK_ENV changes in 0.94.0
      HACKING: update with "gmake" in examples
      don't nuke children for long after_fork and app loads
      local.mk.sample: steal some updates from Rainbows!
      Load Unicorn constants when building app
      tee_input: fix RDoc argument definition for tee
      Add FAQ
      FAQ: fix links to Configurator docs
      tee_input: better premature disconnect handling
      tee_input: don't shadow struct members
      raise Unicorn::ClientShutdown if client aborts in TeeInput
      tee_input: fix comment from an intermediate commit
      FAQ: additional notes on getting HTTPS redirects right
      configurator: update RDoc and comments in examples
      bump version to 0.95.0pre
      configurator: listen :umask parameter for UNIX sockets
      preserve user/group ownership when reopening logs
      old_rails/static: avoid freezing strings
      old_rails: autoload Static
      const: no need to freeze HTTP_EXPECT
      test_server: ensure stderr is written to before reading
      tee_input: expand client error handling
      replace "rescue => e" with "rescue Object => e"
      socket_helper: do not hide errors when setting socket options
      socket_helper: RDoc for constants
      ClientShutdown: RDoc
      Rakefile: add raa_update task
      tee_input: client_error always raises

-- 
Eric Wong



^ permalink raw reply	[relevance 5%]

* Re: zero downtime deploys
  @ 2009-11-13 23:12  7% ` Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2009-11-13 23:12 UTC (permalink / raw)
  To: unicorn list

Suraj Kurapati <sunaku@gmail.com> wrote:
> Hello,
> 
> I tried using preload_app with the "zero downtime deploys" trick of
> sending SIGQUIT to the old master in before_fork(), as described in:
> 
>   http://unicorn.bogomips.org/Unicorn/Configurator.html
>   http://github.com/blog/517-unicorn
> 
> This significantly reduced, but did not eliminate, the transition time
> when the new workers take over (step #2 below):
> 
> 1. old master (and its workers) is killed in before_fork()
> 2. workers re-establish DB connections in after_fork()
> 3. workers are ready to work, at the bottom of after_fork()
> 
> Why do we kill the old master in before_fork() when the new workers
> are really ready to work much later?  Shouldn't we kill the old master
> at the *bottom* of after_fork() --- when the new workers are really
> ready to work?

Hi Suraj,

It depends on your setup, mainly memory constraints.  I know some
deployments run very close to the memory limit of the box and those
examples are geared for that.  We should clarify that in the
documentation.  I also know some setups that always startup with
worker_processes=1 and then SIGTTIN through an external script
gradually.

Obviously I would always try to avoid maintenance during peak traffic
because performance inevitably suffers somewhat (and human error is
always possible :)

-- 
Eric Wong

^ permalink raw reply	[relevance 7%]

* [ANN] unicorn 0.94.0 - small fixes and new features
@ 2009-11-05 10:06  4% Eric Wong
  0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2009-11-05 10:06 UTC (permalink / raw)
  To: mongrel-unicorn

Unicorn is a HTTP server for Rack applications designed to only serve
fast clients on low-latency, high-bandwidth connections and take
advantage of features in Unix/Unix-like kernels.  Slow clients should
only be served by placing a reverse proxy capable of fully buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

Changes:

The HTTP parser is fix for oddly-aligned reads of trailers (this
technically affects headers, too, but is highly unlikely due to
our non-support of slow clients).  This allows our HTTP parser
to better support very slow clients when used by other servers
(like Rainbows!).  Fortunately this bug does not appear to lead
to any invalid memory accesses (and potential arbitrary code
execution).

FreeBSD (and possibly other *BSDs) support is improved and and
all the test cases pass under FreeBSD 7.2.  Various flavors of
GNU/Linux remains our primary platform for development and
production.

New features added include the "working_directory" directive in
the configurator .  Even without specifying a
"working_directory", symlink-aware detection of the current path
no longer depends on /bin/sh so it should work out-of-the-box on
FreeBSD and Solaris and not just systems where /bin/sh is dash,
ksh93 or bash.

User-switching support is finally supported but only intended
for use in the after_fork hook of worker processes.  Putting it
in the after_fork hook allows allows users to set things like
CPU affinity[1] on a per-worker basis before dropping
privileges.  The master process retains all privileges it
started with.

The ENV["RACK_ENV"] (process-wide) environment variable is now
both read and set for `unicorn' in the same way RAILS_ENV is
used by `unicorn_rails'.  This allows the Merb launcher to read
ENV["RACK_ENV"] in config.ru.  Other web servers already set
this and there may be applications or libraries that already
rely on this de facto standard.

Eric Wong (26):
      cleanup: avoid redundant error checks for fstat
      test_helper: connect(2) may fail with EINVAL
      GNUmakefile: fix non-portable tar(1) usage
      tests: provide a pure Ruby setsid(8) equivalent
      more portable symlink awareness for START_CTX[:cwd]
      test_signals: avoid portability issues with fchmod(2)
      cleanup error handling and make it less noisy
      Do not override Dir.chdir in config files
      configurator: add "working_directory" directive
      configurator: working_directory is expanded
      configurator: set ENV["PWD"] with working_directory, too
      configurator: working_directory affects pid, std{err,out}_paths
      configurator: update documentation for working_directory
      TODO: remove working_directory bit, done
      Util.reopen_logs: remove needless Range
      worker: user/group switching for after_fork hooks
      Fix autoload of Etc in Worker for Ruby 1.9
      bin/unicorn: allow RACK_ENV to be passed from parent
      tests for RACK_ENV preservation
      http: allow headers/trailers to be written byte-wise
      http: extra test for bytewise chunked bodies
      tee_input: do not clobber trailer buffer on partial uploads
      test_exec: ensure master is killed after test
      Util::tmpio returns a TmpIO that responds to #size
      TODO: remove user-switching bit, done
      unicorn 0.94.0

Wayne Larsen (1):
      bin/unicorn: set ENV["RACK_ENV"] on startup

[1] - Unicorn does not support CPU affinity directly, but it is
      possible to load code that allows it inside after_fork hooks,
      or even just call sched_tool(8).

-- 
Eric Wong

^ permalink raw reply	[relevance 4%]

Results 1-200 of ~250   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2009-11-05 10:06  4% [ANN] unicorn 0.94.0 - small fixes and new features Eric Wong
2009-11-13 22:54     zero downtime deploys Suraj Kurapati
2009-11-13 23:12  7% ` Eric Wong
2009-11-15 22:34  5% [ANN] unicorn 0.95.0 - we <3 Rainbows! and ponies too Eric Wong
2009-11-19  7:49     RE:Nginx Conf huet bartels
2009-11-22 22:53  6% ` Nginx Conf Eric Wong
2009-11-23  3:57  0%   ` Dylan Stamat
2009-11-26  4:50     feature request - when_ready() hook Suraj Kurapati
2009-11-26  6:05     ` Eric Wong
2009-11-26 19:05  5%   ` Suraj Kurapati
2009-11-26 19:53  0%     ` Eric Wong
2009-12-07 10:01  6% [ANN] unicorn 0.95.2 - small HTTP parser fixes Eric Wong
2009-12-18  0:20     Usernames in the http_URL Scott Chacon
2009-12-18  1:23     ` Eric Wong
2009-12-18  2:31       ` Scott Chacon
2009-12-18  9:48         ` John-Paul Bader
2009-12-19 10:04  7%       ` Eric Wong
2009-12-21 22:21  6% [ANN] unicorn 0.95.3 - userinfo in absoluteURIs Eric Wong
2009-12-26  4:29     "unicorn -D" always returns 0 "success" (even when failed to load) Iñaki Baz Castillo
2009-12-28 20:17     ` Iñaki Baz Castillo
2009-12-28 20:32       ` Eric Wong
2009-12-28 20:41         ` Iñaki Baz Castillo
2009-12-29  0:17  7%       ` Eric Wong
2009-12-29  0:32  0%         ` Iñaki Baz Castillo
2010-01-05 22:12  7% Unicorn, Rails and Memcached Stefan Maier
2010-01-05 22:34  0% ` Eric Wong
2010-01-05 22:47  0%   ` Stefan Maier
2010-01-20  9:20     Suggestion for reload action (USR2) Iñaki Baz Castillo
2010-01-20 20:03     ` Eric Wong
2010-01-20 20:22       ` Iñaki Baz Castillo
2010-01-20 20:58  7%     ` Eric Wong
2010-01-21 11:20  0%       ` Iñaki Baz Castillo
2010-02-13 10:34  6% [ANN] unicorn 0.96.1 - leak fix for Rainbows!/Zbatery Eric Wong
2010-03-08 20:31     Monit configuration Florian Munz
2010-03-08 21:03     ` Iñaki Baz Castillo
2010-03-08 22:12  7%   ` Florian Munz
2010-03-17  9:51     Unicorn 0.97.0 old master is never dying ghazel
2010-03-18  8:40     ` Eric Wong
2010-03-18 16:35       ` ghazel
2010-03-19  8:23         ` Eric Wong
2010-03-19  8:55  5%       ` ghazel
2010-04-09  2:37  4% [ANN] raindrops - real-time stats for preforking Rack servers Eric Wong
2010-05-05  1:09  6% [ANN] unicorn 0.98.0 - Rack HTTP server for fast clients and Unix Eric Wong
2010-06-04 19:06     Logging errors from Unicorn Peter Kieltyka
2010-06-04 20:06  7% ` Eric Wong
2010-06-04 20:47 15%   ` [PATCH] doc: emphasize the importance of stderr_path Eric Wong
2010-06-08  9:51     [ANN] unicorn 0.990.0 - inching towards 1.0 Eric Wong
2010-06-09  8:39     ` Alexander Simonov
2010-06-09 18:22       ` Eric Wong
2010-06-10  5:26         ` Alexander Simonov
2010-06-10  7:38           ` Eric Wong
2010-06-10  8:46  7%         ` Alexander Simonov
2010-06-11  1:27  0%           ` Eric Wong
2010-06-11 18:00  0%             ` Alexander Simonov
2010-06-11  2:31  6% [ANN] unicorn 0.991.0 - startup improvements Eric Wong
2010-06-16  0:09  8% anything left before 1.0? Eric Wong
2010-07-02 20:50     [PATCH] Show the current working directory in the proc title Jeremy Evans
2010-07-02 22:29     ` Eric Wong
2010-07-02 22:50  6%   ` Jeremy Evans
2010-07-05 23:34 25%     ` Eric Wong
2010-07-06  2:18  0%       ` Lawrence Pit
2010-07-08  8:04  6% [ANN] unicorn 1.1.0 - small changes and cleanups Eric Wong
2010-07-08 20:55     Setting app name for process list Paul Dlug
2010-07-08 21:22  7% ` Devin Ben-Hur
2010-07-08 21:42  0%   ` Eric Wong
2010-07-09  5:09  0%     ` Paul Dlug
2010-07-09  5:44  0%       ` Jeremy Evans
2010-07-13  4:25     SIGWINCH Lawrence Pit
2010-07-13  8:24  7% ` SIGWINCH Eric Wong
2010-08-09 22:54  4% [ANN] 1.9 users: socket_dontwait - MSG_DONTWAIT socket methods Eric Wong
2010-08-31  3:57     Hello excellent friends Curtis
2010-08-31  6:17  7% ` Eric Wong
2010-09-15  6:40     Unicorn fails to restart gracefully on capistrano deploy Eirik Dentz Sinclair
2010-09-15 21:52  8% ` Eric Wong
2010-10-04 20:37  6% [ANN] unicorn 1.1.4 - small bug fix and doc updates Eric Wong
2010-11-12 20:51  3% error when HUP'ing unicorn Grant Heffernan
2010-12-26  8:29  7% [ANN] unicorn 3.2.1 - parser improvements for Rainbows! Eric Wong
2011-03-08  4:40 10% [RFC/PATCH] Bundler/Sandbox documentation updates Eric Wong
2011-03-08 14:22 12% ` Justin Giancola
2011-03-10  0:49 12%   ` Eric Wong
2011-03-09 10:39 12% ` Lawrence Pit
2011-03-10  0:52 12%   ` Eric Wong
2011-03-10  3:30 12%     ` Lawrence Pit
2011-03-10 21:29 11%       ` Eric Wong
2011-04-12 16:13     Struggling with logrotate and unicorn Emmanuel Gomez
2011-04-12 17:58     ` Eric Wong
2011-04-12 18:36       ` Emmanuel Gomez
2011-04-12 18:59  6%     ` Eric Wong
2011-04-12 22:38  0%       ` Emmanuel Gomez
2011-04-12 22:51  0%         ` Eric Wong
2011-04-30  6:45  7% [ANN] unicorn 3.6.2 (and 1.1.7) - fix Unicorn::OobGC module Eric Wong
2011-06-06 11:44  6% [PATCH] Document the method for building the Unicorn gem Hongli Lai
2011-06-06 16:58  0% ` Eric Wong
2011-06-06 17:06  9%   ` Eric Wong
2011-06-06 17:31 20% [PATCH] Ensure that 'make gem' builds the documentation too Hongli Lai
2011-06-06 17:51 12% ` Eric Wong
2011-06-07 15:11 12%   ` Hongli Lai
2011-06-07 17:06 12%     ` Eric Wong
2011-06-07  2:28     [PATCH] examples/nginx.conf: add ipv6only comment Eric Wong
2011-06-07 21:05  6% ` [PATCH] configurator: add :ipv6only directive Eric Wong
2011-06-09 20:55  7% [ANN] unicorn 3.7.0 - minor feature update Eric Wong
2011-08-25  1:02  9% [PATCH] doc: add Application Timeouts document Eric Wong
2012-01-20 15:35  6% Default Socket Location Steven Garcia
2012-01-20 17:22  0% ` Devin Ben-Hur
2012-01-28  9:25  6% [ANN] unicorn 4.2.0 - minor fixes and improvements Eric Wong
2012-03-22  6:30  6% unicorn 4.2.1 release soon? Eric Wong
2012-04-05  7:21     Problem restarting Unicorn Andrew Stewart
2012-04-05 11:34  7% ` Michael Guterl
2012-04-10  8:52  7%   ` Andrew Stewart
2012-04-11  8:07     Request-URI Too Long from mongrel-unicorn Nuo Yan
2012-04-11 20:30     ` Eric Wong
2012-04-11 21:44       ` Nuo Yan
2012-04-12  3:52  7%     ` Eric Wong
2012-04-28  2:46  6% unicorn + sleep = long wake up loading time adam k
2012-04-28  4:40  0% ` Eric Wong
2012-05-08 12:14     An Issue with max request uri length Vladislav Shub
2012-05-08 19:13  8% ` Eric Wong
2012-05-11  1:12     [raindrops] testers on 32-bit FreeBSD wanted Eric Wong
2012-05-12  6:05  6% ` Eric Wong
2012-05-23 13:29  7% [Suggestion] Add upstream param to listen statement Manuel Valente
2012-07-17  0:33  4% Any signal other than -9 causes full CPU utilization by master unicorn process on FreeBSD Mark Mccraw
2012-07-17  2:05  0% ` Eric Wong
2012-07-17 11:56  0%   ` Mark Mccraw
2012-07-17 21:23  0%     ` Mark Mccraw
2012-08-31 11:38  4% after_fork - ActiveRecord::AdapterNotSpecified Frank Rennekamp
2012-08-31 20:02  0% ` Eric Wong
2012-10-09  0:39     Is a client uploading a file a slow client from unicorn's point of view? Jimmy Soho
2012-10-09  1:58     ` Eric Wong
2012-10-09  6:31       ` Laas Toom
2012-10-09 20:03  6%     ` Eric Wong
2012-10-09 23:06  0%       ` Laas Toom
2012-10-12 17:55     [PATCH] explicitly use escaped minus in man pages Hleb Valoshka
2012-10-15 18:50  9% ` Eric Wong
2012-10-17 15:33  0%   ` Hleb Valoshka
2012-10-18  8:04  0%     ` Eric Wong
2012-10-29 21:53     Combating nginx 499 HTTP responses during flash traffic scenario Eric Wong
2012-10-30 20:40     ` Tom Burns
2012-10-30 21:37       ` Eric Wong
2012-11-02 17:59         ` Tom Burns
2012-11-02 19:38           ` Eric Wong
2012-11-03 22:45             ` Tom Burns
2012-11-05 11:48               ` Eric Wong
2012-11-06  3:16                 ` Tom Burns
2012-11-06 21:23                   ` Eric Wong
2012-11-29 15:52                     ` Tom Burns
2012-11-29 20:41  7%                   ` Eric Wong
2012-11-29 21:19                       ` Eric Wong
2012-11-29 21:55                         ` [RFC/PATCH] check_client_connection: document local-only requirement Eric Wong
2012-11-29 23:47  7%                       ` Tom Burns
2013-01-29 21:10  7% [ANN] unicorn 4.6.0pre1 - hijacking support! Eric Wong
2013-01-29 21:23 30% ` [PATCH] manpage: update middleware-related documentation Eric Wong
2013-02-04 13:40  5% ` [ANN] unicorn 4.6.0pre1 - hijacking support! Eric Wong
2013-02-06 11:27  9% [ANN] unicorn 4.6.0 - hijacking support Eric Wong
2013-02-08 13:54     Unicorn 4.6.0 version is 4.5.0 Maurizio De Santis
2013-02-08 18:55  8% ` [PATCH] auto-generate Unicorn::Const::UNICORN_VERSION Eric Wong
2013-04-05 21:16     Fedora Unix socket file location problems David Wilkins
2013-04-05 21:56  4% ` Eric Wong
2013-06-21  8:14  9% [ANN] unicorn 4.6.3 - fix --no-default-middleware option Eric Wong
2013-09-20 21:40     [PATCH] preload_app can take an optional block for warmup Aman Gupta
2013-09-21  8:49  6% ` Eric Wong
2013-09-21 23:10  0%   ` Aman Gupta
2013-10-10 22:18     unicorn simple cgi without rails nomad Bellcam
2013-10-10 22:53  6% ` Eric Wong
2013-11-26  1:00     Issues with PID file renaming Jimmy Soho
2013-11-26  1:20     ` Eric Wong
2013-12-10 12:46       ` Petteri Räty
2013-12-10 19:52         ` Eric Wong
2013-12-10 22:44           ` Petteri Räty
2013-12-11 13:54  7%         ` Michael Fischer
2013-12-12 19:15  0%           ` Petteri Räty
2013-12-12 20:51  0%             ` Eric Wong
2013-11-26 13:30     What does it mean for the unicorn process to be bound to a terminal? Rodrigo Rosenfeld Rosas
2013-11-26 18:04  6% ` Eric Wong
2013-11-26 18:35  6%   ` Rodrigo Rosenfeld Rosas
2013-11-26 19:21  0%     ` Eric Wong
2014-05-07  8:05  6% [ANN] unicorn 4.8.3 - the end of an era Eric Wong
2014-05-07  9:30     ` Jérémy Lecour
2014-05-07  9:46       ` Eric Wong
2014-05-07 10:16         ` Lin Jen-Shin (godfat)
2014-05-07 10:52           ` Alejandro Riera
2014-05-07 19:54  6%         ` handling SMTP subscribers to public-inboxen Eric Wong
2014-05-07 12:08  0% ` [ANN] unicorn 4.8.3 - the end of an era Bráulio Bhavamitra
2014-08-02  7:51     Please move to github Gary Grossman
2014-08-02  8:50     ` Eric Wong
2014-08-02 19:07       ` Gary Grossman
2014-08-02 20:15  6%     ` Eric Wong
2014-08-04 18:12     Weird Unicorn Timeout Issues (Hibernation problem?) Tony Devlin
2014-08-04 18:39     ` Eric Wong
2014-08-04 18:45       ` Tony Devlin
2014-08-04 19:11         ` Eric Wong
2014-08-04 19:21           ` Tony Devlin
2014-08-04 19:45  6%         ` Eric Wong
2014-08-04 20:06  0%           ` Michael Fischer
2014-08-04 18:55       ` Daniel Condomitti
2014-08-04 19:34  7%     ` Eric Wong
2014-10-03 11:34     Master hooks needed Bráulio Bhavamitra
2014-10-03 12:22  6% ` Eric Wong
2014-10-03 12:36  0%   ` Valentin Mihov
2014-10-04  0:53  0%   ` Bráulio Bhavamitra
2014-10-04  1:22         ` Eric Wong
2014-10-04  1:35           ` Bráulio Bhavamitra
2014-10-04  1:57  6%         ` Eric Wong
2014-10-04  2:04  6%           ` Bráulio Bhavamitra
2014-10-04  2:25  0%             ` Eric Wong
2014-10-24 17:33     Having issue with Unicorn Imdad
2014-10-24 17:45     ` Eric Wong
2014-10-24 18:02  4%   ` Imdad
2014-12-03  9:50     No, passenger 5.0 is not faster than unicorn :) Bráulio Bhavamitra
2014-12-03 11:00  5% ` Hongli Lai
2014-12-03 11:05  0%   ` Sam Saffron
2014-12-03 14:10  0%   ` Bráulio Bhavamitra
2015-02-04 20:16 11% [PATCH] GNUmakefile: fix clean gem build + reduce build cruft Eric Wong
2015-02-10 17:06     [PATCH] ISSUES: add section for bugs in other projects Eric Wong
2015-02-10 17:26 10% ` Eric Wong
2015-03-12 22:32 22% [PATCH] doc: document UNICORN_FD in manpage Eric Wong
2015-04-22 19:02  7% unicorn 4.8.x-stable branch pushed to git Eric Wong
2015-04-24  3:17  5% [ANN] unicorn 4.9.0 - Rack HTTP server for fast clients and *nix Eric Wong
2015-06-26  0:47 20% [PATCH] doc: update some invalid URLs Eric Wong
2015-07-01 16:08     Unicorn returns blank page after no use Farjad Adamjee
2015-07-01 17:30  6% ` Eric Wong
2015-09-29  6:38     Request to follow SemVer/mention it in homepage Pirate Praveen
2015-09-29  7:36     ` Eric Wong
2015-09-29  8:00       ` Pirate Praveen
2015-09-29 19:36         ` Eric Wong
2015-09-30 16:04           ` Pirate Praveen
2015-09-30 19:51  7%         ` Eric Wong
2015-10-01  4:56  0%           ` Pirate Praveen
2015-10-01 11:18  0%             ` Pirate Praveen
2015-09-29  9:26       ` Jérémy Lecour
2015-09-29 19:43  7%     ` Eric Wong
2015-10-05  2:43  4% [PATCH] doc: update mail archive info Eric Wong
2015-10-27  3:33  6% [PATCH 0/2] socket inheritance behavior/bug => feature! Eric Wong
2015-10-27  3:33 19% ` [PATCH 2/2] inheriting sockets from UNICORN_FD does not close them Eric Wong
2015-11-13  0:51  6% Shared Metrics Between Workers Jeff Utter
2016-01-07  3:41 34% [PUSHED] various documentation updates Eric Wong
2016-01-08 18:34     [PATCH] limit rack version for ruby compatibility Adam Duke
2016-01-08 19:18  6% ` Eric Wong
2016-01-08 21:50  0%   ` Aaron Patterson
2016-01-08 21:56  0%     ` Aaron Patterson
2016-01-08 22:13  0%       ` Adam Duke
2016-01-27 23:16  8% [ANN] unicorn 5.1.0.pre1 - Rack HTTP server for fast clients and *nix Eric Wong
2016-03-07 23:08     Systemd socket inheritance fails with “not a socket file descriptor” Amir Yalon
2016-03-08  3:31     ` Eric Wong
2016-03-08  7:45       ` Amir Yalon
2016-03-08 17:39         ` Eric Wong
2016-03-08 20:32           ` Amir Yalon
2016-03-09  3:51             ` Eric Wong
2016-03-09 14:06               ` Christos Trochalakis
2016-03-10  9:48                 ` Amir Yalon
2016-03-12  5:30  7%               ` Eric Wong
2016-03-15  7:36     https://unicorn.bogomips.org accepts client certificate? Shota Fukumori (sora_h)
2016-03-15  8:58     ` Eric Wong
2016-03-15  9:21       ` Shota Fukumori (sora_h)
2016-03-15  9:43         ` russm
2016-03-15 23:20           ` Shota Fukumori (sora_h)
2016-03-15 23:30  7%         ` Eric Wong
2016-03-15 23:54  0%           ` Shota Fukumori (sora_h)
2016-03-31  1:41  9% [PATCH] doc: further trimming to reduce noise Eric Wong
2016-04-01  0:43  5% [ANN] unicorn 5.1.0 - Rack HTTP server for fast clients and *nix Eric Wong
     [not found]     <CAL-rKu6CZ731c=uHyZ8+Fg2fhC30e-3-J26XODacUK=YrfX+5Q@mail.gmail.com>
2016-06-07 13:41  0% ` [PATCH] `unicorn upgrade` script resilience against exceptions Eric Wong
2016-06-07 15:17  0%   ` Jesper Rønn-Jensen
2016-10-20  9:05     [PATCH] Add some tolerance (RFC2616 sec. 19.3) Mishael A Sibiryakov
2016-10-20 17:55  6% ` Eric Wong
2016-10-20 20:25  0%   ` Mishael A Sibiryakov
2016-10-25 22:25 42% [PATCH] relocate website to https://bogomips.org/unicorn/ Eric Wong
     [not found]     <20161031-unicorn-5.2.0-released@bogomips.org>
2016-10-31 20:04  6% ` [ANN] unicorn 5.2.0 - Rack HTTP server for fast clients and *nix Eric Wong
2017-02-21 19:19     Patch: Add after_worker_exit configuration option Jeremy Evans
2017-02-21 19:43     ` Eric Wong
2017-02-21 20:02       ` Jeremy Evans
2017-02-21 20:15  7%     ` Eric Wong
2017-02-21 20:49  0%       ` Jeremy Evans
2017-02-22 12:02  4% check_client_connection using getsockopt(2) Simon Eskildsen
2017-02-23  0:49     Patch: Add after_worker_ready configuration option Jeremy Evans
2017-02-23  2:32  9% ` Eric Wong
2017-02-23  3:43  6%   ` Jeremy Evans
2017-02-23  9:23  5%     ` Eric Wong
2017-02-23 20:00  0%       ` Jeremy Evans
2017-02-23 18:48 21% Patch: Fix code example in after_worker_exit documentation Jeremy Evans
2017-02-23 20:21 12% ` Eric Wong
2017-02-23 18:49  4% Patch: Add after_worker_ready configuration option V2 Jeremy Evans
2017-02-23 20:29  7% ` Eric Wong
2017-03-08  7:29       ` Eric Wong
2017-03-08  7:44  6%     ` [PATCH] doc: add version annotations for new features Eric Wong
2017-02-25 14:03     [PATCH] check_client_connection: use tcp state on linux Simon Eskildsen
2017-02-25 16:19     ` Simon Eskildsen
2017-02-25 23:12       ` Eric Wong
2017-02-27 11:44         ` Simon Eskildsen
2017-02-28 21:12           ` Eric Wong
2017-03-01  3:18 10%         ` Eric Wong
2017-03-06 21:32  0%           ` Simon Eskildsen
2017-03-20 20:08 13% [PATCH] input: update documentation and hide internals Eric Wong
2017-03-23  2:48  8% [ANN] raindrops 0.18.0 - real-time stats for preforking Rack servers Eric Wong
2017-03-24  0:28  6% [ANN] unicorn 5.3.0.pre1 - Rack HTTP server for fast clients and Unix Eric Wong
2017-04-01  8:08  6% [ANN] unicorn 5.3.0 " Eric Wong
2017-12-23 23:42  5% [ANN] unicorn 5.4.0 " Eric Wong
2018-11-07 23:38 20% [PATCH] doc: update more URLs to use HTTPS and avoid redirects Eric Wong
2018-12-20 22:28  5% [ANN] unicorn 5.5.0.pre1 - Rack HTTP server for fast clients and Unix Eric Wong
2019-03-04  1:15  0% [ANN] unicorn 5.5.0 - Rack HTTP server for fast clients and Eric Wong
2019-04-15  6:52 20% [RFC] doc: unicorn_rails: clarify that it is intended for rails <= 2.x Eric Wong
2019-05-03 22:20     [PATCH] Rescue failed pipe resizes due to permissions sdemjanenko
2019-05-03 22:53  7% ` Eric Wong
2019-05-12 22:25     [PATCH 0/3] slow clients and test/benchmark tools Eric Wong
2019-05-12 22:25 10% ` [PATCH 1/3] test/benchmark/ddstream: demo for slowly reading clients Eric Wong
2019-05-12 22:25 10% ` [PATCH 2/3] test/benchmark/readinput: demo for slowly uploading clients Eric Wong
2019-07-04 22:01     [PATCH 0/3] http: use gperf for common field memoization Eric Wong
2019-07-04 22:01  5% ` [PATCH 2/3] http: use gperf for common fields optimization Eric Wong
2019-12-20  2:15  5% [ANN] unicorn 5.5.2 - Rack HTTP server for fast clients and *nix Eric Wong
2020-01-14  7:46 23% [PATCH] doc: s/bogomips.org/yhbt.net/g Eric Wong
2020-01-14  7:46 29% ` Eric Wong
2020-01-31 20:48  6% [ANN] unicorn 5.5.3 - Rack HTTP server for fast clients and *nix Eric Wong
2020-07-16 10:05     [PATCH] Add early hints support Jean Boussier
2020-07-16 10:50  6% ` Eric Wong
2020-07-16 11:41  4%   ` Jean Boussier
2020-07-16 12:16  0%     ` Eric Wong
2020-07-26  1:57     [PATCH 0/2] minor test improvements Eric Wong
2020-07-26  1:57  5% ` [PATCH 2/2] build: revamp and avoid unnecessary rebuilds Eric Wong
2021-10-01  3:09     [PATCH 0/6] reduce thundering herds on Linux 4.5+ Eric Wong
2021-10-01  3:09 16% ` [PATCH 3/6] HACKING: drop outdated information about pandoc Eric Wong
2021-12-25 17:41     [PATCH 0/3] Ruby 3.1 + doc/URL updates Eric Wong
2021-12-25 17:41 10% ` [PATCH 3/3] doc: v3 .onion updates, nntp => nntps, minor wording changes Eric Wong
2022-07-05 20:05     [PATCH] Master promotion with SIGURG (CoW optimization) Jean Boussier
2022-07-06  2:33  4% ` Eric Wong
2022-07-06  7:40  0%   ` Jean Boussier
2022-07-07 10:23  0%     ` Eric Wong
2023-06-01 18:54     Rack 3 Compatibility Jeremy Evans
2023-06-02  0:00     ` Eric Wong
2023-06-02  2:45       ` Jeremy Evans
2023-06-05  9:12 12%     ` [PATCH v2] chunk unterminated HTTP/1.1 responses for Rack 3.1 Eric Wong
2023-06-20 12:28 11% [PATCH] add chunk_response config directive for compatibility EW
2023-09-10 20:14  3% [PATCH] doc: various updates ahead of the release Eric Wong
2023-09-16 20:46  0% ` ideal.water4095
2024-03-23 19:45  4% [PATCH 0/4] a small pile of patches Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/unicorn.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).