Class: HTTPX::Session
- Inherits:
-
Object
- Object
- HTTPX::Session
- Defined in:
- lib/httpx/session.rb,
lib/httpx/session2.rb
Overview
Class implementing the APIs being used publicly.
HTTPX.get(..) #=> delegating to an internal HTTPX::Session object.
HTTPX.plugin(..).get(..) #=> creating an intermediate HTTPX::Session with plugin, then sending the GET request
Constant Summary
Constants included from Loggable
Loggable::COLORS, Loggable::USE_DEBUG_LOG
Class Attribute Summary collapse
-
.default_options ⇒ Object
readonly
Returns the value of attribute default_options.
Class Method Summary collapse
- .inherited(klass) ⇒ Object
-
.plugin(pl, options = nil, &block) ⇒ Object
returns a new HTTPX::Session instance, with the plugin pointed by
pl
loaded.
Instance Method Summary collapse
-
#build_request(verb, uri, params = EMPTY_HASH, options = @options) ⇒ Object
returns a HTTP::Request instance built from the HTTP
verb
, the requesturi
, and the optional set of request-specificoptions
. -
#close(selector = Selector.new) ⇒ Object
closes all the active connections from the session.
- #deselect_connection(connection, selector, cloned = false) ⇒ Object
- #deselect_resolver(resolver, selector) ⇒ Object
-
#find_connection(request_uri, selector, options) ⇒ Object
returns the HTTPX::Connection through which the
request
should be sent through. -
#initialize(options = EMPTY, &blk) ⇒ Session
constructor
initializes the session with a set of
options
, which will be shared by all requests sent from it. -
#request(*args, **params) ⇒ Object
performs one, or multple requests; it accepts:.
- #select_connection(connection, selector) ⇒ Object (also: #select_resolver)
- #try_clone_connection(connection, selector, family) ⇒ Object
-
#wrap ⇒ Object
Yields itself the block, then closes it after the block is evaluated.
Methods included from Chainable
Methods included from Loggable
Constructor Details
#initialize(options = EMPTY, &blk) ⇒ Session
initializes the session with a set of options
, which will be shared by all requests sent from it.
When pass a block, it’ll yield itself to it, then closes after the block is evaluated.
16 17 18 19 20 21 22 23 24 |
# File 'lib/httpx/session.rb', line 16 def initialize( = EMPTY_HASH, &blk) @options = self.class..merge() @responses = {} @persistent = @options.persistent @pool = @options.pool_class.new(@options.) @wrapped = false @closing = false wrap(&blk) if blk end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class HTTPX::Chainable
Class Attribute Details
.default_options ⇒ Object (readonly)
Returns the value of attribute default_options.
465 466 467 |
# File 'lib/httpx/session.rb', line 465 def @default_options end |
Class Method Details
.inherited(klass) ⇒ Object
467 468 469 470 471 472 |
# File 'lib/httpx/session.rb', line 467 def inherited(klass) super klass.instance_variable_set(:@default_options, @default_options) klass.instance_variable_set(:@plugins, @plugins.dup) klass.instance_variable_set(:@callbacks, @callbacks.dup) end |
.plugin(pl, options = nil, &block) ⇒ Object
returns a new HTTPX::Session instance, with the plugin pointed by pl
loaded.
session_with_retries = session.plugin(:retries)
session_with_custom = session.plugin(CustomPlugin)
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 |
# File 'lib/httpx/session.rb', line 479 def plugin(pl, = nil, &block) # raise Error, "Cannot add a plugin to a frozen config" if frozen? pl = Plugins.load_plugin(pl) if pl.is_a?(Symbol) if !@plugins.include?(pl) @plugins << pl pl.load_dependencies(self, &block) if pl.respond_to?(:load_dependencies) @default_options = @default_options.dup include(pl::InstanceMethods) if defined?(pl::InstanceMethods) extend(pl::ClassMethods) if defined?(pl::ClassMethods) opts = @default_options opts.extend_with_plugin_classes(pl) if defined?(pl::OptionsMethods) (pl::OptionsMethods.instance_methods - Object.instance_methods).each do |meth| opts..method_added(meth) end @default_options = opts..new(opts) end @default_options = pl.(@default_options) if pl.respond_to?(:extra_options) @default_options = @default_options.merge() if pl.configure(self, &block) if pl.respond_to?(:configure) @default_options.freeze elsif # this can happen when two plugins are loaded, an one of them calls the other under the hood, # albeit changing some default. @default_options = pl.(@default_options) if pl.respond_to?(:extra_options) @default_options = @default_options.merge() if @default_options.freeze end self end |
Instance Method Details
#build_request(verb, uri, params = EMPTY_HASH, options = @options) ⇒ Object
returns a HTTP::Request instance built from the HTTP verb
, the request uri
, and the optional set of request-specific options
. This request must be sent through the same session it was built from.
req = session.build_request("GET", "https://server.com")
resp = session.request(req)
120 121 122 123 124 125 126 |
# File 'lib/httpx/session.rb', line 120 def build_request(verb, uri, params = EMPTY_HASH, = @options) rklass = .request_class request = rklass.new(verb, uri, , params) request.persistent = @persistent set_request_callbacks(request) request end |
#close(selector = Selector.new) ⇒ Object
closes all the active connections from the session.
when called directly without specifying selector
, all available connections will be picked up from the connection pool and closed. Connections in use by other sessions, or same session in a different thread, will not be reaped.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/httpx/session.rb', line 64 def close(selector = Selector.new) # throw resolvers away from the pool @pool.reset_resolvers # preparing to throw away connections while (connection = @pool.pop_connection) next if connection.state == :closed connection.current_session = self connection.current_selector = selector select_connection(connection, selector) end begin @closing = true selector.terminate ensure @closing = false end end |
#deselect_connection(connection, selector, cloned = false) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/httpx/session.rb', line 134 def deselect_connection(connection, selector, cloned = false) selector.deregister(connection) # when connections coalesce return if connection.state == :idle return if cloned return if @closing && connection.state == :closed @pool.checkin_connection(connection) end |
#deselect_resolver(resolver, selector) ⇒ Object
147 148 149 150 151 152 153 |
# File 'lib/httpx/session.rb', line 147 def deselect_resolver(resolver, selector) selector.deregister(resolver) return if @closing && resolver.closed? @pool.checkin_resolver(resolver) end |
#find_connection(request_uri, selector, options) ⇒ Object
returns the HTTPX::Connection through which the request
should be sent through.
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/httpx/session.rb', line 199 def find_connection(request_uri, selector, ) if (connection = selector.find_connection(request_uri, )) return connection end connection = @pool.checkout_connection(request_uri, ) connection.current_session = self connection.current_selector = selector case connection.state when :idle do_init_connection(connection, selector) when :open select_connection(connection, selector) if .io when :closed connection.idling select_connection(connection, selector) when :closing connection.once(:close) do connection.idling select_connection(connection, selector) end end connection end |
#request(*args, **params) ⇒ Object
performs one, or multple requests; it accepts:
-
one or multiple HTTPX::Request objects;
-
an HTTP verb, then a sequence of URIs or URI/options tuples;
-
one or multiple HTTP verb / uri / (optional) options tuples;
when present, the set of options
kwargs is applied to all of the sent requests.
respectively returns a single HTTPX::Response response, or all of them in an Array, in the same order.
resp1 = session.request(req1)
resp1, resp2 = session.request(req1, req2)
resp1 = session.request("GET", "https://server.org/a")
resp1, resp2 = session.request("GET", ["https://server.org/a", "https://server.org/b"])
resp1, resp2 = session.request(["GET", "https://server.org/a"], ["GET", "https://server.org/b"])
resp1 = session.request("POST", "https://server.org/a", form: { "foo" => "bar" })
resp1, resp2 = session.request(["POST", "https://server.org/a", form: { "foo" => "bar" }], ["GET", "https://server.org/b"])
resp1, resp2 = session.request("GET", ["https://server.org/a", "https://server.org/b"], headers: { "x-api-token" => "TOKEN" })
104 105 106 107 108 109 110 111 112 |
# File 'lib/httpx/session.rb', line 104 def request(*args, **params) raise ArgumentError, "must perform at least one request" if args.empty? requests = args.first.is_a?(Request) ? args : build_requests(*args, params) responses = send_requests(*requests) return responses.first if responses.size == 1 responses end |
#select_connection(connection, selector) ⇒ Object Also known as: select_resolver
128 129 130 |
# File 'lib/httpx/session.rb', line 128 def select_connection(connection, selector) selector.register(connection) end |
#try_clone_connection(connection, selector, family) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/httpx/session.rb', line 155 def try_clone_connection(connection, selector, family) connection.family ||= family return connection if connection.family == family new_connection = connection.class.new(connection.origin, connection.) new_connection.family = family new_connection.current_session = self new_connection.current_selector = selector connection.once(:tcp_open) { new_connection.force_reset(true) } connection.once(:connect_error) do |err| if new_connection.connecting? new_connection.merge(connection) connection.emit(:cloned, new_connection) connection.force_reset(true) else connection.__send__(:handle_error, err) end end new_connection.once(:tcp_open) do |new_conn| if new_conn != connection new_conn.merge(connection) connection.force_reset(true) end end new_connection.once(:connect_error) do |err| if connection.connecting? # main connection has the requests connection.merge(new_connection) new_connection.emit(:cloned, connection) new_connection.force_reset(true) else new_connection.__send__(:handle_error, err) end end do_init_connection(new_connection, selector) new_connection end |
#wrap ⇒ Object
Yields itself the block, then closes it after the block is evaluated.
session.wrap do |http|
http.get("https://wikipedia.com")
end # wikipedia connection closes here
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/httpx/session.rb', line 31 def wrap prev_wrapped = @wrapped @wrapped = true was_initialized = false current_selector = get_current_selector do selector = Selector.new set_current_selector(selector) was_initialized = true selector end begin yield self ensure unless prev_wrapped if @persistent deactivate(current_selector) else close(current_selector) end end @wrapped = prev_wrapped set_current_selector(nil) if was_initialized end end |