about summary refs log tree commit homepage
path: root/lib/yahns/acceptor.rb
DateCommit message (Collapse)
2017-04-03avoid Thread#[] and Thread#[]= across threads
Support for it may be removed in future versions of Ruby(*), and we actually do not need to waste time looping when a instance variable will do. (*) https://bugs.ruby-lang.org/issues/13245
2016-02-12acceptor: all subclasses of TCPServer use TCP_INFO
This will allow Yahns::OpenSSLServer instances to take advantage of TCP_INFO under Linux, saving us the overhead of method invocations.
2016-01-02copyright updates for 2016
Using the 'update-copyright' script from gnulib[1]: git ls-files | UPDATE_COPYRIGHT_HOLDER='all contributors' \ UPDATE_COPYRIGHT_USE_INTERVALS=2 \ xargs /path/to/gnulib/build-aux/update-copyright We're also switching to 'GPL-3.0+' as recommended by SPDX to be consistent with our gemspec and other metadata (as opposed to the longer but equivalent "GPLv3 or later"). [1] git://git.savannah.gnu.org/gnulib.git
2016-01-02enable frozen_string_literal for Ruby 2.3+
There are likely yet-to-be-discovered bugs in here. Also, keeping explicit #freeze calls for 2.2 users, since most users have not migrated to 2.3, yet.
2015-10-13copyright updates
Future updates may use the update-copyright script in gnulib: git ls-files | UPDATE_COPYRIGHT_HOLDER='all contributors' \ UPDATE_COPYRIGHT_USE_INTERVALS=2 \ xargs /path/to/gnulib/build-aux/update-copyright
2015-03-09acceptor: close inherited-but-unneeded sockets
When inheriting sockets from the parent via YAHNS_FD, we must close sockets ASAP if they are unconfigured in the child. This bug exists in yahns (and not unicorn) because of the trickier shutdown routine we do for blocking accept system calls to work reliably with the threading support in mainline Ruby 2.x. This bug would not exist in a purely C server using blocking accept, either.
2013-11-07fdmap: simplify IO expiry interface
The first argument of the old __expire_for method was completely unused in all but one invocation of it, so it is not worth it. This also simplifies the code a bit too.
2013-11-01enable client expiry for non-TCP sockets
It's conceivable a sub-optimally configured instance can have too many Unix sockets connected to us. This also implements expiry for systems without sufficient "struct tcp_info" support.
2013-10-30Rack hijack issues EPOLL_CTL_DEL
This saves about 200 bytes of unswappable kernel memory, so it might matter for systems with many connections when hijacking.
2013-10-30acceptor: account for inheriting dead descriptors
We may inherit descriptors we never spawned threads for, so account for @thrs not being defined, yet.
2013-10-30allow multiple blocking threads per listen socket
This is probably not needed and just adds contention, but it makes experimenting easier. While we're at it, validate minimum values of for sndbuf/rcvbuf along with this new threads value, too.
2013-10-26StreamFile and TmpIO attempt expiry on EMFILE/ENFILE
This should help prevent some errors from popping up. Obviously, we cannot spend too long doing this inside a worker thread.
2013-10-22rework acceptor thread shutdown (again)
Calling close on the socket while accept4 is running on a different thread can be problematic on Rubinius and some versions of MRI. So we will use a thread-local variable, continuously issue new connections to our own socket and rely on the round-robin behavior of accept4 to eventually get our acceptor thread to wakeup. We must continuously issue new connections because some connections may be going to a new processes (from SIGUSR2). We cannot use shutdown for the same reason.
2013-10-21rework shutdown for systems w/o rb_thread_fd_close
Acceptors require closing the descriptor, first, and then doing a (nasty) cross-thread exception to kick the thread out of the blocking accept via Thread#run (pthread_kill SIGVTALRM). We cannot do what we're doing with epoll with acceptors because the accept socket is shared across processes. We will also NEVER be using non-blocking accept, as it's more important we fairly distribute connections between tasks when we're not shutting the server down. The queue worker threads are much easier to kill off :) We can simply inject a new QueueQuitter object as a Level-Triggering epoll watch, activate it, and let it wreak havok on all the worker threads from a single event activation. rb_thread_fd_close is convenient, but expensive with many threads, so be prepared for more systems without it. This is for Rubinius compatibility. Yes, we are actually using Level-Triggered epoll here (despite the non-shutdown pieces of our code being based around EPOLLONESHOT).
2013-10-20recheck IO#closed? on thread pools after a short delay
The closed IO may not immediately register to all threads due to ordering problems
2013-10-20ensure we stop all threads at exit
Leaving running threads at exit seems to lead to occasional bugs at finalization on Ruby 2.0.0. This could be a bug with sleepy_penguin or kgio, too, so I'll have to investigate further. For now, we'll just destroy the IOs associated with each queue and let the threads die on their own. This changes the QueueEgg internals a bit and I've removed the unit test for QueueEgg now since the rest of the server already works well (and QueueEgg internals may change even more). Queues/worker threads no longer have their own logger, it seems like excessive configurability/complexity since acceptors do not have their own logger, either. This logger only exists to log bugs in yahns, not the application, so using the server logger is sufficient.
2013-10-18initial commit