module Tengine::Core::OptimisticLock

Constants

DEFAULT_RETRY_COUNT

Public Class Methods

update_with_lock_stack() click to toggle source
# File lib/tengine/core/optimistic_lock.rb, line 22
def update_with_lock_stack
  @update_with_lock_stack ||= []
end

Public Instance Methods

__update_with_lock__() click to toggle source
# File lib/tengine/core/optimistic_lock.rb, line 55
def __update_with_lock__
  lock_field_name = self.class.locking_field
  current_version = self.send(lock_field_name)
  hash = as_document.dup.stringify_keys
  hash.delete("_id") # _id not allowed in mod
  new_version = current_version + 1
  hash[lock_field_name.to_s] = new_version
  selector = { :_id => self.id, lock_field_name.to_sym => current_version }
  result = update_in_safe_mode(self.class.collection, selector, hash)
  send("#{lock_field_name}=", new_version)
  result["updatedExisting"] && !result["err"]
end
update_with_lock(options = {}) { || ... } click to toggle source
# File lib/tengine/core/optimistic_lock.rb, line 29
def update_with_lock(options = {})
  unless Tengine::Core::OptimisticLock.update_with_lock_stack.empty?
    Tengine.logger.warn("Tengine::Core::OptimisticLock#update_with_lock is used in another #update_with_lock.\n  " << caller.join("\n  "))
    Tengine::Core::OptimisticLock.update_with_lock_stack.each do |obj|
      Tengine.logger.warn("-" * 100)
      Tengine.logger.warn("invocation from: #{obj}")
    end
    Tengine.logger.warn("-" * 100)
    Tengine.logger.warn("and invocation from: #{self.inspect}")
  end
  Tengine::Core::OptimisticLock.update_with_lock_stack.push(self.inspect)
  begin
    retry_count = options[:retry] || DEFAULT_RETRY_COUNT
    idx = 1
    while idx <= retry_count
      yield
      return if __update_with_lock__
      reload
      idx += 1
    end
    raise RetryOverError, "retried #{retry_count} times but failed to update"
  ensure
    Tengine::Core::OptimisticLock.update_with_lock_stack.pop
  end
end