about summary refs log tree commit homepage
path: root/lib/rainbows/actor_spawn.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-11-27 17:59:28 -0800
committerEric Wong <normalperson@yhbt.net>2009-11-27 17:59:53 -0800
commit3cc3c73959c0227ddc732699975a1edb1f0aa2d1 (patch)
treecb06890fec8a1c0c549e9468a9edd8ef85e79009 /lib/rainbows/actor_spawn.rb
parent48ff371c2021e477a1c57bb68dbeecaca21053de (diff)
downloadrainbows-3cc3c73959c0227ddc732699975a1edb1f0aa2d1.tar.gz
It seems to basically work, this is based heavily on the
Revactor one...
Diffstat (limited to 'lib/rainbows/actor_spawn.rb')
-rw-r--r--lib/rainbows/actor_spawn.rb58
1 files changed, 58 insertions, 0 deletions
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