module Concurrent::Concern::Observable

The [observer pattern](en.wikipedia.org/wiki/Observer_pattern) is one of the most useful design patterns.

The workflow is very simple:

In a single threaded environment the whole pattern is very easy: the `subject` can use a simple data structure to manage all its subscribed `observer`s and every `observer` can react directly to every event without caring about synchronization.

In a multi threaded environment things are more complex. The `subject` must synchronize the access to its data structure and to do so currently we're using two specialized ObserverSet: {Concurrent::Concern::CopyOnWriteObserverSet} and {Concurrent::Concern::CopyOnNotifyObserverSet}.

When implementing and `observer` there's a very important rule to remember: **there are no guarantees about the thread that will execute the callback**

Let's take this example “` class Observer

def initialize
  @count = 0
end

def update
  @count += 1
end

end

obs = Observer.new [obj1, obj2, obj3, obj4].each { |o| o.add_observer(obs) } # execute [obj1, obj2, obj3, obj4] “`

`obs` is wrong because the variable `@count` can be accessed by different threads at the same time, so it should be synchronized (using either a Mutex or an AtomicFixum)

Attributes

observers[RW]

Public Instance Methods

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

@!macro observable_add_observer

Adds an observer to this set. If a block is passed, the observer will be
created by this method and no other params should be passed.

@param [Object] observer the observer to add
@param [Symbol] func the function to call on the observer during notification.
  Default is :update
@return [Object] the added observer
# File lib/concurrent-ruby/concurrent/concern/observable.rb, line 61
def add_observer(observer = nil, func = :update, &block)
  observers.add_observer(observer, func, &block)
end
count_observers() click to toggle source

@!macro observable_count_observers

Return the number of observers associated with this object.

@return [Integer] the observers count
# File lib/concurrent-ruby/concurrent/concern/observable.rb, line 101
def count_observers
  observers.count_observers
end
delete_observer(observer) click to toggle source

@!macro observable_delete_observer

Remove `observer` as an observer on this object so that it will no
longer receive notifications.

@param [Object] observer the observer to remove
@return [Object] the deleted observer
# File lib/concurrent-ruby/concurrent/concern/observable.rb, line 82
def delete_observer(observer)
  observers.delete_observer(observer)
end
delete_observers() click to toggle source

@!macro observable_delete_observers

Remove all observers associated with this object.

@return [Observable] self
# File lib/concurrent-ruby/concurrent/concern/observable.rb, line 91
def delete_observers
  observers.delete_observers
  self
end
with_observer(observer = nil, func = :update, &block) click to toggle source

As `#add_observer` but can be used for chaining.

@param [Object] observer the observer to add @param [Symbol] func the function to call on the observer during notification. @return [Observable] self

# File lib/concurrent-ruby/concurrent/concern/observable.rb, line 70
def with_observer(observer = nil, func = :update, &block)
  add_observer(observer, func, &block)
  self
end