Implements the selector loop, where it registers and monitors “Selectable” objects.
A Selectable object is an object which can calculate the interests (:r, :w or :rw, respectively “read”, “write” or “read-write”) it wants to monitor for, and returns (via to_io method) an IO object which can be passed to functions such as IO.select . More exhaustively, a Selectable must implement the following methods:
| state |
returns the state as a Symbol, must return |
| to_io |
returns the IO object. |
| call |
gets called when the IO is ready. |
| interests |
returns the current interests to monitor for, as described above. |
| timeout |
returns nil or an integer, representing how long to wait for interests. |
| handle_socket_timeout(Numeric) |
called when waiting for interest times out. |
Methods
Public Class
Public Instance
Public Class methods
# File lib/httpx/selector.rb 34 def initialize 35 @timers = Timers.new 36 @selectables = [] 37 @is_timer_interval = false 38 end
Public Instance methods
deregisters io from selectables.
# File lib/httpx/selector.rb 117 def deregister(io) 118 @selectables.delete(io) 119 end
# File lib/httpx/selector.rb 91 def each_connection(&block) 92 return enum_for(__method__) unless block 93 94 @selectables.each do |c| 95 case c 96 when Resolver::Resolver 97 c.each_connection(&block) 98 when Connection 99 yield c 100 end 101 end 102 end
# File lib/httpx/selector.rb 40 def empty? 41 @selectables.empty? && @timers.empty? 42 end
# File lib/httpx/selector.rb 104 def find_connection(request_uri, options) 105 each_connection.find do |connection| 106 connection.match?(request_uri, options) 107 end 108 end
# File lib/httpx/selector.rb 110 def find_mergeable_connection(connection) 111 each_connection.find do |ch| 112 ch != connection && ch.mergeable?(connection) 113 end 114 end
# File lib/httpx/selector.rb 82 def find_resolver(options) 83 res = @selectables.find do |c| 84 c.is_a?(Resolver::Resolver) && 85 options.resolver_options_match?(c.options) 86 end 87 88 res.multi if res 89 end
# File lib/httpx/selector.rb 44 def next_tick 45 catch(:jump_tick) do 46 timeout = next_timeout 47 if timeout && timeout.negative? 48 @timers.fire 49 throw(:jump_tick) 50 end 51 52 begin 53 select(timeout) do |c| 54 c.log(level: 2) { "[#{c.state}] selected from selector##{object_id} #{" after #{timeout} secs" unless timeout.nil?}..." } 55 56 c.call 57 end 58 59 @timers.fire 60 rescue TimeoutError => e 61 @timers.fire(e) 62 end 63 end 64 end
register io.
# File lib/httpx/selector.rb 122 def register(io) 123 return if @selectables.include?(io) 124 125 @selectables << io 126 end
# File lib/httpx/selector.rb 66 def terminate 67 # array may change during iteration 68 selectables = @selectables.reject(&:inflight?) 69 70 selectables.delete_if do |sel| 71 sel.terminate 72 sel.state == :closed 73 end 74 75 until selectables.empty? 76 next_tick 77 78 selectables &= @selectables 79 end 80 end