Class: RelayGrid::Resources::Deliveries
- Inherits:
-
Object
- Object
- RelayGrid::Resources::Deliveries
- Defined in:
- lib/relaygrid/resources/deliveries.rb
Overview
Delivery status lookup for the ids a send returned.
Constant Summary collapse
- MAX_BATCH_SIZE =
Matches the server's cap (Api::V1::DeliveriesController::MAX_BATCH_SIZE); longer id lists are split across several requests.
100
Instance Method Summary collapse
- #get(id) ⇒ RelayGrid::Delivery
-
#get_all(ids) ⇒ Array<RelayGrid::Delivery>
Batch lookup.
-
#initialize(client) ⇒ Deliveries
constructor
A new instance of Deliveries.
-
#wait_for(ids, timeout: 30, interval: 2, raise_on_timeout: false) ⇒ Array<RelayGrid::Delivery>
Poll until every delivery reaches a success state or
timeoutelapses.
Constructor Details
#initialize(client) ⇒ Deliveries
Returns a new instance of Deliveries.
11 12 13 |
# File 'lib/relaygrid/resources/deliveries.rb', line 11 def initialize(client) @client = client end |
Instance Method Details
#get(id) ⇒ RelayGrid::Delivery
18 19 20 21 |
# File 'lib/relaygrid/resources/deliveries.rb', line 18 def get(id) body = @client.get("/api/v1/deliveries/#{id}") Delivery.new(body["delivery"], client: @client) end |
#get_all(ids) ⇒ Array<RelayGrid::Delivery>
Batch lookup. Ids that don't resolve are simply absent from the result, so one stale id never fails a whole poll.
28 29 30 31 32 33 34 35 36 |
# File 'lib/relaygrid/resources/deliveries.rb', line 28 def get_all(ids) ids = Array(ids).compact return [] if ids.empty? ids.each_slice(MAX_BATCH_SIZE).flat_map do |batch| body = @client.get("/api/v1/deliveries", params: { ids: batch.join(",") }) Array(body["deliveries"]).map { |delivery| Delivery.new(delivery, client: @client) } end end |
#wait_for(ids, timeout: 30, interval: 2, raise_on_timeout: false) ⇒ Array<RelayGrid::Delivery>
Poll until every delivery reaches a success state or timeout elapses.
BLOCKING. This sleeps the calling thread between polls. That is fine in a
background job, a rake task, a script, or a test -- but do not call it
from inside a web request: it pins a request thread for up to timeout
seconds, and enough concurrent sends will exhaust the pool. In a request,
return the delivery ids and let the browser poll #get_all, or subscribe
to the realtime channel with RelayGrid.websocket.
failed is not terminal here: delivery jobs retry, so a failed row can
still flip to sent and then delivered inside the window. Waiting out
the timeout on a genuinely failed delivery is the deliberate trade -- it
mirrors the dashboard, and reporting a transient failure as final is the
worse error.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/relaygrid/resources/deliveries.rb', line 59 def wait_for(ids, timeout: 30, interval: 2, raise_on_timeout: false) ids = Array(ids).compact return [] if ids.empty? deadline = monotonic_now + timeout deliveries = [] loop do deliveries = get_all(ids) return deliveries if deliveries.any? && deliveries.all?(&:success?) # Never sleep past the deadline: the caller's timeout is honoured to # within one request, not rounded up to the next whole interval. remaining = deadline - monotonic_now break if remaining <= 0 sleeper.call([interval, remaining].min) end raise TimeoutWaitingForDeliveries.new(deliveries: deliveries) if raise_on_timeout deliveries end |