Class: Puma::Reactor

Inherits:
Object
  • Object
show all
Defined in:
lib/puma/reactor.rb

Overview

Monitors a collection of IO objects, calling a block whenever any monitored object either receives data or times out, or when the Reactor shuts down.

The waiting/wake up is performed with nio4r, which will use the appropriate backend (libev, Java NIO or just plain IO#select). The call to ‘NIO::Selector#select` will ’wakeup’ any IO object that receives data.

This class additionally tracks a timeout for every added object, and wakes up any object when its timeout elapses.

The implementation uses a Queue to synchronize adding new objects from the internal select loop.

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Reactor

Create a new Reactor to monitor IO objects added by #add. The provided block will be invoked when an IO has data available to read, its timeout elapses, or when the Reactor shuts down.



21
22
23
24
25
26
27
# File 'lib/puma/reactor.rb', line 21

def initialize(&block)
  require 'nio'
  @selector = NIO::Selector.new
  @input = Queue.new
  @timeouts = []
  @block = block
end

Instance Method Details

#add(client) ⇒ Object

Add a new client to monitor. The object must respond to #timeout and #timeout_at. Returns false if the reactor is already shut down.



44
45
46
47
48
49
50
# File 'lib/puma/reactor.rb', line 44

def add(client)
  @input << client
  @selector.wakeup
  true
rescue ClosedQueueError
  false
end

#run(background = true) ⇒ Object

Run the internal select loop, using a background thread by default.



30
31
32
33
34
35
36
37
38
39
# File 'lib/puma/reactor.rb', line 30

def run(background=true)
  if background
    @thread = Thread.new do
      Puma.set_thread_name "reactor"
      select_loop
    end
  else
    select_loop
  end
end

#shutdownObject

Shutdown the reactor, blocking until the background thread is finished.



53
54
55
56
57
58
59
60
# File 'lib/puma/reactor.rb', line 53

def shutdown
  @input.close
  begin
    @selector.wakeup
  rescue IOError # Ignore if selector is already closed
  end
  @thread.join if @thread
end