Class: EdiAmazonPendingFeedWorker
- Inherits:
-
Object
- Object
- EdiAmazonPendingFeedWorker
- Includes:
- Sidekiq::Job
- Defined in:
- app/workers/edi_amazon_pending_feed_worker.rb
Overview
Hourly: delivers Amazon feeds that were BUILT and then deferred, rather than
leaving them to rot until the next daily flow.
The gap this closes. Amazon's flows run once a day (every_x_hour: 24), and
the partner loop hits the marketplaces in a fixed order. SP-API meters
createFeed per SELLER ACCOUNT, and the EU account admits exactly five before
it throttles — measured twice on 2026-08-05, fr/be/de/es/it through and
nl/pl/se 429'd on both the 00:00 inventory and 00:30 price runs, five
submissions inside sixteen seconds. Amazon sends no Retry-After on a 429, so
Edi::Amazon::FeedMessageSender#defer falls back to +1 hour — and nothing
ran at +1 hour. The next attempt was the following midnight, where the same
three marketplaces were last in line again.
Deterministic, permanent starvation of exactly the trailing partners. That is
why nl/pl/se shipped no inventory or price feed between 2026-06-16 and
2026-08-04 while their neighbours were fine — see
doc/troubleshooting/MENARD_PLAYWRIGHT_OUTAGE_2026_07.md.
The retry machinery already existed and simply had no runner:
transmit_after is set by the deferral, EdiCommunicationLog.requiring_processing
already honours it, and the sender already skips anything still in its window.
This is the missing hourly pass, not new mechanism.
Sends only — it never builds a snapshot. That keeps the daily
should_execute_flow? gate the sole authority on WHAT gets generated, while
delivery retries at a cadence that can actually reach a one-hour deferral.
Edi::Amazon::FeedSubmissionBudget still applies, so a backlog cannot burst.
Scheduled hourly at :20 — see config/sidekiq_production_schedule.yml, between
the discontinue (:15) and price (:30) slots so a retry never lands in the same
minute as a fresh flow.
Constant Summary collapse
- SENDERS =
Feed categories this drains, and the orchestrator method that sends each.
A partner with the feed disabled returns Edi::NullProcessor, whose #process
is a no-op, so no per-partner gating is needed here. { 'inventory_advice' => :inventory_message_sender, 'price_advice' => :price_message_sender, 'listing_feed_data' => :listing_message_feed_sender }.freeze
Instance Method Summary collapse
Instance Method Details
#perform ⇒ void
This method returns an undefined value.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'app/workers/edi_amazon_pending_feed_worker.rb', line 49 def perform pending.each do |partner, category| orchestrator = Edi::Amazon::Orchestrator.new(partner.to_sym) next unless orchestrator.try(:active).to_b sent = orchestrator.public_send(SENDERS.fetch(category)).process Rails.logger.info "[EdiAmazonPendingFeedWorker] #{partner}/#{category}: " \ "retried #{Array(sent).size} deferred feed(s)" rescue StandardError => e # One partner's failure must not strand the rest of the backlog. ErrorReporting.error(e, source: :background, partner: partner, category: category, message: "Pending Amazon feed retry failed for #{partner}/#{category}") end end |