preliminary ActorSpawn model for Rubinius
[rainbows.git] / lib / rainbows / actor_spawn.rb
blob5d86417491e0bfecedc76df42440634bc7ce8a80
1 # -*- encoding: binary -*-
3 require 'actor'
4 module Rainbows
5   module ActorSpawn
6     include Base
8     # runs inside each forked worker, this sits around and waits
9     # for connections and doesn't die until the parent dies (or is
10     # given a INT, QUIT, or TERM signal)
11     def worker_loop(worker)
12       init_worker_process(worker)
13       limit = worker_connections
14       root = Actor.current
15       clients = {}
17       # ticker
18       Actor.spawn do
19         while true
20           sleep 1
21           G.tick
22         end
23       end
25       listeners = LISTENERS.map do |s|
26         Actor.spawn(s) do |l|
27           begin
28             while clients.size >= limit
29               logger.info "busy: clients=#{clients.size} >= limit=#{limit}"
30               Actor.receive { |filter| filter.when(:resume) {} }
31             end
32             Actor.spawn(l.accept) do |c|
33               clients[Actor.current] = false
34               begin
35                 process_client(c)
36               ensure
37                 root << Actor.current
38               end
39             end
40           rescue Errno::EAGAIN, Errno::ECONNABORTED
41           rescue => e
42             Error.listen_loop(e)
43           end while G.alive
44         end
45       end
47       begin
48         Actor.receive do |filter|
49           filter.when(Actor) do |actor|
50             orig = clients.size
51             clients.delete(actor)
52             orig >= limit and listeners.each { |l| l << :resume }
53           end
54         end
55       end while G.alive || clients.size > 0
56     end
57   end
58 end