class RubyEventStore::Outbox::Repository::Lock

Public Class Methods

obtain(fetch_specification, process_uuid, clock:) click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 35
def self.obtain(fetch_specification, process_uuid, clock:)
  transaction do
    l = get_lock_record(fetch_specification)

    if l.recently_locked?
      :taken
    else
      l.update!(
        locked_by: process_uuid,
        locked_at: clock.now,
      )
      l
    end
  end
rescue ActiveRecord::Deadlocked
  :deadlocked
rescue ActiveRecord::LockWaitTimeout
  :lock_timeout
end
release(fetch_specification, process_uuid) click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 72
def self.release(fetch_specification, process_uuid)
  transaction do
    l = get_lock_record(fetch_specification)
    if !l.locked_by?(process_uuid)
      :not_taken_by_this_process
    else
      l.update!(locked_by: nil, locked_at: nil)
      :ok
    end
  end
rescue ActiveRecord::Deadlocked
  :deadlocked
rescue ActiveRecord::LockWaitTimeout
  :lock_timeout
end

Private Class Methods

get_lock_record(fetch_specification) click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 105
def self.get_lock_record(fetch_specification)
  l = lock_for_split_key(fetch_specification)
  if l.nil?
    begin
      l = create!(format: fetch_specification.message_format, split_key: fetch_specification.split_key)
    rescue ActiveRecord::RecordNotUnique
      l = lock_for_split_key(fetch_specification)
    end
  end
  l
end
lock_for_split_key(fetch_specification) click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 101
def self.lock_for_split_key(fetch_specification)
  lock.find_by(format: fetch_specification.message_format, split_key: fetch_specification.split_key)
end

Public Instance Methods

fetch_specification() click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 96
def fetch_specification
  FetchSpecification.new(format, split_key)
end
locked_by?(process_uuid) click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 88
def locked_by?(process_uuid)
  locked_by.eql?(process_uuid)
end
recently_locked?() click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 92
def recently_locked?
  locked_by && locked_at > RECENTLY_LOCKED_DURATION.ago
end
refresh(clock:) click to toggle source
# File lib/ruby_event_store/outbox/repository.rb, line 55
def refresh(clock:)
  transaction do
    current_process_uuid = locked_by
    lock!
    if locked_by == current_process_uuid
      update!(locked_at: clock.now)
      :ok
    else
      :stolen
    end
  end
rescue ActiveRecord::Deadlocked
  :deadlocked
rescue ActiveRecord::LockWaitTimeout
  :lock_timeout
end