Class: Html2rss::RequestService::Budget
- Inherits:
-
Object
- Object
- Html2rss::RequestService::Budget
- Defined in:
- lib/html2rss/request_service/budget.rb
Overview
Tracks request slots, interaction budget, and wall-clock deadline for one feed build.
HTTP fetches consume request slots; Browserless preload clicks/scrolls/waits consume
interaction budget. Deadline remains on #remaining_timeout_seconds.
Instance Method Summary collapse
-
#consume! ⇒ Integer
Consumes one HTTP request slot.
-
#consume_interaction! ⇒ Integer
Consumes one Browserless preload interaction 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.
-
#initialize(max_requests:, max_interactions: 0, total_timeout_seconds: nil) ⇒ Budget
constructor
A new instance of Budget.
-
#remaining ⇒ Integer
HTTP request slots still available.
-
#remaining_interactions ⇒ Integer
Preload interaction 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:, max_interactions: 0, total_timeout_seconds: nil) ⇒ Budget
Returns a new instance of Budget.
15 16 17 18 19 20 21 22 23 |
# File 'lib/html2rss/request_service/budget.rb', line 15 def initialize(max_requests:, max_interactions: 0, total_timeout_seconds: nil) validate_slot_limits!(max_requests:, max_interactions:) @remaining_requests = max_requests @remaining_interactions = max_interactions @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.
30 31 32 |
# File 'lib/html2rss/request_service/budget.rb', line 30 def consume! consume_request! end |
#consume_interaction! ⇒ Integer
Consumes one Browserless preload interaction slot.
Preload must not steal pagination HTTP request slots.
54 55 56 57 58 59 60 |
# File 'lib/html2rss/request_service/budget.rb', line 54 def consume_interaction! @mutex.synchronize do raise InteractionBudgetExceeded, 'Interaction budget exhausted' if @remaining_interactions.zero? @remaining_interactions -= 1 end end |
#consume_request! ⇒ Integer
Consumes one HTTP request slot.
39 40 41 42 43 44 45 |
# File 'lib/html2rss/request_service/budget.rb', line 39 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.
110 111 112 |
# File 'lib/html2rss/request_service/budget.rb', line 110 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).
99 100 101 102 103 104 |
# File 'lib/html2rss/request_service/budget.rb', line 99 def effective_timeout_seconds(fallback:) timeout = remaining_timeout_seconds || fallback raise RequestTimedOut, 'Request timed out' if timeout <= 0 timeout.to_f end |
#remaining ⇒ Integer
Returns HTTP request slots still available.
64 65 66 |
# File 'lib/html2rss/request_service/budget.rb', line 64 def remaining remaining_requests end |
#remaining_interactions ⇒ Integer
Returns preload interaction slots still available.
76 77 78 |
# File 'lib/html2rss/request_service/budget.rb', line 76 def remaining_interactions @mutex.synchronize { @remaining_interactions } end |
#remaining_requests ⇒ Integer
Returns HTTP request slots still available.
70 71 72 |
# File 'lib/html2rss/request_service/budget.rb', line 70 def remaining_requests @mutex.synchronize { @remaining_requests } end |
#remaining_timeout_seconds ⇒ Float?
Returns the remaining timeout in seconds, or nil if not tracked.
82 83 84 85 86 87 88 |
# File 'lib/html2rss/request_service/budget.rb', line 82 def remaining_timeout_seconds return unless @total_timeout_seconds elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start_time remaining = @total_timeout_seconds - elapsed [remaining, 0.0].max end |