Module: Ucode::Fetch::Http
- Defined in:
- lib/ucode/fetch/http.rb
Overview
Shared HTTP wrapper. Single network boundary for the whole project.
Streaming download with retries and exponential backoff. Raises Ucode::NetworkError on final failure (after ‘http_retries` attempts).
Class Method Summary collapse
-
.get(url, dest:, retries: nil, timeout: nil) ⇒ Pathname
Stream ‘url` to `dest` (a Pathname or String path).
Class Method Details
.get(url, dest:, retries: nil, timeout: nil) ⇒ Pathname
Stream ‘url` to `dest` (a Pathname or String path).
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 |
# File 'lib/ucode/fetch/http.rb', line 28 def get(url, dest:, retries: nil, timeout: nil) uri = url.is_a?(URI) ? url : URI(url) destination = Pathname.new(dest) destination.dirname.mkpath attempts = retries || Ucode.configuration.http_retries read_timeout = timeout || Ucode.configuration.http_timeout backoff_sequence = DEFAULT_BACKOFF.take(attempts + 1) last_error = nil (attempts + 1).times do |attempt| return stream_to(uri, destination, read_timeout) rescue StandardError => e last_error = e sleep_for = backoff_sequence[attempt] || backoff_sequence.last Ucode.configuration.logger&.warn do "Http GET #{uri} failed (attempt #{attempt + 1}/#{attempts + 1}): " \ "#{e.class}: #{e.}; retrying in #{sleep_for}s" end sleep(sleep_for) end raise Ucode::NetworkError.new( "GET #{uri} failed after #{attempts + 1} attempts", context: { url: uri.to_s, last_error: last_error&. }, ) end |