class Concurrent::Collection::CopyOnWriteObserverSet

A thread safe observer set implemented using copy-on-write approach: every time an observer is added or removed the whole internal data structure is duplicated and replaced with a new one.

@api private

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 13
def initialize
  super()
  synchronize { ns_initialize }
end

Public Instance Methods

add_observer(observer = nil, func = :update, &block) click to toggle source

@!macro observable_add_observer

# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 19
def add_observer(observer = nil, func = :update, &block)
  if observer.nil? && block.nil?
    raise ArgumentError, 'should pass observer as a first argument or block'
  elsif observer && block
    raise ArgumentError.new('cannot provide both an observer and a block')
  end

  if block
    observer = block
    func = :call
  end

  synchronize do
    new_observers = @observers.dup
    new_observers[observer] = func
    @observers = new_observers
    observer
  end
end
count_observers() click to toggle source

@!macro observable_count_observers

# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 56
def count_observers
  observers.count
end
delete_observer(observer) click to toggle source

@!macro observable_delete_observer

# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 40
def delete_observer(observer)
  synchronize do
    new_observers = @observers.dup
    new_observers.delete(observer)
    @observers = new_observers
    observer
  end
end
delete_observers() click to toggle source

@!macro observable_delete_observers

# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 50
def delete_observers
  self.observers = {}
  self
end
notify_and_delete_observers(*args, &block) click to toggle source

Notifies all registered observers with optional args and deletes them.

@param [Object] args arguments to be passed to each observer @return [CopyOnWriteObserverSet] self

# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 72
def notify_and_delete_observers(*args, &block)
  old = clear_observers_and_return_old
  notify_to(old, *args, &block)
  self
end
notify_observers(*args, &block) click to toggle source

Notifies all registered observers with optional args @param [Object] args arguments to be passed to each observer @return [CopyOnWriteObserverSet] self

# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 63
def notify_observers(*args, &block)
  notify_to(observers, *args, &block)
  self
end

Protected Instance Methods

ns_initialize() click to toggle source
# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 80
def ns_initialize
  @observers = {}
end

Private Instance Methods

clear_observers_and_return_old() click to toggle source
# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 102
def clear_observers_and_return_old
  synchronize do
    old_observers = @observers
    @observers = {}
    old_observers
  end
end
notify_to(observers, *args) { || ... } click to toggle source
# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 86
def notify_to(observers, *args)
  raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty?
  observers.each do |observer, function|
    args = yield if block_given?
    observer.send(function, *args)
  end
end
observers() click to toggle source
# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 94
def observers
  synchronize { @observers }
end
observers=(new_set) click to toggle source
# File lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb, line 98
def observers=(new_set)
  synchronize { @observers = new_set }
end