Class: EdiInventoryFlowWorker
- Inherits:
-
Object
- Object
- EdiInventoryFlowWorker
- Includes:
- Sidekiq::Job, Workers::EdiFlowDispatch
- Defined in:
- app/workers/edi_inventory_flow_worker.rb
Overview
Sidekiq worker: edi inventory flow.
+lock_ttl+ is the ceiling on how long ONE wedged partner can suppress the feed
for EVERY partner. This worker walks all orchestrators sequentially, and the
global +lock: :until_and_while_executing+ with +on_conflict: :log+ (see
config/initializers/sidekiq.rb) means a run that HANGS holds the RUN lock and
every later scheduled enqueue is coalesced away with a log line — no dead job,
no retry, no AppSignal incident. That is how a hung Menard portal upload
stopped Wayfair/Walmart/CommerceHub/Amazon/reseller inventory for 8.5 hours on
2026-08-02 (doc/troubleshooting/MENARD_PLAYWRIGHT_OUTAGE_2026_07.md).
2h is a ceiling, not an SLA: a real run of every partner finishes in seconds,
so the TTL can only expire on a wedge and never lets two healthy runs overlap.
Applied to every EDI +execute_flow+ worker for the same reason.
It DOES admit one overlap — a TTL that expires while the wedged run is still
alive lets the next scheduled run start alongside it. That is the trade: one
overlapping run beats no runs until someone notices, and every message this
flow sends is a full snapshot, so a duplicate is wasteful rather than wrong.
An advisory lock spanning the flow was rejected because a hung job holds its
DB session, so the lock would never release and we would be back to the
original bug. Per-flow analysis:
doc/troubleshooting/MENARD_PLAYWRIGHT_OUTAGE_2026_07.md § "The overlap
lock_ttl buys".
Instance Method Summary collapse
-
#perform(options = {}) ⇒ String, Array
Batch id when fanned out, results when targeted.
Methods included from Workers::EdiFlowDispatch
Instance Method Details
#perform(options = {}) ⇒ String, Array
Returns batch id when fanned out, results when targeted.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'app/workers/edi_inventory_flow_worker.rb', line 37 def perform( = {}) ErrorReporting.scoped({ job: self.class.name, jid: jid, orchestrator_name: ['orchestrator_name'], partner: ['partner'], options: , worker_start_time: Time.current.iso8601, worker_host: Socket.gethostname }) do dispatch_flow(:execute_inventory_flow, ) rescue StandardError => e ErrorReporting.error(e, { job: self.class.name, jid: jid, options: , error_type: 'inventory_flow_dispatch_error', worker_host: Socket.gethostname, message: "Error dispatching inventory flow: #{.inspect}" }) raise end end |