Class: Html2rss::RequestService::Budget
- Inherits:
-
Object
- Object
- Html2rss::RequestService::Budget
- Defined in:
- lib/html2rss/request_service/budget.rb
Overview
Tracks HTTP request slots and wall-clock deadline for one feed build.
HTTP fetches consume request slots. Deadline remains on #remaining_timeout_seconds.
Instance Method Summary collapse
-
#consume! ⇒ Integer
Consumes one HTTP request slot.
-
#consume_request! ⇒ Integer
Consumes one HTTP request slot.
-
#effective_timeout_ms(fallback:) ⇒ Integer
Milliseconds available for this attempt.
-
#effective_timeout_seconds(fallback:) ⇒ Float
Resolves wall-clock seconds for the next adapter attempt.
-
#elapsed_seconds ⇒ Float
Seconds since this budget was created.
-
#initialize(max_requests:, total_timeout_seconds: nil) ⇒ Budget
constructor
A new instance of Budget.
-
#remaining ⇒ Integer
HTTP request slots still available.
-
#remaining_requests ⇒ Integer
HTTP request slots still available.
-
#remaining_timeout_seconds ⇒ Float?
The remaining timeout in seconds, or nil if not tracked.
Constructor Details
#initialize(max_requests:, total_timeout_seconds: nil) ⇒ Budget
Returns a new instance of Budget.
13 14 15 16 17 18 19 20 |
# File 'lib/html2rss/request_service/budget.rb', line 13 def initialize(max_requests:, total_timeout_seconds: nil) validate_slot_limits!(max_requests:) @remaining_requests = max_requests @start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) @total_timeout_seconds = total_timeout_seconds @mutex = Mutex.new end |
Instance Method Details
#consume! ⇒ Integer
Consumes one HTTP request slot.
27 28 29 |
# File 'lib/html2rss/request_service/budget.rb', line 27 def consume! consume_request! end |
#consume_request! ⇒ Integer
Consumes one HTTP request slot.
36 37 38 39 40 41 42 |
# File 'lib/html2rss/request_service/budget.rb', line 36 def consume_request! @mutex.synchronize do raise RequestBudgetExceeded, 'Request budget exhausted' if @remaining_requests.zero? @remaining_requests -= 1 end end |
#effective_timeout_ms(fallback:) ⇒ Integer
Returns milliseconds available for this attempt.
91 92 93 |
# File 'lib/html2rss/request_service/budget.rb', line 91 def effective_timeout_ms(fallback:) (effective_timeout_seconds(fallback:) * 1000).to_i end |
#effective_timeout_seconds(fallback:) ⇒ Float
Resolves wall-clock seconds for the next adapter attempt.
Prefers the tracked deadline remainder; falls back to the policy total when this Budget was constructed without a timeout (common in unit tests).
80 81 82 83 84 85 |
# File 'lib/html2rss/request_service/budget.rb', line 80 def effective_timeout_seconds(fallback:) timeout = remaining_timeout_seconds || fallback raise RequestTimedOut, 'Request timed out' if timeout <= 0 timeout.to_f end |
#elapsed_seconds ⇒ Float
Returns seconds since this budget was created.
67 68 69 |
# File 'lib/html2rss/request_service/budget.rb', line 67 def elapsed_seconds Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start_time end |
#remaining ⇒ Integer
Returns HTTP request slots still available.
46 47 48 |
# File 'lib/html2rss/request_service/budget.rb', line 46 def remaining remaining_requests end |
#remaining_requests ⇒ Integer
Returns HTTP request slots still available.
52 53 54 |
# File 'lib/html2rss/request_service/budget.rb', line 52 def remaining_requests @mutex.synchronize { @remaining_requests } end |
#remaining_timeout_seconds ⇒ Float?
Returns the remaining timeout in seconds, or nil if not tracked.
58 59 60 61 62 63 |
# File 'lib/html2rss/request_service/budget.rb', line 58 def remaining_timeout_seconds return unless @total_timeout_seconds remaining = @total_timeout_seconds - elapsed_seconds [remaining, 0.0].max end |