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: |
* [ANN] unicorn 4.7.0 - minor updates, license tweak
@ 2013-11-04  7:57  5% Eric Wong
  0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2013-11-04  7:57 UTC (permalink / raw)
  To: mongrel-unicorn

* git://bogomips.org/unicorn.git
* http://unicorn.bogomips.org/NEWS.atom.xml

Changes:

* support SO_REUSEPORT on new listeners (:reuseport)

This allows users to start an independent instance of unicorn on
a the same port as a running unicorn (as long as both instances
use :reuseport).

ref: https://lwn.net/Articles/542629/

* unicorn is now GPLv2-or-later and Ruby 1.8-licensed
(instead of GPLv2-only, GPLv3-only, and Ruby 1.8-licensed)

This changes nothing at the moment.  Once the FSF publishes the next
version of the GPL, users may choose the newer GPL version without the
unicorn BDFL approving it.  Two years ago when I got permission to add
GPLv3 to the license options, I also got permission from all past
contributors to approve future versions of the GPL.  So now I'm
approving all future versions of the GPL for use with unicorn.

Reasoning below:

In case the GPLv4 arrives and I am not alive to approve/review it,
the lesser of evils is have give blanket approval of all future GPL
versions (as published by the FSF).  The worse evil is to be stuck
with a license which cannot guarantee the Free-ness of this project
in the future.

This unfortunately means the FSF can theoretically come out with
license terms I do not agree with, but the GPLv2 and GPLv3 will
always be an option to all users.

Note: we currently prefer GPLv3

Two improvements thanks to Ernest W. Durbin III:

* USR2 redirects fixed for Ruby 1.8.6 (broken since 4.1.0)
* unicorn(1) and unicorn_rails(1) enforces valid integer for -p/--port

A few more odd, minor tweaks and fixes:

* attempt to rename PID file when possible (on USR2)
* workaround reopen atomicity issues for stdio vs non-stdio
* improve handling of client-triggerable socket errors

-- 
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 5%]

* Re: [PATCH] support SO_REUSEPORT on new listeners (:reuseport)
  2013-10-25 20:34  5% [PATCH] support SO_REUSEPORT on new listeners (:reuseport) Eric Wong
@ 2013-10-25 20:49 14% ` Eric Wong
  0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2013-10-25 20:49 UTC (permalink / raw)
  To: mongrel-unicorn

Eric Wong <normalperson@yhbt.net> wrote:
> This allows users to start an independent instance of unicorn on
> a the same port as a running unicorn (as long as both instances
> use :reuseport).
> 
> ref: https://lwn.net/Articles/542629/
> ---

Also pushed out a couple of trivial IO_PURGATORY-related fixes to
support this.  We'll drop 1.8 support one of these days.

commit e025cd99beee500f175a3bcc302a1307b39ffb77
Author: Eric Wong <e@80x24.org>
Date:   Fri Oct 25 19:45:15 2013 +0000

    avoid IO_PURGATORY on Ruby 1.9+
    
    Ruby 1.9 and later includes IO#autoclose=, so we can use it
    and prevent some dead IO objects from hanging around.

commit 7c125886b5862bf20711bae22e6697ad46141434
Author: Eric Wong <e@80x24.org>
Date:   Fri Oct 25 19:27:05 2013 +0000

    support SO_REUSEPORT on new listeners (:reuseport)
    
    This allows users to start an independent instance of unicorn on
    a the same port as a running unicorn (as long as both instances
    use :reuseport).
    
    ref: https://lwn.net/Articles/542629/

commit 1dc099228ee0f59c13385a3e7346a2cb37d85153
Author: Eric Wong <e@80x24.org>
Date:   Fri Oct 25 19:54:39 2013 +0000

    tests: limit oobgc check to accepted sockets
    
    Otherwise these tests fail if we start using IO#autoclose=true
    on Ruby 1.9 (and also if we use IPv6 sockets for tests).
_______________________________________________
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 14%]

* [PATCH] support SO_REUSEPORT on new listeners (:reuseport)
@ 2013-10-25 20:34  5% Eric Wong
  2013-10-25 20:49 14% ` Eric Wong
  0 siblings, 1 reply; 3+ results
From: Eric Wong @ 2013-10-25 20:34 UTC (permalink / raw)
  To: mongrel-unicorn

This allows users to start an independent instance of unicorn on
a the same port as a running unicorn (as long as both instances
use :reuseport).

ref: https://lwn.net/Articles/542629/
---
 lib/unicorn/configurator.rb     | 19 +++++++++++++++++++
 lib/unicorn/socket_helper.rb    | 30 ++++++++++++++++++++++--------
 test/unit/test_socket_helper.rb |  8 ++++++++
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 0d0eac7..fc3405a 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -319,6 +319,25 @@ class Unicorn::Configurator
   #
   #   Default: Operating-system dependent
   #
+  # [:reuseport => true or false]
+  #
+  #   This enables multiple, independently-started unicorn instances to
+  #   bind to the same port (as long as all the processes enable this).
+  #
+  #   This option must be used when unicorn first binds the listen socket.
+  #   It cannot be enabled when a socket is inherited via SIGUSR2
+  #   (but it will remain on if inherited), and it cannot be enabled
+  #   directly via SIGHUP.
+  #
+  #   Note: there is a chance of connections being dropped if
+  #   one of the unicorn instances is stopped while using this.
+  #
+  #   This is supported on *BSD systems and Linux 3.9 or later.
+  #
+  #   ref: https://lwn.net/Articles/542629/
+  #
+  #   Default: false (unset)
+  #
   # [:tries => Integer]
   #
   #   Times to retry binding a socket if it is already in use
diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb
index 18b0be7..2701d58 100644
--- a/lib/unicorn/socket_helper.rb
+++ b/lib/unicorn/socket_helper.rb
@@ -41,6 +41,15 @@ module Unicorn
 
       # do not send out partial frames (Linux)
       TCP_CORK = 3 unless defined?(TCP_CORK)
+
+      # Linux got SO_REUSEPORT in 3.9, BSDs have had it for ages
+      unless defined?(SO_REUSEPORT)
+        if RUBY_PLATFORM =~ /(?:alpha|mips|parisc|sparc)/
+          SO_REUSEPORT = 0x0200 # untested
+        else
+          SO_REUSEPORT = 15 # only tested on x86_64 and i686
+        end
+      end
     when /freebsd/
       # do not send out partial frames (FreeBSD)
       TCP_NOPUSH = 4 unless defined?(TCP_NOPUSH)
@@ -142,9 +151,9 @@ module Unicorn
           File.umask(old_umask)
         end
       elsif /\A\[([a-fA-F0-9:]+)\]:(\d+)\z/ =~ address
-        new_ipv6_server($1, $2.to_i, opt)
+        new_tcp_server($1, $2.to_i, opt.merge(:ipv6=>true))
       elsif /\A(\d+\.\d+\.\d+\.\d+):(\d+)\z/ =~ address
-        Kgio::TCPServer.new($1, $2.to_i)
+        new_tcp_server($1, $2.to_i, opt)
       else
         raise ArgumentError, "Don't know how to bind: #{address}"
       end
@@ -152,13 +161,18 @@ module Unicorn
       sock
     end
 
-    def new_ipv6_server(addr, port, opt)
-      opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port)
-      defined?(IPV6_V6ONLY) or
-        abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS"
-      sock = Socket.new(AF_INET6, SOCK_STREAM, 0)
-      sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0)
+    def new_tcp_server(addr, port, opt)
+      # n.b. we set FD_CLOEXEC in the workers
+      sock = Socket.new(opt[:ipv6] ? AF_INET6 : AF_INET, SOCK_STREAM, 0)
+      if opt.key?(:ipv6only)
+        defined?(IPV6_V6ONLY) or
+          abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS"
+        sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0)
+      end
       sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+      if defined?(SO_REUSEPORT) && opt[:reuseport]
+        sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
+      end
       sock.bind(Socket.pack_sockaddr_in(port, addr))
       IO_PURGATORY << sock
       Kgio::TCPServer.for_fd(sock.fileno)
diff --git a/test/unit/test_socket_helper.rb b/test/unit/test_socket_helper.rb
index a38082c..abc177b 100644
--- a/test/unit/test_socket_helper.rb
+++ b/test/unit/test_socket_helper.rb
@@ -184,4 +184,12 @@ class TestSocketHelper < Test::Unit::TestCase
     assert_equal 1, cur
     rescue Errno::EAFNOSUPPORT
   end if RUBY_VERSION >= "1.9.2"
+
+  def test_reuseport
+    port = unused_port @test_addr
+    name = "#@test_addr:#{port}"
+    sock = bind_listen(name, :reuseport => true)
+    cur = sock.getsockopt(Socket::SOL_SOCKET, SO_REUSEPORT).unpack('i')[0]
+    assert_equal 1, cur
+  end if defined?(SO_REUSEPORT)
 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 5%]

Results 1-3 of 3 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2013-10-25 20:34  5% [PATCH] support SO_REUSEPORT on new listeners (:reuseport) Eric Wong
2013-10-25 20:49 14% ` Eric Wong
2013-11-04  7:57  5% [ANN] unicorn 4.7.0 - minor updates, license tweak 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).