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 5.0.0.pre1 - incompatible changes!
@ 2015-06-15 22:56  7% Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2015-06-15 22:56 UTC (permalink / raw)
  To: unicorn-public

This release finally drops Ruby 1.8 support and requires Ruby 1.9.3
or later.  The horrible "Status:" header in our HTTP response is
finally gone, saving at least 16 precious bytes in every single HTTP
response.

Under Ruby 2.1 and later, the monotonic clock is used for timeout
handling for better accuracy.

Several experimental, unused and undocumented features are removed.

There's also tiny, minor performance and memory improvements from
dropping 1.8 compatibility, but probably nothing noticeable on a
typical real-life (bloated) app.

The biggest performance improvement we made was to our website by
switching to olddoc.  Depending on connection speed, latency, and
renderer performance, it typically loads two to four times faster.

Finally, for the billionth time: unicorn must never be exposed
to slow clients, as it will never ever use new-fangled things
like non-blocking socket I/O, threads, epoll or kqueue.  unicorn
must be used with a fully-buffering reverse proxy such as nginx
for slow clients.

I'll tag 5.0.0 final in a week or so if all goes well

= gem install --pre unicorn
= git clone git://bogomips.org/unicorn.git
= http://unicorn.bogomips.org/

* ISSUES: update with mailing list subscription
* GIT-VERSION-GEN: start 5.0.0 development
* http: remove xftrust options
* FAQ: add entry for Rails autoflush_log
* dev: remove isolate dependency
* unicorn.gemspec: depend on test-unit 3.0
* http_response: remove Status: header
* remove RubyForge and Freecode references
* remove mongrel.rubyforge.org references
* http: remove the keepalive requests limit
* http: reduce parser from 72 to 56 bytes on 64-bit
* examples: add run_once to before_fork hook example
* worker: remove old tmp accessor
* http_server: save 450+ bytes of memory on x86-64
* t/t0002-parser-error.sh: relax test for rack 1.6.0
* remove SSL support
* tmpio: drop the "size" method
* switch docs + website to olddoc
* README: clarify/reduce references to unicorn_rails
* gemspec: fixup olddoc migration
* use the monotonic clock under Ruby 2.1+
* http: -Wshorten-64-to-32 warnings on clang
* remove old inetd+git examples and exec_cgi
* http: standalone require + reduction in binary size
* GNUmakefile: fix clean gem build + reduce build cruft
* socket_helper: reduce constant lookups and caching
* remove 1.8, <= 1.9.1 fallback for missing IO#autoclose=
* favor IO#close_on_exec= over fcntl in 1.9+
* use require_relative to reduce syscalls at startup
* doc: update support status for Ruby versions
* fix uninstalled testing and reduce require paths
* test_socket_helper: do not depend on SO_REUSEPORT
* favor "a.b(&:c)" form over "a.b { |x| x.c }"
* ISSUES: add section for bugs in other projects
* http_server: favor ivars over constants
* explain 11 byte magic number for self-pipe
* const: drop constants used by Rainbows!
* reduce and localize constant string use
* Links: mark Rainbows! as historical, reference yahns
* save about 200 bytes of memory on x86-64
* http: remove deprecated reset method
* http: remove experimental dechunk! method
* socket_helper: update comments
* doc: document UNICORN_FD in manpage
* doc: document Etc.nprocessors for worker_processes
* favor more string literals for cold call sites
* tee_input: support for Rack::TempfileReaper middleware
* support TempfileReaper in deployment and development envs
* favor kgio_wait_readable for single FD over select
* Merge tag 'v4.9.0'
* http_request: support rack.hijack by default
* avoid extra allocation for hijack proc creation
* FAQ: add note about ECONNRESET errors from bodies
* process SIGWINCH unless stdin is a TTY
* ISSUES: discourage HTML mail strongly, welcome nyms
* http: use rb_hash_clear in Ruby 2.0+
* http_response: avoid special-casing for Rack < 1.5
* www: install NEWS.atom.xml properly
* http_server: remove a few more accessors and constants
* http_response: simplify regular expression
* move the socket into Rack env for hijacking
* http: move response_start_sent into the C ext
* FAQ: reorder bit on Rack 1.1.x and Rails 2.3.x
* ensure body is closed during hijack

-- 
EW

^ permalink raw reply	[relevance 7%]

* [PATCH] http_server: remove a few more accessors and constants
@ 2015-06-04  1:39  7% Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2015-06-04  1:39 UTC (permalink / raw)
  To: unicorn-public; +Cc: Eric Wong

Unnecessarily exposed accessors and constants take up unnecessary
memory in constant/method tables as well as using extra space in
instruction sequences.

Preforking servers like unicorn are a bloated pigs anyways,
but saving a few hundred bytes here and there can add up and
make them marginally less bad.
---
 lib/unicorn/http_server.rb | 52 ++++++++++++++++++++++------------------------
 test/test_helper.rb        |  5 +++--
 2 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index cf8e122..2657c29 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -11,25 +11,23 @@
 # See Unicorn::Configurator for information on how to configure \Unicorn.
 class Unicorn::HttpServer
   # :stopdoc:
-  attr_accessor :app, :request, :timeout, :worker_processes,
+  attr_accessor :app, :timeout, :worker_processes,
                 :before_fork, :after_fork, :before_exec,
                 :listener_opts, :preload_app,
-                :reexec_pid, :orig_app, :init_listeners,
-                :master_pid, :config, :ready_pipe, :user
+                :orig_app, :config, :ready_pipe, :user
 
   attr_reader :pid, :logger
   include Unicorn::SocketHelper
   include Unicorn::HttpResponse
 
   # all bound listener sockets
+  # note: this is public used by raindrops, but not recommended for use
+  # in new projects
   LISTENERS = []
 
   # listeners we have yet to bind
   NEW_LISTENERS = []
 
-  # list of signals we care about and trap in master.
-  QUEUE_SIGS = [ :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
-
   # :startdoc:
   # We populate this at startup so we can figure out how to reexecute
   # and upgrade the currently running instance of Unicorn
@@ -70,7 +68,7 @@ class Unicorn::HttpServer
   def initialize(app, options = {})
     @app = app
     @request = Unicorn::HttpRequest.new
-    self.reexec_pid = 0
+    @reexec_pid = 0
     options = options.dup
     @ready_pipe = options.delete(:ready_pipe)
     @init_listeners = options[:listeners] ? options[:listeners].dup : []
@@ -102,7 +100,10 @@ class Unicorn::HttpServer
     # monitoring tools may also rely on pid files existing before we
     # attempt to connect to the listener(s)
     config.commit!(self, :skip => [:listeners, :pid])
-    self.orig_app = app
+    @orig_app = app
+    # list of signals we care about and trap in master.
+    @queue_sigs = [
+      :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
   end
 
   # Runs the thing.  Returns self so you can run join on it
@@ -116,7 +117,7 @@ class Unicorn::HttpServer
     # setup signal handlers before writing pid file in case people get
     # trigger happy and send signals as soon as the pid file exists.
     # Note that signals don't actually get handled until the #join method
-    QUEUE_SIGS.each { |sig| trap(sig) { @sig_queue << sig; awaken_master } }
+    @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
@@ -186,7 +187,7 @@ class Unicorn::HttpServer
     if path
       if x = valid_pid?(path)
         return path if pid && path == pid && x == $$
-        if x == reexec_pid && pid.end_with?('.oldbin')
+        if x == @reexec_pid && pid.end_with?('.oldbin')
           logger.warn("will not set pid=#{path} while reexec-ed "\
                       "child is running PID:#{x}")
           return
@@ -387,9 +388,9 @@ class Unicorn::HttpServer
     begin
       wpid, status = Process.waitpid2(-1, Process::WNOHANG)
       wpid or return
-      if reexec_pid == wpid
+      if @reexec_pid == wpid
         logger.error "reaped #{status.inspect} exec()-ed"
-        self.reexec_pid = 0
+        @reexec_pid = 0
         self.pid = pid.chomp('.oldbin') if pid
         proc_name 'master'
       else
@@ -404,13 +405,13 @@ class Unicorn::HttpServer
 
   # reexecutes the START_CTX with a new binary
   def reexec
-    if reexec_pid > 0
+    if @reexec_pid > 0
       begin
-        Process.kill(0, reexec_pid)
-        logger.error "reexec-ed child already running PID:#{reexec_pid}"
+        Process.kill(0, @reexec_pid)
+        logger.error "reexec-ed child already running PID:#@reexec_pid"
         return
       rescue Errno::ESRCH
-        self.reexec_pid = 0
+        @reexec_pid = 0
       end
     end
 
@@ -428,7 +429,7 @@ class Unicorn::HttpServer
       end
     end
 
-    self.reexec_pid = fork do
+    @reexec_pid = fork do
       listener_fds = {}
       LISTENERS.each do |sock|
         sock.close_on_exec = false
@@ -576,9 +577,6 @@ class Unicorn::HttpServer
     handle_error(client, e)
   end
 
-  EXIT_SIGS = [ :QUIT, :TERM, :INT ]
-  WORKER_QUEUE_SIGS = QUEUE_SIGS - EXIT_SIGS
-
   def nuke_listeners!(readers)
     # only called from the worker, ordering is important here
     tmp = readers.dup
@@ -593,9 +591,10 @@ class Unicorn::HttpServer
   def init_worker_process(worker)
     worker.atfork_child
     # we'll re-trap :QUIT later for graceful shutdown iff we accept clients
-    EXIT_SIGS.each { |sig| trap(sig) { exit!(0) } }
-    exit!(0) if (@sig_queue & EXIT_SIGS)[0]
-    WORKER_QUEUE_SIGS.each { |sig| trap(sig, nil) }
+    exit_sigs = [ :QUIT, :TERM, :INT ]
+    exit_sigs.each { |sig| trap(sig) { exit!(0) } }
+    exit!(0) if (@sig_queue & exit_sigs)[0]
+    (@queue_sigs - exit_sigs).each { |sig| trap(sig, nil) }
     trap(:CHLD, 'DEFAULT')
     @sig_queue.clear
     proc_name "worker[#{worker.nr}]"
@@ -629,7 +628,7 @@ class Unicorn::HttpServer
   # for connections and doesn't die until the parent dies (or is
   # given a INT, QUIT, or TERM signal)
   def worker_loop(worker)
-    ppid = master_pid
+    ppid = @master_pid
     readers = init_worker_process(worker)
     nr = 0 # this becomes negative if we need to reopen logs
 
@@ -723,7 +722,7 @@ class Unicorn::HttpServer
     config.commit!(self)
     soft_kill_each_worker(:QUIT)
     Unicorn::Util.reopen_logs
-    self.app = orig_app
+    self.app = @orig_app
     build_app! if preload_app
     logger.info "done reloading config_file=#{config.config_file}"
   rescue StandardError, LoadError, SyntaxError => e
@@ -788,9 +787,8 @@ class Unicorn::HttpServer
   # call only after calling inherit_listeners!
   # This binds any listeners we did NOT inherit from the parent
   def bind_new_listeners!
-    NEW_LISTENERS.each { |addr| listen(addr) }
+    NEW_LISTENERS.each { |addr| listen(addr) }.clear
     raise ArgumentError, "no listeners" if LISTENERS.empty?
-    NEW_LISTENERS.clear
   end
 
   # try to use the monotonic clock in Ruby >= 2.1, it is immune to clock
diff --git a/test/test_helper.rb b/test/test_helper.rb
index c4fe07a..c21f75d 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -292,6 +292,7 @@ def chunked_spawn(stdout, *cmd)
 end
 
 def reset_sig_handlers
-  sigs = %w(CHLD).concat(Unicorn::HttpServer::QUEUE_SIGS)
-  sigs.each { |sig| trap(sig, "DEFAULT") }
+  %w(WINCH QUIT INT TERM USR1 USR2 HUP TTIN TTOU CHLD).each do |sig|
+    trap(sig, "DEFAULT")
+  end
 end
-- 
EW


^ permalink raw reply related	[relevance 7%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2015-06-04  1:39  7% [PATCH] http_server: remove a few more accessors and constants Eric Wong
2015-06-15 22:56  7% [ANN] unicorn 5.0.0.pre1 - incompatible changes! 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).