Class: StartRunJob

Inherits:
ApplicationJob show all
Defined in:
app/jobs/start_run_job.rb

Instance Method Summary collapse

Instance Method Details

#perform(card_id) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'app/jobs/start_run_job.rb', line 4

def perform(card_id)
  card = Card.find(card_id)
  column = card.column
  return unless column.execution? && column.ai?
  return if column.at_wip_limit? # stays queued; kicked when a slot frees

  # Atomic claim (§ races): two kicks can enqueue this job twice for the
  # same card; exactly one claimer flips queued→working, the rest no-op.
  return unless Card.where(id: card.id, status: "queued")
                    .update_all(status: "working", updated_at: Time.current) == 1
  card.reload.touch # update_all skips callbacks — nudge the board broadcast

  # Re-check AFTER claiming: claims are atomic, so an over-subscribed slot
  # shows up as strictly more running than allowed and the loser un-claims
  # back into the queue (the next kick retries it).
  if column.at_wip_limit_exceeded?
    card.update!(status: "queued")
    return
  end

  # Record the model the session actually runs on — the card's effective
  # (possibly overridden) model, not the raw column default (card #33).
  session = card.agent_sessions.create!(status: "provisioning", model: card.effective_model)
  run = session.runs.create!(status: "queued", briefing: { "card" => card.title, "column" => column.name })
  Agent::Runner.start(run)
end