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 Attribute Summary collapse
-
#reactor_max ⇒ Object
Maximum number of clients in the selector.
-
#reactor_size ⇒ Object
readonly
Returns the value of attribute reactor_size.
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.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/puma/reactor.rb', line 27 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 @reactor_size = 0 @reactor_max = 0 end |
Instance Attribute Details
#reactor_max ⇒ Object
Maximum number of clients in the selector. Reset with calls to ‘Server.stats`.
21 22 23 |
# File 'lib/puma/reactor.rb', line 21 def reactor_max @reactor_max end |
#reactor_size ⇒ Object (readonly)
Returns the value of attribute reactor_size.
22 23 24 |
# File 'lib/puma/reactor.rb', line 22 def reactor_size @reactor_size 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.
57 58 59 60 61 62 63 |
# File 'lib/puma/reactor.rb', line 57 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.
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/puma/reactor.rb', line 43 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.
66 67 68 69 70 71 72 73 |
# File 'lib/puma/reactor.rb', line 66 def shutdown @input.close begin @selector.wakeup rescue IOError # Ignore if selector is already closed end @thread&.join end |