Class: CollavreOpenclaw::ProcessedAiRun

Inherits:
ApplicationRecord show all
Defined in:
app/models/collavre_openclaw/processed_ai_run.rb

Overview

Durable idempotency key for OpenClaw Gateway runs. Owned by this engine so the run concept stays off core collavre’s general-purpose comments table. comment_id is set when a comment owns the run; ON DELETE SET NULL keeps the row alive as a tombstone after the comment is destroyed (review-fold).

Class Method Summary collapse

Class Method Details

.claim_canonical(run_id, comment) ⇒ Object

The canonical (activity-logged) reply wins: on a lost race it reclaims the run from the proactive duplicate and destroys it, leaving one comment.



41
42
43
44
45
46
47
48
49
# File 'app/models/collavre_openclaw/processed_ai_run.rb', line 41

def self.claim_canonical(run_id, comment)
  return if run_id.blank? || comment.nil?

  create!(run_id: run_id, comment: comment)
rescue ActiveRecord::RecordNotUnique
  reclaim_for(run_id, comment)
rescue StandardError => e
  Rails.logger.warn("[CollavreOpenclaw::ProcessedAiRun] Failed to claim run #{run_id}: #{e.message}")
end

.claim_proactive(run_id, comment) ⇒ Object

Returns false when another process already claimed the run, so the caller discards its duplicate.



27
28
29
30
31
32
33
34
35
36
37
# File 'app/models/collavre_openclaw/processed_ai_run.rb', line 27

def self.claim_proactive(run_id, comment)
  return true if run_id.blank?

  create!(run_id: run_id, comment: comment)
  true
rescue ActiveRecord::RecordNotUnique
  false
rescue StandardError => e
  Rails.logger.warn("[CollavreOpenclaw::ProcessedAiRun] Failed to claim run #{run_id}: #{e.message}")
  false
end

.comment_for(run_id) ⇒ Object



19
20
21
22
23
# File 'app/models/collavre_openclaw/processed_ai_run.rb', line 19

def self.comment_for(run_id)
  return nil if run_id.blank?

  find_by(run_id: run_id)&.comment
end

.processed?(run_id) ⇒ Boolean

Returns:

  • (Boolean)


13
14
15
16
17
# File 'app/models/collavre_openclaw/processed_ai_run.rb', line 13

def self.processed?(run_id)
  return false if run_id.blank?

  exists?(run_id: run_id)
end