Class: PatientHttp::Client
- Inherits:
-
Object
- Object
- PatientHttp::Client
- Defined in:
- lib/patient_http/client.rb
Instance Method Summary collapse
-
#close ⇒ void
Close all clients and release resources.
-
#decode_response(response_data) ⇒ Hash
Decode raw response data into deliverable response data.
-
#initialize(processor) ⇒ Client
constructor
A new instance of Client.
-
#make_request(request, request_id) ⇒ Hash
Make an asynchronous HTTP request.
Constructor Details
#initialize(processor) ⇒ Client
Returns a new instance of Client.
5 6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/patient_http/client.rb', line 5 def initialize(processor) @processor = processor @client_pool = ClientPool.new( max_size: config.connection_pool_size, connection_timeout: config.connection_timeout, proxy_url: config.proxy_url, retries: config.retries, protocol: config.protocol, connection_limit: config.max_connections_per_host ) @response_reader = ResponseReader.new(@processor) @request_preparer = RequestPreparer.new(config) end |
Instance Method Details
#close ⇒ void
This method returns an undefined value.
Close all clients and release resources.
85 86 87 |
# File 'lib/patient_http/client.rb', line 85 def close @client_pool.close end |
#decode_response(response_data) ⇒ Hash
Decode raw response data into deliverable response data.
Joins and inflates the raw body chunks, applies the charset, and rewrites the content-encoding header to name only the encodings still applied to the body. The header is removed when nothing is left, and kept when the server used an encoding the reader cannot decode, so the delivered response always describes the body it carries. This is CPU-bound work intended to run on a completion worker thread.
74 75 76 77 78 79 80 |
# File 'lib/patient_http/client.rb', line 74 def decode_response(response_data) headers = response_data[:headers] body = @response_reader.decode_body(response_data[:body], headers) headers = ResponseReader.rewrite_content_encoding(headers) response_data.merge(headers: headers, body: body) end |
#make_request(request, request_id) ⇒ Hash
Make an asynchronous HTTP request.
The returned body is the array of raw (possibly compressed) body chunks; use #decode_response to produce the final body string. Splitting the decode out keeps CPU-bound work off the reactor thread.
28 29 30 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 58 59 60 |
# File 'lib/patient_http/client.rb', line 28 def make_request(request, request_id) async_response = nil begin outgoing = @request_preparer.prepare(request, request_id) url = outgoing.url headers = outgoing.headers.to_h body = Protocol::HTTP::Body::Buffered.wrap([request.body.to_s]) if request.body timeout = request.timeout || config.request_timeout Async::Task.current.with_timeout(timeout) do async_response = @client_pool.request(request.http_method, url, headers, body) # Note: headers that appear multiple times (e.g. set-cookie) are # flattened to a single joined string value. headers_hash = async_response.headers.to_h.transform_values(&:to_s) body = @response_reader.read_raw_body(async_response, headers_hash) { status: async_response.status, headers: headers_hash, body: body } end rescue => e # Close the response and evict the client for this host to ensure the # stale connection is not reused for subsequent requests. async_response&.close if connection_error?(e) @client_pool.evict(request.url) end raise end end |