Class: Ductwork::BranchClaim

Inherits:
Object
  • Object
show all
Defined in:
lib/ductwork/branch_claim.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pipeline_klass) ⇒ BranchClaim

Returns a new instance of BranchClaim.



7
8
9
10
# File 'lib/ductwork/branch_claim.rb', line 7

def initialize(pipeline_klass)
  @pipeline_klass = pipeline_klass
  @claimed_for_advancing_at = nil
end

Instance Attribute Details

#advancementObject (readonly)

Returns the value of attribute advancement.



5
6
7
# File 'lib/ductwork/branch_claim.rb', line 5

def advancement
  @advancement
end

#tokenObject (readonly)

Returns the value of attribute token.



5
6
7
# File 'lib/ductwork/branch_claim.rb', line 5

def token
  @token
end

#transitionObject (readonly)

Returns the value of attribute transition.



5
6
7
# File 'lib/ductwork/branch_claim.rb', line 5

def transition
  @transition
end

Instance Method Details

#latestObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ductwork/branch_claim.rb', line 12

def latest
  # NOTE: an advancement must attach to a live process record so the reaper
  # can find and recover it if this process dies. `Process.current` is only
  # nil when our record was reaped for a stale heartbeat (e.g. host suspend)
  # and the runner has not re-adopted it yet — i.e. the system has already
  # declared this process dead. Claiming as a presumed-dead zombie would
  # create an advancement with a nil `process_id` that no reaper sweep can
  # reach, orphaning the branch. Skip this cycle instead; the runner
  # re-adopts within its heartbeat interval.
  process = Ductwork::Process.current

  return log_no_process if process.nil?

  id = find_candidate_branch_id

  return log_no_branches if id.blank?

  rows_updated = claim_and_setup_records(id, process)

  if rows_updated == 1
    Ductwork::Branch.find(id)
  else
    log_race_condition(id)
  end
rescue ActiveRecord::InvalidForeignKey => e
  # NOTE: our own `process` record was reaped (heartbeat-stale, destroyed)
  # between the nil-check above and `transition.advancements.create!`
  # inside `claim_and_setup_records`. The insert's FK check blocks on the
  # reaper's row lock and then fails once the parent is gone, rolling back
  # the whole claim transaction (branch + transition + advancement) --
  # nothing is left half-committed. Treat it like any other lost claim
  # race instead of letting it propagate and kill the advancer thread.
  log_process_reaped_mid_claim(id, e)
end