about summary refs log tree commit homepage
path: root/lib
DateCommit message (Collapse)
2017-03-23doc: add version annotations for new features
We will inevitably have people running old unicorn versions for many years to come; but they may be reading the latest documentation online. Annotate when the new features (will) appear to avoid misleading users on old versions.
2017-03-23Merge remote-tracking branch 'origin/worker_exec'
* origin/worker_exec: Don't pass a block for fork when forking workers Add worker_exec configuration option
2017-03-23Merge branch 'ccc-tcp-v3'
* ccc-tcp-v3: test_ccc: use a pipe to synchronize test http_request: support proposed Raindrops::TCP states on non-Linux
2017-03-23http_server: initialize @pid ivar
This quiets down warnings when run with '-w'
2017-03-23input: update documentation and hide internals.
rack 2.x exists nowadays still allows rewindable input as an option, and we will still enable it by default to avoid breaking any existing code. Hide the internal documentation since we do not want people depending on unicorn internals; so there's no reason to confuse or overwhelm people with documentation about it. Arguably, TeeInput and StreamInput should not be documented publically at all, but I guess that ship has long sailed...
2017-03-21http_request: support proposed Raindrops::TCP states on non-Linux
raindrops 0.18+ will have Raindrops::TCP state hash for portable mapping of TCP states to their respective numeric values. This was necessary because TCP state numbers (and even macro names) differ between FreeBSD and Linux (and possibly other OSes). Favor using the Raindrops::TCP state hash if available, but fall back to the hard-coded values since older versions of raindrops did not support TCP_INFO on non-Linux systems. While we're in the area, favor "const_defined?" over "defined?" to reduce the inline constant cache footprint for branches which are only evaluated once. Patches to implement Raindrops::TCP for FreeBSD are available at: https://bogomips.org/raindrops-public/20170316031652.17433-1-e@80x24.org/T/
2017-03-15Merge remote-tracking branch 'origin/ccc-tcp-v3'
* origin/ccc-tcp-v3: http_request: reduce insn size for check_client_connection support "struct tcp_info" on non-Linux and Ruby 2.2+ revert signature change to HttpServer#process_client new test for check_client_connection check_client_connection: use tcp state on linux
2017-03-14doc: fix links to raindrops project
bogomips.org is dropping prefixes to reduce subjectAltName bloat in TLS certificates.
2017-03-14freebsd: avoid EINVAL when setting accept filter
Accept filters can only be set on listen sockets, and it also fails with EINVAL if it's already set. Untested, but I suppose changing the accept filter on a listening socket is not supported, either; since that could affect in-flight sockets.
2017-03-14http_request: reduce insn size for check_client_connection
Unlike constants and instance variables, class variable access is not optimized in the mainline Ruby VM. Use a constant instead, to take advantage of inline constant caching. This further reduces runtime instruction size by avoiding a branch by allocating the Raindrops::TCP_Info object up front. This reduces the method size by roughly 300 bytes on 64-bit.
2017-03-13Don't pass a block for fork when forking workers worker_exec
This reduces the stack depth, making GC more efficient.
2017-03-10Add worker_exec configuration option
The worker_exec configuration option makes all worker processes exec after forking. This initializes the worker processes with separate memory layouts, defeating address space discovery attacks on operating systems supporting address space layout randomization, such as Linux, MacOS X, NetBSD, OpenBSD, and Solaris. Support for execing workers is very similar to support for reexecing the master process. The main difference is the worker's to_i and master pipes also need to be inherited after worker exec just as the listening sockets need to be inherited after reexec. Because execing working is similar to reexecing the master, this extracts a couple of methods from reexec (listener_sockets and close_sockets_on_exec), so they can be reused in worker_spawn.
2017-03-08oob_gc: rely on opt_aref_with optimization on Ruby 2.2+
Maybe oob_gc probably isn't heavily used anymore, maybe some Ruby 2.2+ users will benefit from this constant reduction. Followup-to: fb2f10e1d7a72e67 ("reduce constants and optimize for Ruby 2.2")
2017-03-08support "struct tcp_info" on non-Linux and Ruby 2.2+
Ruby 2.2+ can show "struct tcp_info" as a string via Socket::Option#inspect, and we can attempt to parse it out to extract the information we need. Parsing this string is inefficient, but does not depend on the ordering of the tcp_info struct.
2017-03-08revert signature change to HttpServer#process_client
We can force kgio_tryaccept to return an internal class for TCP objects by subclassing Kgio::TCPServer. This avoids breakage in any unfortunate projects which depend on our undocumented internal APIs, such as gctools <https://github.com/tmm1/gctools>
2017-03-08check_client_connection: use tcp state on linux ccc-tcp-v2
* Use a frozen empty array and a class variable for TCP_Info to avoid garbage. As far as I can tell, this shouldn't result in any garbage on any requests (other than on the first request). * Pass listener socket to #read to only check the client connection on a TCP server. * Short circuit CLOSE_WAIT after ESTABLISHED since in my testing it's the most common state after ESTABLISHED, it makes the numbers un-ordered, though. But comment should make it OK. * Definition of of `check_client_connection` based on whether Raindrops::TCP_Info is defined, instead of the class variable approach. * Changed the unit tests to pass a `nil` listener. Tested on our staging environment, and still works like a dream. I should note that I got the idea between this patch into Puma as well! https://github.com/puma/puma/pull/1227 [ew: squashed in temporary change for oob_gc.rb, but we'll come up with a different change to avoid breaking gctools <https://github.com/tmm1/gctools>] Acked-by: Eric Wong <e@80x24.org>
2017-02-23Add after_worker_ready configuration option chroot
This adds a hook that is called after the application has been loaded by the worker process, directly before it starts accepting requests. This hook is necessary if your application needs to gain access to resources during initialization, and then drop privileges before serving requests. This is especially useful in conjunction with chroot support so the app can load all the normal ruby libraries it needs to function, and then chroot before accepting requests. If you are preloading the app, it's possible to drop privileges or chroot in after_fork, but if you are not preloading the app, the only way to currently do this is to override the private HttpServer#init_worker_process method, and overriding private methods is a recipe for future breakage if the internals are modified. This hook allows for such functionality to be supported and not break in future versions of Unicorn.
2017-02-23Add support for chroot to Worker#user
Any chrooting would need to happen inside Worker#user, because you can't chroot until after you have parsed the list of groups, and you must chroot before dropping root privileges. chroot adds an extra layer of security, so that if the unicorn process is exploited, file system access is limited to the chroot directory instead of the entire file system.
2017-02-23Fix code example in after_worker_exit documentation
Fixes: 2af91a1fef70d654 ("Add after_worker_exit configuration option")
2017-02-21Add after_worker_exit configuration option
This option is executed in the master process following all worker process exits. It is most useful in the case where the worker process crashes the ruby interpreter, as the worker process may not be able to send error notifications appropriately. For example, let's say you have a specific request that crashes a worker process, which you expect to be due to a improperly programmed C extension. By modifying your worker to save request related data in a temporary file and using this option, you can get a record of what request is crashing the application, which will make debugging easier. Example: after_worker_exit do |server, worker, status| server.logger.info "worker #{status.success? ? 'exit' : 'crash'}: #{status}" file = "request.#{status.pid}.txt" if File.exist?(file) do_something_with(File.read(file)) unless status.success? File.delete(file) end end
2017-02-13http_request: freeze constant strings passed IO#write
This ensures we won't have duplicate objects in Ruby 2.0-2.4. For Ruby 2.5.0dev+, this avoids any duplicate cleanup introduced as of r57471: https://bugs.ruby-lang.org/issues/13085
2017-02-10tee_input: simplify condition for IO#write
IO#write already elides the write(2) syscall for empty buffers, so there's no need to complicate our instruction sequence footprint for the rare case of an empty buffer. The only cases a Rack app will have an empty buffer are: 1) `env['rack.input'].read` without args 2) `env['rack.input'].gets` Neither of these calls are safe for server-independent Rack apps as the client can OOM the app. unicorn itself provides no facility for limiting maximum rack.input size. Instead, unicorn relies on nginx to limit input size using the client_max_body_size directive.
2016-10-25relocate website to https://bogomips.org/unicorn/
HTTPS helps some with reader privacy and Let's Encrypt seems to be working well enough the past few months. This change will allow us to reduce subjectAltName bloat in our TLS certificate over time. It will also promote domain name agility to support mirrors or migrations to other domains (including a Tor hidden service mirror). http://bogomips.org/unicorn/ will remain available for people on legacy systems without usable TLS. There is no plan for automatic redirecting from HTTP to HTTPS at this time.
2016-07-28doc: update gmane URLs to point to our own archives
Gmane's NNTP server remains up, but the HTTP site is down: https://lars.ingebrigtsen.no/2016/07/28/the-end-of-gmane/ Anyways, our own archives are designed to be mirror-able via git: git clone --mirror https://bogomips.org/unicorn-public And the code is self-hostable: git clone https://public-inbox.org
2016-01-27doc update for ClientShutdown exceptions class
State explicitly applications should not rely on it, and instead rescue the generic EOFError exception. This class will stick around because there may inevitably be things which rely on it, but we should not encourage it, either.
2016-01-27rack is optional at runtime, required for dev
We do not want to pull in a newer or older version of rack depending on an the application running under it requires. Furthermore, it has always been possible to use unicorn without any middleware at all. Without rack, we'll be missing descriptive status text in the first response line, but any valid HTTP/1.x parser should be able to handle it properly. ref: http://bogomips.org/unicorn-public/20160121201255.GA6186@dcvr.yhbt.net/t/#u Thanks-to: Adam Duke <adam.v.duke@gmail.com> Thanks-to: Aaron Patterson <tenderlove@ruby-lang.org>
2016-01-07various documentation updates
* add nntp_url to the olddoc website footer * update legacy support status for 4.x (not 4.8.x) * update copyright range to 2016 * note all of our development tools are Free Software, too * remove cgit mention; it may not always be cgit (but URLs should remain compatible). * discourage downloading snapshot tarballs; "git clone" + periodic "git fetch" is more efficient * remove most mentions of unicorn_rails as that was meant for ancient Rails 1.x/2.x users * update path reference to Ruby 2.3.0 * fix nginx upstream module link to avoid redirect * shorten Message-ID example to avoid redirects and inadvertant linkage
2015-11-17http_response: allow nil values in response headers
This blatantly violates Rack SPEC, but we've had this bug since March 2009[1]. Thus, we cannot expect all existing applications and middlewares to fix this bug and will probably have to support it forever. Unfortunately, supporting this bug contributes to application server lock-in, but at least we'll document it as such. [1] commit 1835c9e2e12e6674b52dd80e4598cad9c4ea1e84 ("HttpResponse: speed up non-multivalue headers") Reported-by: Owen Ou <o@heroku.com> Ref: <CAO47=rJa=zRcLn_Xm4v2cHPr6c0UswaFC_omYFEH+baSxHOWKQ@mail.gmail.com>
2015-11-01golf down conditional for socket activation
The PID of a process can never be zero as kill(2) interprets a '0' PID arg as "every process in caller's process group", so there's no risk of the 'nil.to_i => 0' conversion resulting in a truth value when compared to $$.
2015-10-27sd_listen_fds emulation cleanup
Re-enable and expand on the test case while we're at it for new Rubies. The bug is now fixed in Ruby 2.3.0dev as of r51576. We shall assume anybody running a pre-release 2.3.0 at this point is running a fairly recent snapshot, so we won't bother doing a finer-grained check in the test for an exact revision number.
2015-08-22stream_input: favor String#clear over String#replace
We no longer need Ruby 1.8 compatibility, so use String#clear to reduce argument passing and code size.
2015-07-15doc: remove references to old servers
They'll continue to be maintained, but we're no longer advertising them. Also, favor lowercase "unicorn" while we're at it since that matches the executable and gem name to avoid unnecessary escaping for RDoc.
2015-07-15configurator: document net.core.somaxconn sysctl dependency
Linux users are effectively capped to 128 on stock installations and may wonder why connections get rejected with overloaded apps sooner rather than later.
2015-07-05emulate sd_listen_fds for systemd support
systemd socket emulation shares FDs across execve, just like the built-in SIGUSR2 upgrade process in unicorn. Thus it is easy to support inheriting sockets from systemd. Tested-by: Christos Trochalakis <yatiohi@ideopolis.gr>
2015-06-30http_response: reduce size of multi-line header path
This should save over 100 bytes of bytecode overhead due to reduced method dispatch points. The performance difference when this is actually hit could go either way depending on how String#<< and realloc(3) interact, but it's uncommon enough that nobody is expected to notice either way.
2015-06-30reduce constants and optimize for Ruby 2.2
Ruby (MRI) 2.1 optimizes allocations away on String#freeze with literal strings. Furthermore, Ruby 2.2 optimizes away literal string allocations when they are used as arguments to Hash#[] and Hash#[]= Thus we can avoid expensive constant lookups and cache overhead by taking advantage of advancements in Ruby. Since Ruby 2.2 has been out for 7 months, now; it ought to be safe to introduce minor performance regressions for folks using older Rubies (1.9.3+ remains supported) to benefit folks on the latest Ruby. This should recover the performance lost in the "reflect changes in Rack::Utils::HTTP_STATUS_CODES" change in synthetic benchmarks.
2015-06-30reflect changes in Rack::Utils::HTTP_STATUS_CODES
Applications may want to alter the message associated with HTTP status codes in Rack::Utils::HTTP_STATUS_CODES. Avoid memoizing status lines ahead-of-time Note: this introduces a minor performance regression, but ought to be unnoticeable unless you're running "Hello world"-type apps.
2015-06-27apply TCP socket options on inherited sockets
TCP socket options are now set when inheriting existing sockets from a parent process. I'm fairly certain all the TCP setsockopt knobs we use are idempotent and harmless to change. If anything, the only directive I'd be uncomfortable changing is shortening the listen(2) (aka :backlog) size, but we've always changed that anyways since it also applies to UNIX sockets. Note: removing a configuration knob in a unicorn config file can not reset the value to the OS-provided default setting. Inherited sockets must use a new setting to override existing ones. (or the socket needs to be closed and re-created in the process launcher before unicorn inherits it). Noticed-by: Christos Trochalakis <yatiohi@ideopolis.gr> <20150626114129.GA25883@luke.ws.skroutz.gr>
2015-06-26doc: update some invalid URLs
Most of these were found by the `linkchecker' package in Debian.
2015-06-10ensure body is closed during hijack
Middlewares such as Rack::Lock (used by Rails) break badly unless the response body is closed on hijack, so we will close it to follow the lead of other popular Rack servers. While it's unclear if there's anybody using rack.hijack with unicorn, we'll try to emulate the behavior of other servers as much as possible. ref: https://github.com/ngauthier/tubesock/issues/10
2015-06-06http: move response_start_sent into the C ext
Combined with the previous commit to eliminate the `@socket' instance variable, this eliminates the last instance variable in the Unicorn::HttpRequest class. Eliminating the last instance variable avoids the creation of a internal hash table used for implementing the "generic" instance variables found in non-pure-Ruby classes. Method entry overhead remains the same. While this change doesn't do a whole lot for unicorn memory usage where the HttpRequest is a singleton, it helps other HTTP servers which rely on this code where thousands of clients may be connected.
2015-06-06move the socket into Rack env for hijacking
This avoids the expensive generic instance variable for @socket and exposes the socket as `env["unicorn.socket"]' to the Rack application. As as nice side-effect, applications may access `env["unicorn.socket"]' as part of the API may be useful for 3rd-party bits such as Raindrops::TCP_Info for reading the tcp_info struct on Linux-based systems. Yes, `env["unicorn.socket"]' is a proprietary API in unicorn! News at 11! But then again, unicorn is not the first Rack server to implement `env["#{servername}.socket"]', either...
2015-06-04http_response: simplify regular expression
It's ugly and less-readable to have redundant \z statements, and according to ObjectSpace.memsize_of, this saves 4 bytes on x86-64.
2015-06-04http_server: remove a few more accessors and constants
Unnecessarily exposed accessors and constants take up unnecessary memory in constant/method tables as well as using extra space in instruction sequences. Preforking servers like unicorn are a bloated pigs anyways, but saving a few hundred bytes here and there can add up and make them marginally less bad.
2015-06-01http_response: avoid special-casing for Rack < 1.5
Rack 1.4 and earlier will soon die out, so avoid having extra, overengineered code and method dispatch to silently drop support for mis-hijacking with old Rack versions. This will cause improperly hijacked responses in all versions of Rack to fail, but allows properly hijacked responses to work regardless of Rack version. Followup-to: commit fdf09e562733f9509d275cb13c1c1a04e579a68a ("http_request: support rack.hijack by default")
2015-05-20process SIGWINCH unless stdin is a TTY
Some process managers such as foreman and daemontools rely on unicorn not daemonizing, but we still want to be able to process SIGWINCH in that case. stdout and stderr may be redirected to a pipe (for cronolog or similar process), so those are less likely to be attached to a TTY than stdin. This also allows users to process SIGWINCH when running inside a regular terminal if they redirect stdin to /dev/null. Reported-by: Dan Moore <dan@vaporwa.re> References: <etPan.555b4293.5b47a5b7.e617@danbookpro> <20150519232858.GA23515@dcvr.yhbt.net>
2015-05-16avoid extra allocation for hijack proc creation
proc creation is expensive, so merely use a 48-byte generic ivar hash slot for @socket instead.
2015-05-16http_request: support rack.hijack by default
Rack 1.4 and earlier will soon die out, so avoid having extra code The only minor overhead is assigning two hash slots and the extra hash checks when running ancient versions of Rack, so it is unlikely anybody cares about that overhead with Rack 1.5 and later.
2015-05-07favor kgio_wait_readable for single FD over select
kgio_wait_readable is superior for single FDs in that it may use the ppoll syscall on Linux via Ruby, making it immune to the slowdown high FDs with select() and the array allocations enforced by the Ruby wrapper interface. Note: IO#wait in the io/wait stdlib has the same effect, but as of 2.2 still needlessly checks the FIONREAD ioctl. So avoid needing to force a new require on users which also incur shared object loading costs. The longer term plan is to rely entirely on Ruby IO primitives entirely and drop kgio, but that won't happen until we can depend on Ruby 2.3 for exception-free accept_nonblock (which will be released December 2015).
2015-04-24support TempfileReaper in deployment and development envs
rack 1.6 added a TempfileReaper middleware to cleanup temporary files. Enable it by default for users running rack 1.6 or later to avoid leaving temporary files around.