class HTTPX::Selector

  1. lib/httpx/selector.rb
Superclass: Object

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 :closed when disposed of resources.

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.

Public Class methods

new()
[show source]
   # File lib/httpx/selector.rb
34 def initialize
35   @timers = Timers.new
36   @selectables = []
37   @is_timer_interval = false
38 end

Public Instance methods

deregister(io)

deregisters io from selectables.

[show source]
    # File lib/httpx/selector.rb
122 def deregister(io)
123   @selectables.delete(io)
124 end
each_connection(&block)
[show source]
    # File lib/httpx/selector.rb
 96 def each_connection(&block)
 97   return enum_for(__method__) unless block
 98 
 99   @selectables.each do |c|
100     case c
101     when Resolver::Resolver
102       c.each_connection(&block)
103     when Connection
104       yield c
105     end
106   end
107 end
empty?()
[show source]
   # File lib/httpx/selector.rb
40 def empty?
41   @selectables.empty? && @timers.empty?
42 end
find_connection(request_uri, options)
[show source]
    # File lib/httpx/selector.rb
109 def find_connection(request_uri, options)
110   each_connection.find do |connection|
111     connection.match?(request_uri, options)
112   end
113 end
find_mergeable_connection(connection)
[show source]
    # File lib/httpx/selector.rb
115 def find_mergeable_connection(connection)
116   each_connection.find do |ch|
117     ch != connection && ch.mergeable?(connection)
118   end
119 end
find_resolver(options)
[show source]
   # File lib/httpx/selector.rb
87 def find_resolver(options)
88   res = @selectables.find do |c|
89     c.is_a?(Resolver::Resolver) &&
90       options.resolver_options_match?(c.options)
91   end
92 
93   res.multi if res
94 end
initial_call()

first time the registered selectables are added, there’s probably work to do.

[show source]
   # File lib/httpx/selector.rb
45 def initial_call
46   @selectables.each(&:initial_call)
47 end
next_tick()
[show source]
   # File lib/httpx/selector.rb
49 def next_tick
50   catch(:jump_tick) do
51     timeout = next_timeout
52     if timeout && timeout.negative?
53       @timers.fire
54       throw(:jump_tick)
55     end
56 
57     begin
58       select(timeout) do |c|
59         c.log(level: 2) { "[#{c.state}] selected from selector##{object_id} #{" after #{timeout} secs" unless timeout.nil?}..." }
60 
61         c.call
62       end
63 
64       @timers.fire
65     rescue TimeoutError => e
66       @timers.fire(e)
67     end
68   end
69 end
register(io)

register io.

[show source]
    # File lib/httpx/selector.rb
127 def register(io)
128   return if @selectables.include?(io)
129 
130   @selectables << io
131 end
terminate()
[show source]
   # File lib/httpx/selector.rb
71 def terminate
72   # array may change during iteration
73   selectables = @selectables.reject(&:inflight?)
74 
75   selectables.delete_if do |sel|
76     sel.terminate
77     sel.state == :closed
78   end
79 
80   until selectables.empty?
81     next_tick
82 
83     selectables &= @selectables
84   end
85 end