about summary refs log tree commit homepage
path: root/lib/unicorn.rb
DateCommit message (Collapse)
2009-03-31Use {read,write}_nonblock on the pipe
Instead of trusting sysread/syswrite to throw EAGAIN if the pipe is full (highly unlikely); just use non-blocking methods which are indeed non-blocking and don't care for the #blocking= method added to it.
2009-03-29Fix default listener setup
Combining command-line and config file options in a reasonable manner has and always will be a painful experience.
2009-03-29Avoid having two pid files pointing to the same pid
It makes test_exec more reliable and probably helps other scripts people may run around this.
2009-03-29configurator: per-listener backlog, {rcv,snd}buf config
Instead of having global options for all listeners, make all socket options per-listener. This allows reverse-proxies to pick different listeners to get different options on different sockets. Given a cluster of machines (10.0.0.1, 10.0.0.2, 10.0.0.3) running Unicorn with the following config: ------------------ 8< ---------------- listen "/tmp/local.sock", :backlog => 1 listen "*:8080" # use the backlog=1024 default ------------------ 8< ---------------- It is possible to configure a reverse proxy to try to use "/tmp/local.sock" first and then fall back to using the TCP listener on port 8080 in a failover configuration. Thus the nginx upstream configuration on 10.0.0.1 to compliment this would be: ------------------ 8< ---------------- upstream unicorn_cluster { # reject connections ASAP if we are overloaded server unix:/tmp/local.sock; # fall back to other machines in the cluster via "backup" # listeners which have a large backlog queue. server 10.0.0.2:8080 backup; server 10.0.0.3:8080 backup; } ------------------ 8< ---------------- This removes the global "backlog" config option which was inflexible with multiple machines in a cluster and exposes the ability to change SO_SNDBUF/SO_RCVBUF via setsockopt(2) for the first time.
2009-03-27Always try to send a valid HTTP response back
This reworks error handling throughout the entire stack to be more Ruby-ish. Exceptions are raised instead of forcing the us to check return values. If a client is sending us a bad request, we send a 400. If unicorn or app breaks in an unexpected way, we'll send a 500. Both of these last-resort error responses are sent using IO#write_nonblock to avoid tying Unicorn up longer than necessary and all exceptions raised are ignored. Sending a valid HTTP response back should reduce the chance of us from being marked as down or broken by a load balancer. Previously, some load balancers would mark us as down if we close a socket without sending back a valid response; so make a best effort to send one. If for some reason we cannot write a valid response, we're still susceptible to being marked as down. A successful HttpResponse.write() call will now close the socket immediately (instead of doing it higher up the stack). This ensures the errors will never get written to the socket on a successful response.
2009-03-27No need to disable luserspace buffering on client socket
Unicorn always uses lower-level sys{read,write} methods when doing I/O so setting "client.sync=true" is just a wasted operation.
2009-03-27style: symbols instead of strings for signal names
They're easier for me to type and read and just barely faster when doing comparisons on.
2009-03-27Deferred log rotation in workers
Instead of rotating logs immediately when SIGUSR1 is caught, defer it until the current client is processing is complete. This allows multi-line log messages generated by apps to not be broken up if SIGUSR1 is received while the app is running. If we're sleeping inside IO.select, we close a pipe in the exceptfds set to cause EBADF to be raised. This also adds a small reliability improvement to test_exec so we wait until signals are ready before sending USR1 to rotate logs.
2009-03-26Don't allow failed log rotation to to break app
In case there are permissions problems that cause log rotation to fail, we trap the error and defer death until the current request finishes running.
2009-03-25Socket: add {snd,rcv}buf opts to bind_listen
bind_listen takes a hash as its second parameter now, allowing the addition of :sndbuf and :rcvbuf options to specify the size of the buffers in bytes. These correspond to the SO_SNDBUF and SO_RCVBUF options via setsockopt(2) respectively. This also adds support for per-listener backlogs to be used. However, this is only an internal API change and the changes have not yet been exposed to the user via Unicorn::Configurator, yet. Also add a bunch of SocketHelper tests
2009-03-22Don't bother unlinking UNIX sockets
Since we always unlink existing sockets when binding, there's no point in having code to unlink the sockets when we exit. Additionally, the old code path was racy.
2009-03-21Simplify code for sleeping/waking up the master
Only sleep if our signal queue is empty. Remove redundant exception handling and go back to just consuming the entire pipe since that's more efficient if we're slammed with signals for whatever reason.
2009-03-21Rotate master logs before workers.
The master _may_ run with different user/group/umask than the workers. Since the logs were always created by the master process, the master should rotate them first to ensure correct ownership and permissions. This way if the workers fail log rotation and die, they'll be automatically respawned with the new logs in place.
2009-03-20Process management cleanups
* Use waitpid2 to more reliably trap exit status * Stop including Process namespace since it leads to confusing conflicts.
2009-03-19Trap WINCH to QUIT children without respawning
This will only be enabled if we're daemonized and "real" WINCH signals cannot be generated by resizing the terminal. This is to avoid confusing developers who run in the foreground of a terminal. Additionally document procedures for reexecuting a running binary.
2009-03-18Add signal queueing for test reliability
Although I didn't like the idea initially, signal queueing allows test_exec to run more reliably and the limited signal queue size will prevent scary queued signal behavior. Also, always wakeup the master immediately when CHLD is trapped to reduce the performance impact of SIGHUP-based config reloading. Combined with an extra check in test_exec, this should make test_exec run much more reliably than before.
2009-03-18gracefully die if working dir is invalid at fork
In nearly every app, if the current working directory disappears, the app becomes broken, sometimes subtly. It can be especially broken when preload_app is false (the default). So just shut ourselves down to spare ourselves the wasted CPU cycles on a dead app. As a (hopefully) pleasant side effect, this allows configurations with preload_app==false (the default) to do application code reloads via SIGHUP (in addition to unicorn config reloads).
2009-03-04Add before_exec hook
This is useful for freeing certain resources you do NOT want passed to child processes.
2009-03-04Remove "directory" config option
Unicorn will always continue to run in the directory it started in, it does not chdir to "/". Since the default start_ctx[:cwd] is symlink-aware, this should not be a problem for Capistrano-deployed applications.
2009-03-04Ensure reopened std{out,err}_paths can be rotated
The $stderr/$stdout objects need to point to +File+ objects and mot just +IO+ objects they default to for reopen_logs to work.
2009-03-03Raise ArgumentError if listeners are empty
Instead of blindly trying to bind to the default listener (which is already the default as specified by Configurator).
2009-03-03fix typo (DEFAULT_LISTENER => DEFAULT_LISTEN)
2009-03-03Allow stderr_path and stdout_path to be set in the config
As opposed to doing this in the shell, this allows the files to be reopened reliably after rotation. While we're at it, use $stderr/$stdout instead of STDERR/STDOUT since they seem to be more favored.
2009-03-03Load the app _after_ forking workers by default
This means processes will share less memory but things should be compatible with all existing setups.
2009-03-03Handle Errno::EINTR during IO.select in workers
If we get woken up during an IO.select, just make a bet that we spent some time doing something else and aggressively try to accept new connections without trying to wait for I/O-readiness notification.
2009-03-03Make USR1 rotate log files by default
I consider it a sensible default for long-running servers. Additionally, there is no easy way to make USR1 rotate the master process log without this.
2009-03-03Add Unicorn::Util for a reopen_logs method
Since I use it myself and also in the tests, we might as well implement it correctly as a class method so people can run it in their trap('USR2') hooks.
2009-03-03symlink-aware start_ctx[:cwd]
Using `/bin/sh -c pwd` here instead of Dir.pwd since the pwd shell builtin is symlink-aware if ENV['PWD'] is correct (and it is when launched via Cap). Also, correctly use @directory if it is set.
2009-03-03Unlink the pid file explicitly when master exits
Relying on at_exit can still means a child might get it if there's any race condition....
2009-03-03Begin to allow deferred app creation/loading
Some applications do not handle loading before forking out-of-the-box very gracefully, this starts adding support to build the Rack(-ish) application later in the process.
2009-02-23Allow overriding :directory or via -C/--directory
This allows Unicorn to be constantly started in symlink paths such as the ones Capistrano creates (e.g. "/u/apps/$app/current")
2009-02-21Fix+test reexec error handling on bad inputs
People can screw config files up, it's not my fault if they do, but they do... Don't let the original process get wedged if we can help it..
2009-02-21revamp configuration with Configurator DSL
The Configurator includes error checking and opens the way for better reloading/error-checking abilities. This also renames many of the config settings with something nginx-like to minimize the learning/setup curve since nginx is the only recommended reverse-proxy for this. s/pid_file/pid/ => blech!, more confusing :< s/listen_backlog/backlog/ => maybe more confusing to some, or less... s/nr_workers/worker_processes/ => less confusing to non-AWKers for sure s/hot_config_file/config_file/ => the config file is now general purpose, not just hot reloads
2009-02-21Register default constants in Const module
This will make setting some of this easier to deal with in the executable.
2009-02-21Ignore ENV['PWD'] in default start context
This variable is not guaranteed to be updated outside of an interactive POSIX-ish shell.
2009-02-13continue ignoring SIGCHLD for now...
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.
2009-02-13trap SIGCHLD and wakeup master on it
And avoid repeatedly sending kill -0 to each worker, that nugget of stupid probably slipped in while I was testing something...
2009-02-10add_listener logging includes fd= information
This is to make things consistent with the other logging when adding listeners
2009-02-10Set default process title
This can be overridden in {after,before}_fork hooks of course; but makes things look a little nicer.
2009-02-10add hot_config_file config parameter
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.
2009-02-10Allow listen_backlog to be specified in config.
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.
2009-02-10Minor and insignificant cleanups and style changes
* 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
2009-02-09Use a short-as-possible path for worker Tempfiles
These files are unlinked immediately anyways, so it's wasteful to give them a long name...
2009-02-09Prevent leakage of private pipes and tempfiles.
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.
2009-02-09add add_listener method for use in configs
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.
2009-02-09Delete UNICORN_* environment variables in workers
Workers have no business knowing these things...
2009-02-09Avoid starting the pipe until we need it
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.
2009-02-09Add optional PID file support
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.
2009-02-09Reinstate timeouts for killing workers
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
2009-02-09More reliable wakeups in master process
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