Date | Commit message (Collapse) |
|
It's too complicated and error-prone to allow apps to use a
different version of Rack than the one Unicorn would otherwise
use by default.
If an app requires a different version of Rack than what Unicorn
would load by default, it is recommended they only install that
version of Rack (and no others) since Unicorn does not have any
strict requirements on currently released Rack versions.
If it is not possible to only have one Rack version installed
globally, then they should either use Isolate or Bundler and
install a private version of Unicorn along with their preferred
version of Rack. Users who install in this way are recommended
to execute the isolated/bundled version of Unicorn, instead of
what would normally be in $PATH.
Feedback/tips to mailto:mongrel-unicorn@rubyforge.org from
Isolate and Bundler users would be greatly appreciated.
|
|
This is useful as a :listeners argument when setting up
Raindrops::Middleware (http://raindrops.bogomips.org/),
as it can be done automatically.
|
|
Trying to fix this issue again, as it seems to have been broken
again.
|
|
There is no need to be using autoload except for HttpResponse
which depends on Rack (which we want to load as late as
possible).
|
|
This will help ensure we use the same version of Rack the
application uses and avoid loading conflicting/incompatible
versions.
|
|
It's part of the standard Ruby library and will always be loaded
by various modules (Rack::Utils, Tmpdir) so there's no point in
deferring it.
|
|
Allowing the "user" directive outside of after_fork reduces the
cognitive overhead for folks that do not need the complexity of
*_fork hooks. Using Worker#user remains supported as it offers
fine-grained control of user switching.
|
|
Do not assume the user wants config.ru to be Encoding::BINARY
for 1.9.
|
|
This lets us reuse code for Zbatery and Rainbows!, too.
|
|
This should make it easier to reuse code in derivative
servers like Rainbows! and Zbatery. Unfortunately, we
can't depend on Rack::Builder/Rack::Server yet since
Rack 1.1 just got them and notable frameworks (like
Rails 2.3.x) do not fully work with Rack 1.1 yet).
This also fixes subtle issue with config.ru files that could
have variables that conflict with the Unicorn-specific
namespace (this bug still affects "unicorn_rails", which
could use some reworking as well).
|
|
If preload_app is true and Unicorn is HUP-ed with a bad
config.ru, then it would be possible to have Unicorn in a bad
state and constantly throw 500 errors.
We now detect syntax and load errors since they're likely to
appear in modified Rackup files, and will restore the original
app if reloading failed.
|
|
Earlier elements of a Struct (in both Ruby and C) are faster
to access, so put more-often accessed elements like :app first.
This does not noticeably affect most applications, but may
matter to some micro benchmarks somewhere...
|
|
This prevents trigger-happy init scripts from reading the pid
file (and thus sending signals) to a not-fully initialized
master process to handle them.
This does NOT fix anything if other processes are sending
signals prematurely without relying on the presence of the pid
file. It's not possible to prevent all cases of this in one
process, even in a purely C application, so we won't bother
trying.
We continue to always defer signal handling to the main loop
anyways, and signals sent to the master process will be
deferred/ignored until Unicorn::HttpServer#join is run.
|
|
* rack-1.1:
http_response: disallow blank, multi-value headers
local.mk.sample: use rack-1.1.0
bump "rack.version" env to [1,1]
set env["rack.logger"] for applications
|
|
When using multiple listeners, the log messages can be
potentially misleading as to which listener fails to bind:
Before:
INFO -- : unlinking existing socket=/tmp/unicorn.sock
INFO -- : listening on addr=/tmp/unicorn.sock fd=3
unicorn/socket_helper.rb:110:in `initialize': Permission denied - bind(2) (Errno::EACCES)
After:
INFO -- : unlinking existing socket=/tmp/openxdms.sock
INFO -- : listening on addr=/tmp/openxdms.sock fd=3
FATAL -- : error adding listener addr=0.0.0.0:84
unicorn/socket_helper.rb:110:in `initialize': Permission denied - bind(2) (Errno::EACCES)
|
|
Otherwise the original spawner process may not notice the close
as it's still being shared by workers. While we're at it, avoid
confusing the original spawner by using readpartial instead of
sysread.
|
|
This behavior change also means our grandparent (launched
from a controlling terminal or script) will wait until
the master process is ready before returning.
Thanks to IƱaki Baz Castillo for the initial implementations
and inspiration.
|
|
rack.git upstream has it, so it will likely be in Rack 1.1
|
|
Durr....
|
|
A minor nit, and some folks I know hate needless returns
as MRI does not optimize them away.
|
|
|
|
"Object" is needless noise and some folks are annoyed by
seeing it.
|
|
This is only supported when SIGUSR1 is sent only to the master
process (which then resends SIGUSR1 to the workers).
Since we only added support for user/group switching in the
workers, we now chown any log files upon switching users so the
master can pick up and chown the log files later on. Thus
we can avoid having to restart workers because they fail to
rotate log files on their own.
|
|
Leaving the EOFError exception as-is bad because most
applications/frameworks run an application-wide exception
handler to pretty-print and/or log the exception with a huge
backtrace.
Since there's absolutely nothing we can do in the server-side
app to deal with clients prematurely shutting down, having a
backtrace does not make sense. Having a backtrace can even be
harmful since it creates unnecessary noise for application
engineers monitoring or tracking down real bugs.
|
|
This will benefit users of a copy-on-write-friendly memory
manager provided with Ruby Enterprise Edition. Additionally,
this will the reduce maintenance impact on Rainbows! in the future
since load/require are not thread-safe under 1.9.
|
|
Sometimes app loads and after_fork hooks can take a long time,
even longer than shorter timeouts. Since timeouts are only
meant for application processing when clients are involved,
we won't nuke workers that have never chmodded before.
|
|
Constant scoping appears to be a bit different under 1.9
|
|
This must be called in the after_fork hook because there may be
Ruby modules that'll allow things such as CPU affinity and
scheduling class/priority to be set on a per-worker basis. So
we give the user the ability to change users at any time during
the after_fork hook.
|
|
Even if START_CTX[:cwd] is pointing to another directory,
avoid overriding the user's decision to Dir.chdir if they
do it in either the Unicorn config file or the config.ru.
|
|
split out uncommon code from the common path
|
|
`sh -c pwd` doesn't reliably read ENV["PWD"] on all platforms,
this means that directories that are symlinks may be ignored
and the real path is resolved. This can be problematic when
doing upgrades for common deployment systems such as Capistrano
which rely on the working directory being a symlink.
|
|
If fstat() fails on an open file descriptor in the master,
something is seriously wrong (like your kernel is broken/buggy)
and trying to restart the worker that owned that file descriptor
is likely masking the symptoms. Instead let the error propagate
up to the main loop to avoid wasting cycles to restart broken
workers.
|
|
The method introduced in commit
6c8a3d3c55997978bacaecc5dbbb7d03c2fee345 to avoid killing
workers after suspend/hibernate interacted badly with the change
for OpenBSD fchmod(2) compatibility introduced with the 0.93.3
release. This interaction lead to workers with files stuck in
the zero state to never be murdered off for timeout violations.
Additionally, the method to avoid killing processes off was
never completely reliable and has been reworked even if we
entered suspend/hibernate/STOP during client processing.
This regression was discovered during continued development of the
Rainbows! test suite (which we will bring over as it becomes ready).
|
|
Since our :QUIT and :TERM signal handlers are idempotent, we can
safely retry sending signals in case workers don't/can't handle
them them the first time around. This appears to be a problem
with the Thread-based concurrency models in Rainbows! not
behaving well (no surprise, though, since pthreads and signals
are difficult to manage/mix properly).
|
|
This removes the Time.now.to_i comparison that was used to avoid
multiple, no-op fchmod() syscalls[1] within the same second.
This should allow us to run on OpenBSD where it can raise EINVAL
when Time.now.to_i is passed to it.
Reported-by: Jeremy Evans <jeremyevans0@gmail.com>
[1] - gettimeofday() from Time.now is not a real syscall on
VDSO-enabled x86_64 GNU/Linux systems where Unicorn is primarily
developed.
|
|
There seems to be a small amount of confusion regarding how it's
used (and some of the code is not very obvious). So explain our
usage of it and distinguish its use in the master vs worker(s).
|
|
Modifying this can be useful for esoteric cases like switching
entire Ruby installations or if the app was originally started
in a no-longer-existent directory and we can't upgrade because
we can't chdir to it.
|
|
There's always been a small window of opportunity for a script
to do File.read(pid).to_i would cause File.read() to read an
empty file and return "". This closes that window while
hopefully retaining backwards compatibility...
We've always checked for dirname(pid) writability in
Configurator, so we can safely write to a temporary file in the
intended directory and then atomically rename() it to the
destination path.
|
|
It's pointless to try and stat a file before trying to read it.
Instead just try opening it and rescue ENOENT because it
would've been racy anyways.
Additionally add some comments to keep us from forgetting
why we did the things we did with the pid file management.
|
|
I'd rather document and maintain a stable interface for the
Worker class than to have to deal with potential (portability
and security) issues with with supporting user privilege
management right now.
There's already an example of user/group-switching support in
the after_fork() hook and the error handling involved may be
different depending on the application and environment so I
remain hesitant to add official support for it...
|
|
It's compatible with both Ruby 1.8 and 1.9 without
needing a Range object.
|
|
Sometimes the upgraded version won't survive and we can fail to
unset that pid and instead accidentally create a local variable.
This is unlikely to be a problem in practice because this
variable is immediately reclobbered when we fork.
|
|
We've started using magic comments to ensure any strings we
create are binary instead. Additionally, ensure we create any
StringIO objects with an explicit string (which default to
binary) to ensure the StringIO object is binary. This is
because StringIO.new (with no arguments) will always use the
process-wide default encoding since it does not know about
magic comments (and couldn't, really...)
|
|
This may be redundant for the "normal" configuration file
directive, but allows the same syntax to be used in after_fork
hooks where HttpServer#listen() may be called.
|
|
This allows per-worker listeners to be configured to retry and
and not continue until the equivalent worker belonging to a
previous master (or even another server) has released the
socket.
In the Configurator RDoc, include better examples for
per-worker server.listen calls using these :tries == -1.
Inspired by an example by Chris Wanstrath.
|
|
When SIGHUP reloads the config, we didn't account for the case
where the listen socket was completely unspecified. Thus the
default listener (0.0.0.0:8080), did not get preserved and
re-injected into the config properly.
Note that relying on the default listen or specifying listeners
on the command-line means it's /practically/ impossible to
_unbind_ those listeners with a configuration file reload. We
also need to preserve the (unspecified) default listener across
upgrades that later result in SIGHUP, too; so the easiest way is
to inject the default listener into the command-line for
upgrades.
Many thanks to James Golick for reporting and helping me track
down the bug since this behavior is difficult to write reliable
automated tests for.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
|
|
This gives applications more rope to play with in case they have
any reasons for changing some values of the default constants.
Freezing strings for Hash assignments still speeds up MRI, so
we'll keep on doing that for now (and as long as MRI supports
frozen strings, I expect them to always be faster for Hashes
though I'd be very happy to be proven wrong...)
|
|
We used to try it on every listener, but then rarely-used
listener ports used mainly for monitoring/debugging would have
accept() unnecessary called, getting unnecessarily expensive
inside the kernel.
|
|
This ensures any string literals that pop up in *our* code will
just be a bag of bytes. This shouldn't affect/fix/break
existing apps in most cases, but most constants will always have
the "correct" encoding (none!) to be consistent with HTTP/socket
expectations. Since this comment affects things only on a
per-source basis, it won't affect existing apps with the
exception of strings we pass to the Rack application.
This will eventually allow us to get rid of that Unicorn::Z
constant, too.
|
|
Avoid potential issues that can arise from logging any weird
characters that may not be supported in the current encoding.
|