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
urltodest(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 |