class Concurrent::CopyOnNotifyObserverSet
prevent concurrency issues
a notification is required the internal data structure is copied to
observers are added and removed from a thread safe collection; every time
A thread safe observer set implemented using copy-on-read approach:
def add_observer(observer, func=:update)
-
(Symbol)- the added function
Parameters:
-
func(Symbol) -- the function to call on the observer during notification. Default is :update -
observer(Object) -- the observer to add
def add_observer(observer, func=:update) @mutex.synchronize { @observers[observer] = func } end
def count_observers
-
(Integer)- the observers count
def count_observers @mutex.synchronize { @observers.count } end
def delete_observer(observer)
-
(Object)- the deleted observer
Parameters:
-
observer(Object) -- the observer to remove
def delete_observer(observer) @mutex.synchronize { @observers.delete(observer) } observer end
def delete_observers
-
(CopyOnWriteObserverSet)- self
def delete_observers @mutex.synchronize { @observers.clear } self end
def duplicate_and_clear_observers
def duplicate_and_clear_observers @mutex.synchronize do observers = @observers.dup @observers.clear observers end end
def initialize
def initialize @mutex = Mutex.new @observers = {} end
def notify_and_delete_observers(*args, &block)
-
(CopyOnWriteObserverSet)- self
Parameters:
-
args(Object) -- arguments to be passed to each observer
def notify_and_delete_observers(*args, &block) observers = duplicate_and_clear_observers notify_to(observers, *args, &block) self end
def notify_observers(*args, &block)
-
(CopyOnWriteObserverSet)- self
Parameters:
-
args(Object) -- arguments to be passed to each observer
def notify_observers(*args, &block) observers = @mutex.synchronize { @observers.dup } notify_to(observers, *args, &block) self end
def notify_to(observers, *args)
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