Class: Legion::Data::Model::Task

Inherits:
Sequel::Model
  • Object
show all
Defined in:
lib/legion/data/models/task.rb

Constant Summary collapse

TERMINAL_STATUSES =
%w[
  completed complete failed error cancelled canceled timeout timed_out
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.create_idempotent(values, payload: nil, idempotency_key: nil, ttl: nil) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/legion/data/models/task.rb', line 37

def self.create_idempotent(values, payload: nil, idempotency_key: nil, ttl: nil)
  key = idempotency_key || idempotency_key_for(payload || values)
  existing = find_active_by_idempotency_key(key)
  return existing if existing

  expires_at = ttl ? Time.now + ttl : nil
  create(values.merge(idempotency_key: key, idempotency_expires_at: expires_at))
end

.find_active_by_idempotency_key(key, now: Time.now) ⇒ Object



26
27
28
29
30
31
32
33
34
35
# File 'lib/legion/data/models/task.rb', line 26

def self.find_active_by_idempotency_key(key, now: Time.now)
  return nil if key.to_s.empty?
  return nil unless columns.include?(:idempotency_key)

  where(idempotency_key: key)
    .exclude(status: TERMINAL_STATUSES)
    .where { (idempotency_expires_at =~ nil) | (idempotency_expires_at > now) }
    .reverse_order(:created, :id)
    .first
end

.idempotency_key_for(payload) ⇒ Object



22
23
24
# File 'lib/legion/data/models/task.rb', line 22

def self.idempotency_key_for(payload)
  Digest::SHA256.hexdigest(Legion::JSON.dump(canonical_payload(payload)))
end

Instance Method Details

#cancelled?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/legion/data/models/task.rb', line 46

def cancelled?
  !cancelled_at.nil?
end