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 116 def deregister(io) 117 @selectables.delete(io) 118 end
# File lib/httpx/selector.rb 40 def each(&blk) 41 @selectables.each(&blk) 42 end
# File lib/httpx/selector.rb 90 def each_connection(&block) 91 return enum_for(__method__) unless block 92 93 @selectables.each do |c| 94 case c 95 when Resolver::Resolver 96 c.each_connection(&block) 97 when Connection 98 yield c 99 end 100 end 101 end
# File lib/httpx/selector.rb 103 def find_connection(request_uri, options) 104 each_connection.find do |connection| 105 connection.match?(request_uri, options) 106 end 107 end
# File lib/httpx/selector.rb 109 def find_mergeable_connection(connection) 110 each_connection.find do |ch| 111 ch != connection && ch.mergeable?(connection) 112 end 113 end
# File lib/httpx/selector.rb 82 def find_resolver(options) 83 res = @selectables.find do |c| 84 c.is_a?(Resolver::Resolver) && options == c.options 85 end 86 87 res.multi if res 88 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 121 def register(io) 122 return if @selectables.include?(io) 123 124 @selectables << io 125 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