Module: Rainbows::ThreadSpawn

Includes:
Base, WorkerYield
Included in:
ActorSpawn
Defined in:
lib/rainbows/thread_spawn.rb

Overview

Spawns a new thread for every client connection we accept(). This model is recommended for platforms like Ruby (MRI) 1.8 where spawning new threads is inexpensive, but still seems to work well enough with good native threading implementations such as NPTL under Linux on Ruby (MRI/YARV) 1.9

This model should provide a high level of compatibility with all Ruby implementations, and most libraries and applications. Applications running under this model should be thread-safe but not necessarily reentrant.

If you’re using green threads (MRI 1.8) and need to perform DNS lookups, consider using the “resolv-replace” library which replaces parts of the core Socket package with concurrent DNS lookup capabilities.

Instance Method Summary collapse

Methods included from WorkerYield

#worker_yield

Methods included from Base

included, #init_worker_process, #process_client, #reopen_worker_logs, #sig_receiver

Instance Method Details

#accept_loop(klass) ⇒ Object

:nodoc:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rainbows/thread_spawn.rb', line 23

def accept_loop(klass) #:nodoc:
  lock = Mutex.new
  limit = worker_connections
  nr = 0
  LISTENERS.each do |l|
    klass.new do
      begin
        if lock.synchronize { nr >= limit }
          worker_yield
        elsif client = l.kgio_accept
          klass.new(client) do |c|
            begin
              lock.synchronize { nr += 1 }
              c.process_loop
            ensure
              lock.synchronize { nr -= 1 }
            end
          end
        end
      rescue => e
        Rainbows::Error.listen_loop(e)
      end while Rainbows.alive
    end
  end
  sleep 1 while Rainbows.tick || lock.synchronize { nr > 0 }
end

#worker_loop(worker) ⇒ Object

:nodoc:



50
51
52
53
# File 'lib/rainbows/thread_spawn.rb', line 50

def worker_loop(worker) #:nodoc:
  init_worker_process(worker)
  accept_loop(Thread)
end