Class: RelayGrid::Resources::Deliveries

Inherits:
Object
  • Object
show all
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

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

Parameters:

  • id (Integer, String)

Returns:

Raises:



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.

Parameters:

  • ids (Array<Integer>)

Returns:



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.

Parameters:

  • ids (Array<Integer>)
  • timeout (Numeric) (defaults to: 30)

    seconds

  • interval (Numeric) (defaults to: 2)

    seconds between polls

  • raise_on_timeout (Boolean) (defaults to: false)

Returns:

Raises:



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