Date | Commit message (Collapse) |
|
|
|
We don't need these dependencies slowing down load times
on our tests..
|
|
Reset connections can also return EPIPE under Linux, not just
ECONNRESET; so be sure to trap that error, too.
|
|
Prevent the GC from trying to close it (and hitting the wrong
descriptor) when @random is reopened for running tests.
|
|
The Rack spec requires it. So we'll just set it to "localhost"
if we're dealing with HTTP/1.0 clients that omit the "Host:"
header.
|
|
It was mistakenly set to false before, which breaks Rack::Lint.
As the Rack SPEC doesn't require it, don't bother setting it at
all and save a few bytes of memory.
|
|
This also fixes a subtle bug in header generation when the +$,+
($OFS) variable is defined to something other than nil or ""
I'm really wondering what kind of drugs I was on (or _not_ on)
when I modified some of this from the Mongrel source.
|
|
Rack spec specifies #each must be defined, not #each_pair.
Hash#each_pair was marginally faster in Ruby 1.8, but in Ruby
1.9.1, Hash#each and Hash#each_pair are the same function.
|
|
Since dying children can be a sign that something is wrong with
the app itself, continue to use the 1 wakeup/sec throttle and
don't wake the master immediately.
|
|
And avoid repeatedly sending kill -0 to each worker,
that nugget of stupid probably slipped in while I was
testing something...
|
|
|
|
Ruby 1.9 Tempfile objects can be passed directly to File.rename
(instead of the pathname). This doesn't work in 1.8, so always
just pass the pathname to File.rename.
|
|
Tempfile reuse was over-engineered and the problem was not
nearly as big a problem as initially thought.
Additionally, it could lead to a subtle bug in an applications
that link(2)s or rename(2)s the temporary file to a permanent
location _without_ closing it after the request is done.
Applications that suffer from the problem of directory bloat are
still free to modify ENV['TMPDIR'] to influence the creation of
Tempfiles.
|
|
unused_port is more reliable as it actually tries to bind
a port and retries if it fails. This is also safe across
parallel unicorn tests running in different directories.
|
|
|
|
|
|
This is to make things consistent with the other logging
when adding listeners
|
|
|
|
This can be overridden in {after,before}_fork hooks
of course; but makes things look a little nicer.
|
|
|
|
Add a make task for updating it, too.
|
|
This allows changing certain variables without restarting the
master process or code reload. Currently, only the following
variables are supported: @timeout, @nr_workers, @hot_config_file.
Any other config changes will/should require re-executing the
running binary. This config file is run through eval(); so it
really users plenty of rope to hang themselves with. Of course,
it requires valid Ruby syntax:
------------------------- 8< ------------------------
@nr_workers = 8
@timeout = 15
@hot_config_file = "/var/tmp/new_hot_config_file"
------------------------- 8< ------------------------
Lowering the timeout will trigger all existing workers to be
gracefully stopped and restarted.
This file is loaded at startup, and overrides any config
settings that may already be loaded.
|
|
This controls the backlog argument to the listen(2) system call.
See your operating system documentation for listen(2) on the
specifics of this option.
The default is 1024, which is the same as Mongrel. 5 is the
default for Ruby TCPServer and UNIXServer; and in some case it
can be better where failover to a different machine/cluster
is properly configured.
|
|
|
|
* IO.pipe.map { } looks moronic, especially without
doing more inside it (like setting set_cloexec).
* No need to sleep when we have an unhandled master
loop exception (save for paranoia).
* client.class == TCPSocket is slightly more expensive
than TCPSocket === client
* nilify client to avoid GC from trying to close it
* Process.kill => kill
|
|
These files are unlinked immediately anyways, so
it's wasteful to give them a long name...
|
|
Don't rely on FD_CLOEXEC if we don't have to since it may not be
completely portable. Just explicitly close things (pipes,
tempfiles) we don't want to pass on to our children when
forking.
|
|
This makes it possible to bind per-process listener ports for
easier debugging. One of my biggest gripes about other prefork
webservers is that strace-ing the correct process for debugging
is difficult. This makes it possible for each worker to bind to
a unique port or UNIX socket independent of the other workers.
|
|
Workers have no business knowing these things...
|
|
Daemonization only happens once at initial startup and is less
intrusive than traditional daemonize routines: we do not chdir,
set umask, or redirect/close STDOUT/STDERR since those are
doable via other config options with Unicorn (and the Unicorn
"config file" is just Ruby).
STDIN has no business being open on a daemon (and can be
dangerous to close if using certain buggy third-party libs).
|
|
If we're running in the foreground and don't care for process
manglement, then there's no need to start a pipe we won't need.
|
|
Like nginx, we'll replace the existing "pid_file" with
"pid_file.oldbin" when executing a new binary. We'll also
refuse to reexecute a new binary if the ".oldbin" pid file
already exists and points to a valid PID.
|
|
We may have stale UNIX sockets leftover since we don't clean
those up at_exit. So unlink them if we didn't inherit one.
|
|
|
|
The timeout mechanism is implemented via shared tempfile handles
between the worker and master and checking the ctime of the
tempfile from the master. Instead of using sockets or pipes to
communicate between the workers and master, this allows the
master to avoid being overloaded with wakeups when the workers
are running at full crank (or this avoids having extra logic in
workers to throttle wakeup notifications to master).
The master still wakes up at a leisurely interval of once per
second to check, reap, or murder workers that are timed out.
[1] http://cr.yp.to/docs/selfpipe.html
|
|
This implements the self-pipe trick[1] to wakeup the master
process when signaled. We still wakeup every second to reap
workers and eventually check for timed out workers.
[1] http://cr.yp.to/docs/selfpipe.html
|
|
We'll be using this flag with a pipe, too.
|
|
Along with worker process management. This is nginx-style
inplace upgrading (I don't know of another web server that does
this). Basically we can preserve our opened listen sockets
across entire executable upgrades.
Signals:
USR2 - Sending USR2 to the master unicorn process will cause
it to exec a new master and keep the original workers running.
This is useful to validate that the new code changes took place
are valid and don't immediately die. Once the changes are
validated (manually), you may send QUIT to the original
master process to have it gracefully exit.
HUP - Sending this to the master will make it immediately exec
a new binary and cause the old workers to gracefully exit.
Use this if you're certain the latest changes to Unicorn (and
your app) are ready and don't need validating.
Unlike nginx, re-execing a new binary will pick up any and all
configuration changes. However listener sockets cannot be
removed when exec-ing; only added (for now).
I apologize for making such a big change in one commit, but once
I got the ability to replace the entire codebase while preserving
connections, it was too tempting to continue working.
So I wrote a large chunk of this while hitting
the unicorn-hello-world app with the following loop:
while curl -vSsfN http://0:8080; do date +%N; done
_Zero_ requests lost across multiple restarts.
|
|
Makes it much easier to track down failures if you know
something failed in the first place. A failed test early on
could be hidden because noise from successful tests drowned it
out.
|
|
Avoid needless userspace copies and craziness. We'll need to
handle EINTR since writes to sockets means stupid things like
this, but it's a small cost...
|
|
Since we handle signals, read(2) syscalls can fail on sockets
with EINTR. Restart the call if we hit this.
|
|
Keeping I/O out of unicorn.rb
|
|
I'll be removing signal handling from worker processes...
|
|
We're not using them and they don't seem useful in any
shape or form...
|
|
This allows us to avoid the overhead of allocating a new buffer
each and every time we call sysread (even when just parsing
headers for GET requests).
|
|
Unicorn is only designed for fast internal networks (and
loopback); so avoid wasting time with userspace I/O buffering.
This should not significantly affect userspace threading on 1.8
in case your application itself is running threads for some
(masochistic) reason as long as the clients you're serving
directly with Unicorn are fast.
|
|
Instead of ".#{$$}" as the suffix. This makes it clearer that
it's a temporary name and also so we can use per-process sockets
to make debugging easier.
|
|
We're not currently using them; and I don't see the need to
ever use either...
|
|
Note: since we've stripped everything down to hell, we're Ruby
1.9 compatible at the moment. Also remove references to that
new school stuff like JRuby and threads.
|
|
Running Rake is too slow for me to do builds on, and
I don't have net access to install the Echoe gem at
the moment for Ruby 1.9...
|