class Synapse::Repository::LockingRepository

Partial implementation of a repository that handles integration with a lock manager @abstract

Attributes

lock_manager[R]

@return [LockManager]

Public Class Methods

new(lock_manager) click to toggle source

@param [LockManager] lock_manager @return [undefined]

# File lib/synapse/repository/locking.rb, line 11
def initialize(lock_manager)
  @lock_manager = lock_manager
end

Public Instance Methods

add(aggregate) click to toggle source

@api public @raise [ArgumentError] If the version of the aggregate is not null @param [AggregateRoot] aggregate @return [undefined]

# File lib/synapse/repository/locking.rb, line 45
def add(aggregate)
  @lock_manager.obtain_lock aggregate.id

  begin
    assert_compatible aggregate

    register_aggregate aggregate
    register_listener LockCleaningUnitOfWorkListener.new aggregate.id, @lock_manager

    post_registration aggregate
  rescue
    @lock_manager.release_lock aggregate.id
    raise
  end
end
load(aggregate_id, expected_version = nil) click to toggle source

@api public @raise [AggregateNotFoundError]

If the aggregate with the given identifier could not be found

@raise [ConflictingModificationError]

If the expected version doesn't match the aggregate's actual version

@param [Object] aggregate_id @param [Integer] expected_version If this is nil, no version validation is performed @return [AggregateRoot]

# File lib/synapse/repository/locking.rb, line 23
def load(aggregate_id, expected_version = nil)
  @lock_manager.obtain_lock aggregate_id

  begin
    aggregate = perform_load aggregate_id, expected_version

    register_aggregate aggregate
    register_listener LockCleaningUnitOfWorkListener.new aggregate_id, @lock_manager

    post_registration aggregate

    aggregate
  rescue
    @lock_manager.release_lock aggregate_id
    raise
  end
end

Protected Instance Methods

assert_valid_lock(aggregate) click to toggle source

@raise [ConcurrencyError] If aggregate is versioned and its lock has been invalidated by

the lock manager

@param [AggregateRoot] aggregate @return [undefined]

# File lib/synapse/repository/locking.rb, line 125
def assert_valid_lock(aggregate)
  if aggregate.version && !@lock_manager.validate_lock(aggregate)
    raise ConcurrencyError
  end
end
delete_aggregate(aggregate) click to toggle source

@raise [ConcurrencyError] If aggregate is versioned and its lock has been invalidated by

the lock manager

@param [AggregateRoot] aggregate @return [undefined]

# File lib/synapse/repository/locking.rb, line 107
def delete_aggregate(aggregate)
  assert_valid_lock aggregate
  delete_aggregate_with_lock aggregate
end
delete_aggregate_with_lock(aggregate) click to toggle source

Deletes the given aggregate from the underlying storage mechanism, ensuring that the lock for the aggregate is valid before doing so

@abstract @param [AggregateRoot] aggregate @return [undefined]

# File lib/synapse/repository/locking.rb, line 83
def delete_aggregate_with_lock(aggregate)
  raise NotImplementedError
end
perform_load(aggregate_id, expected_version) click to toggle source

Fetches the aggregate with the given identifier from the underlying aggregate store

@abstract @raise [AggregateNotFoundError]

If the aggregate with the given identifier could not be found

@raise [ConflictingModificationError]

If the expected version doesn't match the aggregate's actual version

@param [Object] aggregate_id @param [Integer] expected_version @return [AggregateRoot]

# File lib/synapse/repository/locking.rb, line 73
def perform_load(aggregate_id, expected_version)
  raise NotImplementedError
end
post_registration(aggregate) click to toggle source

Hook that is called after an aggregate is registered to the current unit of work

@param [AggregateRoot] aggregate @return [undefined]

# File lib/synapse/repository/locking.rb, line 101
def post_registration(aggregate); end
save_aggregate(aggregate) click to toggle source

@raise [ConcurrencyError] If aggregate is versioned and its lock has been invalidated by

the lock manager

@param [AggregateRoot] aggregate @return [undefined]

# File lib/synapse/repository/locking.rb, line 116
def save_aggregate(aggregate)
  assert_valid_lock aggregate
  save_aggregate_with_lock aggregate
end
save_aggregate_with_lock(aggregate) click to toggle source

Saves the given aggregate using the underlying storage mechanism, ensuring that the lock for the aggregate is valid before doing so

@abstract @param [AggregateRoot] aggregate @return [undefined]

# File lib/synapse/repository/locking.rb, line 93
def save_aggregate_with_lock(aggregate)
  raise NotImplementedError
end