Class: Puma::Reactor
- Inherits:
-
Object
- Object
- Puma::Reactor
- 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
-
#add(client) ⇒ Object
Add a new client to monitor.
-
#initialize(backend, &block) ⇒ Reactor
constructor
Create a new Reactor to monitor IO objects added by #add.
-
#run(background = true) ⇒ Object
Run the internal select loop, using a background thread by default.
-
#shutdown ⇒ Object
Shutdown the reactor, blocking until the background thread is finished.
Constructor Details
#initialize(backend, &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 28 29 30 31 32 |
# File 'lib/puma/reactor.rb', line 21 def initialize(backend, &block) require 'nio' valid_backends = [:auto, *::NIO::Selector.backends] unless valid_backends.include?(backend) raise ArgumentError.new("unsupported IO selector backend: #{backend} (available backends: #{valid_backends.join(', ')})") end @selector = ::NIO::Selector.new(NIO::Selector.backends.delete(backend)) @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.
49 50 51 52 53 54 55 |
# File 'lib/puma/reactor.rb', line 49 def add(client) @input << client @selector.wakeup true rescue ClosedQueueError, IOError # Ignore if selector is already closed false end |
#run(background = true) ⇒ Object
Run the internal select loop, using a background thread by default.
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/puma/reactor.rb', line 35 def run(background=true) if background @thread = Thread.new do Puma.set_thread_name "reactor" select_loop end else select_loop end end |
#shutdown ⇒ Object
Shutdown the reactor, blocking until the background thread is finished.
58 59 60 61 62 63 64 65 |
# File 'lib/puma/reactor.rb', line 58 def shutdown @input.close begin @selector.wakeup rescue IOError # Ignore if selector is already closed end @thread&.join end |