Class: Solrengine::Sdp::TrackTransferJob

Inherits:
ActiveJob::Base
  • Object
show all
Defined in:
app/jobs/solrengine/sdp/track_transfer_job.rb

Overview

Settles every Transfer row into a terminal state (R6). Two modes, keyed on the row's status:

processing/confirmed 

Deadline exhaustion is checked at the top of perform, BEFORE any SDP I/O, so an SDP outage can never keep a row unsettled past its deadline (an in-poll check would only fire after a successful GET).

API errors never orphan a row (mirrors ProvisionWalletJob's posture): Unavailable/Timeout propagate to retry_on; NotFound flips the row to "unknown" so the memo token — not a 404 poll loop — decides; any other Sdp::Error re-enqueues within the deadline and settles the row failed (message renderable) past it.

Backoff: a simple fixed wait (Configuration#transfer_poll_interval, default 3s) rather than exponential — Solana confirmation latency is bounded at seconds, and expired_transfer_deadline caps total tracking, so growing waits would only delay the verdict.

Inherits ActiveJob::Base directly so the engine never depends on the host app's ApplicationJob (same posture as ProvisionWalletJob).

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.poll_intervalObject



54
55
56
# File 'app/jobs/solrengine/sdp/track_transfer_job.rb', line 54

def self.poll_interval
  Solrengine::Sdp.configuration.transfer_poll_interval.seconds
end

Instance Method Details

#perform(transfer) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'app/jobs/solrengine/sdp/track_transfer_job.rb', line 58

def perform(transfer)
  return if transfer.terminal?
  return if settle_past_deadline(transfer)

  if transfer.unknown?
    reconcile(transfer)
  else
    poll(transfer)
  end
rescue ::Sdp::Unavailable, ::Sdp::Timeout
  raise # transport: retry_on owns backoff and the exhaustion handoff
rescue ::Sdp::NotFound
  # The id provably doesn't exist at SDP — polling it would 404
  # forever. Reconcile by memo token instead: it positively identifies
  # OUR attempt (found → adopt; never found → the deadline settles
  # the row as unsent).
  transfer.update!(status: "unknown")
  reenqueue(transfer)
rescue ::Sdp::Error => e
  # Auth/rate-limit/validation errors must never strand the row in a
  # dead-letter: within the deadline they read as an API hiccup —
  # re-enqueue and try again; past it the row settles failed with the
  # renderable reason.
  if past_deadline?(transfer)
    transfer.settle!("failed", sdp_error: e.message)
  else
    reenqueue(transfer)
  end
end