diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-10-11 12:15:47 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-10-11 16:55:58 -0700 |
commit | df204a05d3a5bda8f716fa9f51be464fa59a3af1 (patch) | |
tree | 1391300d9dfe0a01a5f38958e3cf8c4c30c2fa0a /lib/rainbows/thread_spawn.rb | |
parent | 4f8ae9abbb985a4091acbb7f57fb7f88fa2d43ba (diff) | |
download | rainbows-df204a05d3a5bda8f716fa9f51be464fa59a3af1.tar.gz |
The process-based heartbeat continues, but we no longer time threads out just because a client is idle for any reason (for now).
Diffstat (limited to 'lib/rainbows/thread_spawn.rb')
-rw-r--r-- | lib/rainbows/thread_spawn.rb | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/lib/rainbows/thread_spawn.rb b/lib/rainbows/thread_spawn.rb index c9fd23c..77cc3f2 100644 --- a/lib/rainbows/thread_spawn.rb +++ b/lib/rainbows/thread_spawn.rb @@ -29,45 +29,28 @@ module Rainbows rescue Errno::EBADF, TypeError break end + alive.chmod(m = 0 == m ? 1 : 0) ret.first.each do |l| - nuke_old_thread(threads, limit) - c = begin - l.accept_nonblock + # Sleep if we're busy, another less busy worker process may + # take it for us if we sleep. This is gross but other options + # still suck because they require expensive/complicated + # synchronization primitives for _every_ case, not just this + # unlikely one. Since this case is (or should be) uncommon, + # just busy wait when we have to. + while threads.list.size > limit # unlikely + sleep(0.1) # hope another process took it + break # back to IO.select + end + begin + threads.add(Thread.new(l.accept_nonblock) {|c| process_client(c) }) rescue Errno::EAGAIN, Errno::ECONNABORTED - next end - threads.add(Thread.new(c) { |c| process_client(c) }) end rescue Object => e - listen_loop_error(e) if alive - end while alive && master_pid == Process.ppid - join_spawned_threads(threads) - end - - def nuke_old_thread(threads, limit) - while (list = threads.list).size > limit - list.each do |thr| - thr.alive? or return # it _just_ died, we don't need it - next if (age = (Time.now - (thr[:t] || next))) < timeout - thr.kill # no-op if already dead - logger.error "killed #{thr.inspect} for being too old: #{age}" - return - end - # nothing to kill, yield to another thread - Thread.pass - end - end - - def join_spawned_threads(threads) - logger.info "Joining spawned threads..." - t0 = Time.now - timeleft = timeout - threads.list.each { |thr| - thr.join(timeleft) - timeleft -= (Time.now - t0) - } - logger.info "Done joining spawned threads." + listen_loop_error(e) if LISTENERS.first + end while LISTENERS.first && master_pid == Process.ppid + join_threads(threads.list) end end |