Date | Commit message (Collapse) |
|
|
|
Bah, it's so much busy work to deal with this as configuration
option. Maybe I should say we allow any logger the user wants,
as long as it's $stderr :P
|
|
Make us look even better in "Hello World" benchmarks!
Passing a third parameter to avoid the constant lookup
for the HttpRequest object doesn't seem to have a
measurable effect.
|
|
This should be faster/cheaper than using an instance variable
since it's accessed in a critical code path. Unicorn was never
designed to be reentrant or thread-safe at all, either.
|
|
This makes SIGHUP handling more consistent across different
configurations, and allows togging preload_app to take effect
when SIGHUP is issued.
|
|
There is a potential race condition in closing the tempfile
immediately after SIGKILL-ing the child. So instead just
close it when we reap the dead child.
Some some versions of Ruby may also not like having the
WORKERS hash being changed while it is iterating through
each_pair, so dup the hash to be on the safe side (should
be cheap, since it's not a deep copy) since kill_worker()
can modify the WORKERS hash.
This is somewhat of a shotgun fix as I can't reproduce the
problem consistently, but oh well.
|
|
|
|
This should prevent Rack from being required too early
on so "-I" being passed through the unicorn command-line
can modify $LOAD_PATH for Rack
|
|
No point in refreshing the list of gems unless the app
can actually be reloaded.
|
|
On application reloads, Gems installed by the Ruby instance may
be different than when Unicorn started. So when preload_app is
false, HUP-ing Unicorn will always refresh the list of Gems
before loading the application code.
|
|
* commit 'v0.7.1':
unicorn 0.7.1
Conflicts:
lib/unicorn/const.rb
|
|
|
|
Rack::Lint says they just have to work when to_i is
called on the status, so that's what we'll do.
|
|
2 seconds is still prone to race conditions under high load.
We're intentionally less accurate than we could be in order to
reduce syscall and method dispatch overhead.
|
|
|
|
Ensure we preserve both internal and external encodings
when reopening logs.
|
|
|
|
This makes it easier to use "killall -$SIGNAL unicorn"
without having to lookup the correct PID.
|
|
Timeouts of less than 2 seconds are unsafe due to the lack of
subsecond resolution in most POSIX filesystems. This is the
trade-off for using a low-complexity solution for timeouts.
Since this type of timeout is a last resort; 2 seconds is not
entirely unreasonable IMNSHO. Additionally, timing out too
aggressively can put us in a fork loop and slow down the system.
Of course, the default is 60 seconds and most people do not
bother to change it.
|
|
"out" was an invalid variable in that context...
|
|
Don't allow newly created IO objects to get GC'ed and
subsequently close(2)-ed. We're not reopening the
{$std,STD}{in,out,err} variables since those can't be
trusted to have fileno 1, 2 and 3 respectively.
|
|
Unicorn proper no longer needs these constants,
so don't bother with them.
|
|
Rack::Lint says they just have to work when to_i is
called on the status, so that's what we'll do.
|
|
Preventing needless duplication since Rack already has these
codes for us. Also, put the status codes in HttpResponse since
nothing else needs (or should need) them.
|
|
There may be other logs opened if preload_app is true
besides stderr/stdout paths. So err on the safe side
and reopen everything.
|
|
If we're using middleware that pushes the body into an
array, bad things will happen if we're clobbering the
string for each iteration of body#each.
|
|
Give this a more palatable name and unfreeze it,
allowing users to modify it more easily.
|
|
This used to happen on machines that were coming out of
suspend/hibernation.
|
|
2 seconds is still prone to race conditions under high load.
We're intentionally less accurate than we could be in order to
reduce syscall and method dispatch overhead.
|
|
This reduces garbage generation to improve performance. Rack
1.0 allows InputWrapper to read with an explicit buffer.
|
|
This allows alternative I/O implementations to be easier
to use with Unicorn...
|
|
|
|
Ensure we preserve both internal and external encodings
when reopening logs.
|
|
These potentially leaves an open file handle around until the
next request hits the process, but this makes the common case
faster.
|
|
|
|
First, reduce no-op fchmod syscalls under heavy traffic.
gettimeofday(2) is a cheaper syscall than fchmod(2). Since
ctime resolution is only in seconds on most filesystems (and
Ruby can only get to seconds AFAIK), we can avoid fchmod(2)
happening within the same second. This allows us to cheat on
synthetic benchmarks where performance is measured in
requests-per-second and not seconds-per-request :)
Secondly, cleanup the acceptor loop and avoid nested
begins/loops as much as possible. If we got ECONNABORTED, then
there's no way the client variable would've been set correctly,
either. If there was something there, then it is at the mercy
of the garbage collector because a method can't both return a
value and raise an exception.
|
|
Use SIGQUIT if you're going to be nice and do graceful
shutdowns. Sometimes people run real applications on this
server and SIGINT/SIGTERM get lost/trapped when Object is
rescued and that is not good. Also make sure we break out of
the loop properly when the master is dead.
Testcases added for both SIGINT and dead master handling.
|
|
If our response succeeds, we've already closed the socket.
Otherwise, we would've raised an exception at some point hit one
of the rescue clauses.
|
|
This makes it easier to use "killall -$SIGNAL unicorn"
without having to lookup the correct PID.
|
|
Timeouts of less than 2 seconds are unsafe due to the lack of
subsecond resolution in most POSIX filesystems. This is the
trade-off for using a low-complexity solution for timeouts.
Since this type of timeout is a last resort; 2 seconds is not
entirely unreasonable IMNSHO. Additionally, timing out too
aggressively can put us in a fork loop and slow down the system.
Of course, the default is 60 seconds and most people do not
bother to change it.
|
|
Since we've switched to readpartial, we'll already be protected
from any unpleasant errors that might get thrown at us. There's
no easy way to prevent MRI from calling a select() internally to
check for readiness, so speculative+blocking read() calls are
out already.
Additionally, most requests come in the form of GETs which are
fully-buffered in the kernel before we even accept() the socket;
so a single readpartial call will be enough to fully consume it.
|
|
readpartial is actually as low-level as sysread is,
except it's less likely to throw exceptions and
won't change the blocking/non-blocking status of
a file descriptor (we explicitly enable blocking I/O)
|
|
Simpler code on our end can be just a tick faster because
syscalls are still not as cheap as normal functions and this
still manages to play well with our lack of keepalive
support as closing the socket will flush it immediately.
|
|
Since the vast majority of web traffic is GET/HEAD
requests without bodies, avoid creating a StringIO
object for every single request that comes in.
|
|
"out" was an invalid variable in that context...
|
|
Only do speculative accept on the previous ready set of
listeners. This makes it less CPU-intensive to have per-process
debug listeners configured.
Unfortunately, this makes non-primary listeners unable to accept
connections if the server is under extremely heavy load and
speculative accept() on the previous listener is always
succeeding and hogging the process. Fortunately, this is an
uncommon case.
|
|
Don't allow newly created IO objects to get GC'ed and
subsequently close(2)-ed. We're not reopening the
{$std,STD}{in,out,err} variables since those can't be
trusted to have fileno 1, 2 and 3 respectively.
|
|
No need to use ensure since process_client will handle errors
regardless. And if not, there's a bug on our side that needs to
fixed.
|
|
|
|
Keep in mind that it's plenty possible to use Unicorn as a
library without using Rack itself. Most of the unit tests
do not depend on Rack, for example.
|