class Synapse::Repository::OptimisticLockManager

Lock manager that uses an optimistic locking strategy

This implementation uses the sequence number of an aggregate's last committed event to detect concurrenct access.

Public Class Methods

new() click to toggle source

@return [undefined]

# File lib/synapse/repository/optimistic_lock_manager.rb, line 9
def initialize
  @aggregates = Hash.new
  @mutex = Mutex.new
end

Public Instance Methods

obtain_lock(aggregate_id) click to toggle source

@param [Object] aggregate_id @return [undefined]

# File lib/synapse/repository/optimistic_lock_manager.rb, line 22
def obtain_lock(aggregate_id)
  obtained = false
  until obtained
    lock = lock_for aggregate_id
    obtained = lock && lock.lock
    unless obtained
      remove_lock aggregate_id, lock
    end
  end
end
release_lock(aggregate_id) click to toggle source

@param [Object] aggregate_id @return [undefined]

# File lib/synapse/repository/optimistic_lock_manager.rb, line 35
def release_lock(aggregate_id)
  lock = @aggregates[aggregate_id]
  if lock
    lock.unlock
    if lock.closed?
      remove_lock aggregate_id, lock
    end
  end
end
validate_lock(aggregate) click to toggle source

@param [AggregateRoot] aggregate @return [Boolean]

# File lib/synapse/repository/optimistic_lock_manager.rb, line 16
def validate_lock(aggregate)
  @aggregates.has_key?(aggregate.id) && @aggregates[aggregate.id].validate(aggregate)
end

Private Instance Methods

lock_for(aggregate_id) click to toggle source

@param [Object] aggregate_id @return [OptimisticLock]

# File lib/synapse/repository/optimistic_lock_manager.rb, line 60
def lock_for(aggregate_id)
  @mutex.synchronize do
    if @aggregates.has_key? aggregate_id
      @aggregates[aggregate_id]
    else
      @aggregates[aggregate_id] = OptimisticLock.new
    end
  end
end
remove_lock(aggregate_id, lock) click to toggle source

@param [Object] aggregate_id @param [OptimisticLock] lock @return [undefined]

# File lib/synapse/repository/optimistic_lock_manager.rb, line 50
def remove_lock(aggregate_id, lock)
  @mutex.synchronize do
    if @aggregates.has_key?(aggregate_id) && @aggregates[aggregate_id] === lock
      @aggregates.delete aggregate_id
    end
  end
end