* [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: favor ivars over constants
@ 2015-02-12 19:09 4% Eric Wong
0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2015-02-12 19:09 UTC (permalink / raw)
To: unicorn-public
In 1.9+ at least, instance variables use less space than constants
in class tables and bytecode, leading to ~700 byte reduction in
bytecode overhead on 64-bit and a reduction in constant table/entries
of the Unicorn::HttpServer class.
---
lib/unicorn/http_server.rb | 77 +++++++++++++++++++++-------------------------
1 file changed, 35 insertions(+), 42 deletions(-)
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index f0216d0..278b469 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -21,32 +21,12 @@ class Unicorn::HttpServer
include Unicorn::SocketHelper
include Unicorn::HttpResponse
- # backwards compatibility with 1.x
- Worker = Unicorn::Worker
-
# all bound listener sockets
LISTENERS = []
# listeners we have yet to bind
NEW_LISTENERS = []
- # This hash maps PIDs to Workers
- WORKERS = {}
-
- # We use SELF_PIPE differently in the master and worker processes:
- #
- # * 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
- #
- # * The workers immediately close the pipe they inherit. See the
- # Unicorn::Worker class for the pipe workers use.
- SELF_PIPE = []
-
- # signal queue used for self-piping
- SIG_QUEUE = []
-
# list of signals we care about and trap in master.
QUEUE_SIGS = [ :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
@@ -98,6 +78,19 @@ class Unicorn::HttpServer
self.config = Unicorn::Configurator.new(options)
self.listener_opts = {}
+ # We use @self_pipe differently in the master and worker processes:
+ #
+ # * 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
+ #
+ # * The workers immediately close the pipe they inherit. See the
+ # Unicorn::Worker class for the pipe workers use.
+ @self_pipe = []
+ @workers = {} # hash maps PIDs to Workers
+ @sig_queue = [] # signal queue used for self-piping
+
# we try inheriting listeners first, so we bind them later.
# we don't write the pid file until we've bound listeners in case
# unicorn was started twice by mistake. Even though our #pid= method
@@ -117,13 +110,13 @@ class Unicorn::HttpServer
inherit_listeners!
# 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)
+ @self_pipe.replace(Unicorn.pipe)
@master_pid = $$
# 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
@@ -276,7 +269,7 @@ class Unicorn::HttpServer
end
begin
reap_all_workers
- case SIG_QUEUE.shift
+ case @sig_queue.shift
when nil
# avoid murdering workers after our master process (or the
# machine) comes out of suspend/hibernation
@@ -335,7 +328,7 @@ class Unicorn::HttpServer
def stop(graceful = true)
self.listeners = []
limit = time_now + timeout
- until WORKERS.empty? || time_now > limit
+ until @workers.empty? || time_now > limit
if graceful
soft_kill_each_worker(:QUIT)
else
@@ -376,13 +369,13 @@ class Unicorn::HttpServer
# wait for a signal hander to wake us up and then consume the pipe
def master_sleep(sec)
- IO.select([ SELF_PIPE[0] ], nil, nil, sec) or return
- SELF_PIPE[0].kgio_tryread(11)
+ IO.select([ @self_pipe[0] ], nil, nil, sec) or return
+ @self_pipe[0].kgio_tryread(11)
end
def awaken_master
return if $$ != @master_pid
- SELF_PIPE[1].kgio_trywrite('.') # wakeup master process from select
+ @self_pipe[1].kgio_trywrite('.') # wakeup master process from select
end
# reaps all unreaped workers
@@ -396,7 +389,7 @@ class Unicorn::HttpServer
self.pid = pid.chomp('.oldbin') if pid
proc_name 'master'
else
- worker = WORKERS.delete(wpid) and worker.close rescue nil
+ 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)
end
@@ -465,7 +458,7 @@ class Unicorn::HttpServer
def murder_lazy_workers
next_sleep = @timeout - 1
now = time_now.to_i
- WORKERS.dup.each_pair do |wpid, worker|
+ @workers.dup.each_pair do |wpid, worker|
tick = worker.tick
0 == tick and next # skip workers that haven't processed any clients
diff = now - tick
@@ -483,7 +476,7 @@ class Unicorn::HttpServer
end
def after_fork_internal
- SELF_PIPE.each(&:close).clear # this is master-only, now
+ @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
@@ -498,11 +491,11 @@ class Unicorn::HttpServer
def spawn_missing_workers
worker_nr = -1
until (worker_nr += 1) == @worker_processes
- WORKERS.value?(worker_nr) and next
- worker = Worker.new(worker_nr)
+ @workers.value?(worker_nr) and next
+ worker = Unicorn::Worker.new(worker_nr)
before_fork.call(self, worker)
if pid = fork
- WORKERS[pid] = worker
+ @workers[pid] = worker
worker.atfork_parent
else
after_fork_internal
@@ -516,9 +509,9 @@ class Unicorn::HttpServer
end
def maintain_worker_count
- (off = WORKERS.size - worker_processes) == 0 and return
+ (off = @workers.size - worker_processes) == 0 and return
off < 0 and return spawn_missing_workers
- WORKERS.each_value { |w| w.nr >= worker_processes and w.soft_kill(:QUIT) }
+ @workers.each_value { |w| w.nr >= worker_processes and w.soft_kill(:QUIT) }
end
# if we get any error, try to write something back to the client
@@ -597,13 +590,13 @@ class Unicorn::HttpServer
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]
+ exit!(0) if (@sig_queue & EXIT_SIGS)[0]
WORKER_QUEUE_SIGS.each { |sig| trap(sig, nil) }
trap(:CHLD, 'DEFAULT')
- SIG_QUEUE.clear
+ @sig_queue.clear
proc_name "worker[#{worker.nr}]"
START_CTX.clear
- WORKERS.clear
+ @workers.clear
after_fork.call(self, worker) # can drop perms and create listeners
LISTENERS.each { |sock| sock.close_on_exec = true }
@@ -683,17 +676,17 @@ class Unicorn::HttpServer
# is no longer running.
def kill_worker(signal, wpid)
Process.kill(signal, wpid)
- rescue Errno::ESRCH
- worker = WORKERS.delete(wpid) and worker.close rescue nil
+ rescue Errno::ESRCH
+ worker = @workers.delete(wpid) and worker.close rescue nil
end
# delivers a signal to each worker
def kill_each_worker(signal)
- WORKERS.keys.each { |wpid| kill_worker(signal, wpid) }
+ @workers.keys.each { |wpid| kill_worker(signal, wpid) }
end
def soft_kill_each_worker(signal)
- WORKERS.each_value { |worker| worker.soft_kill(signal) }
+ @workers.each_value { |worker| worker.soft_kill(signal) }
end
# unlinks a PID file at given +path+ if it contains the current PID
--
EW
^ permalink raw reply related [relevance 4%]
Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2015-02-12 19:09 4% [PATCH] http_server: favor ivars over 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).