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/actor_spawn.rb | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/rainbows/actor_spawn.rb (limited to 'lib/rainbows/actor_spawn.rb') 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