From 4b52a167cfb7ea1d1d663844028dcde2d4536223 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 4 Oct 2009 03:09:56 -0700 Subject: revactor: implement actor limiting While we're at it, make it properly 100% message-driven so there's no more busy-waiting and polling for dead actors, No we just wait for client actors to die off and resume listener actors if they stopped accepting. --- lib/rainbows/revactor.rb | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/rainbows/revactor.rb b/lib/rainbows/revactor.rb index 66a4ae3..a0740fa 100644 --- a/lib/rainbows/revactor.rb +++ b/lib/rainbows/revactor.rb @@ -68,16 +68,24 @@ module Rainbows trap(:QUIT) { alive = false; LISTENERS.each { |s| s.close rescue nil } } [:TERM, :INT].each { |sig| trap(sig) { exit!(0) } } # instant shutdown - Actor.current.trap_exit = true + root = Actor.current + root.trap_exit = true + limit = worker_connections listeners = revactorize_listeners logger.info "worker=#{worker.nr} ready with Revactor" - clients = [] + clients = 0 listeners.map! do |s| Actor.spawn(s) do |l| begin - clients << Actor.spawn(l.accept) { |c| process_client(c) } + while clients >= limit + logger.info "busy: clients=#{clients} >= limit=#{limit}" + Actor.receive { |filter| filter.when(:resume) {} } + end + actor = Actor.spawn(l.accept) { |c| process_client(c) } + clients += 1 + root.link(actor) rescue Errno::EAGAIN, Errno::ECONNABORTED rescue Object => e if alive @@ -90,13 +98,20 @@ module Rainbows nr = 0 begin - Actor.sleep 1 - clients.delete_if { |c| c.dead? } - if alive - alive.chmod(nr = 0 == nr ? 1 : 0) - ppid == Process.ppid or alive = false + Actor.receive do |filter| + filter.after(1) do + if alive + alive.chmod(nr = 0 == nr ? 1 : 0) + ppid == Process.ppid or alive = false + end + end + filter.when(Case[:exit, Actor, Object]) do |_,actor,_| + orig = clients + clients -= 1 + orig >= limit and listeners.each { |l| l << :resume } + end end - end while alive || ! clients.empty? + end while alive || clients > 0 end private -- cgit v1.2.3-24-ge0c7