From 3cc3c73959c0227ddc732699975a1edb1f0aa2d1 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 27 Nov 2009 17:59:28 -0800 Subject: preliminary ActorSpawn model for Rubinius It seems to basically work, this is based heavily on the Revactor one... --- lib/rainbows.rb | 1 + lib/rainbows/actor_spawn.rb | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 lib/rainbows/actor_spawn.rb diff --git a/lib/rainbows.rb b/lib/rainbows.rb index 9d81a2e..8a41586 100644 --- a/lib/rainbows.rb +++ b/lib/rainbows.rb @@ -79,6 +79,7 @@ module Rainbows :EventMachine => 50, :FiberSpawn => 50, :FiberPool => 50, + :ActorSpawn => 50, }.each do |model, _| u = model.to_s.gsub(/([a-z0-9])([A-Z0-9])/) { "#{$1}_#{$2.downcase!}" } autoload model, "rainbows/#{u.downcase!}" diff --git a/lib/rainbows/actor_spawn.rb b/lib/rainbows/actor_spawn.rb new file mode 100644 index 0000000..5d86417 --- /dev/null +++ b/lib/rainbows/actor_spawn.rb @@ -0,0 +1,58 @@ +# -*- encoding: binary -*- + +require 'actor' +module Rainbows + module ActorSpawn + include Base + + # runs inside each forked worker, this sits around and waits + # for connections and doesn't die until the parent dies (or is + # given a INT, QUIT, or TERM signal) + def worker_loop(worker) + init_worker_process(worker) + limit = worker_connections + root = Actor.current + clients = {} + + # ticker + Actor.spawn do + while true + sleep 1 + G.tick + end + end + + listeners = LISTENERS.map do |s| + Actor.spawn(s) do |l| + begin + while clients.size >= limit + logger.info "busy: clients=#{clients.size} >= limit=#{limit}" + Actor.receive { |filter| filter.when(:resume) {} } + end + Actor.spawn(l.accept) do |c| + clients[Actor.current] = false + begin + process_client(c) + ensure + root << Actor.current + end + end + rescue Errno::EAGAIN, Errno::ECONNABORTED + rescue => e + Error.listen_loop(e) + end while G.alive + end + end + + begin + Actor.receive do |filter| + filter.when(Actor) do |actor| + orig = clients.size + clients.delete(actor) + orig >= limit and listeners.each { |l| l << :resume } + end + end + end while G.alive || clients.size > 0 + end + end +end -- cgit v1.2.3-24-ge0c7