Class: Collavre::DropTriggerJob

Inherits:
ApplicationJob
  • Object
show all
Defined in:
app/jobs/collavre/drop_trigger_job.rb

Defined Under Namespace

Classes: DispatchFailedError

Instance Method Summary collapse

Instance Method Details

#perform(parent_creative_id, child_creative_id) ⇒ Object

End-to-end idempotent: safe to retry at any point.

  1. Find or create trigger comment (no duplicates)

  2. Check if dispatch already succeeded (Task exists)

  3. Dispatch explicitly if needed (not via after_create_commit)

This avoids the failure mode where:

- Comment is created (committed)
- after_create_commit dispatch fails
- Retry skips everything because comment already exists


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'app/jobs/collavre/drop_trigger_job.rb', line 23

def perform(parent_creative_id, child_creative_id)
  parent = Creative.find_by(id: parent_creative_id)
  child = Creative.find_by(id: child_creative_id)
  return unless parent && child
  return unless parent.drop_trigger_enabled?

  agent = find_trigger_agent(parent)
  unless agent
    post_trigger_failure_notice(child, parent)
    return
  end

  topic = find_or_create_trigger_topic(child, agent)

  # Initialize trigger loop state on the child creative
  initialize_trigger_loop(child, topic)

  # Step 1: Find existing or create new trigger comment (idempotent)
  comment = find_trigger_comment(child, parent, topic) ||
            create_trigger_comment(child, parent, agent, topic)

  # Step 2: Skip if dispatch already produced a Task for this comment
  return if task_exists_for?(comment)

  # Step 3: Dispatch explicitly
  dispatch_trigger(comment)
rescue StandardError => e
  Rails.logger.error(
    "[DropTriggerJob] Failed for parent=#{parent_creative_id} child=#{child_creative_id}: " \
    "#{e.class} #{e.message}\n#{e.backtrace&.first(5)&.join("\n")}"
  )
  raise
end