Class: BatchKit::Events

Inherits:
Object
  • Object
show all
Defined in:
lib/batch-kit/events.rb

Overview

Manages batch event notifications and subscriptions, which provide a useful means of decoupling different components of the batch library.

The problem we are looking to solve here is that we want our batch jobs, tasks etc to be able to notify interested parties when something happens (e.g. a task starts, a job fails, etc) without these event sources needing to know all the interested parties to notify. We therefore introduce an intermediary, which is the Events system.

Interested parties register their interest in specific events or event classes by subscribing to the events of interest. Framework classes then notify the Event system when an event occurs, and the event system routes these notifications on to all registered subscribers.

One of the problems we need to solve for is how subscribers can define the scope of their interest. Is it all events of a particular type, regardless of source? Or are we only interested in events from a specific source (e.g job or task)?

Defined Under Namespace

Classes: Subscription

Class Method Summary collapse

Class Method Details

.debug=(dbg) ⇒ Object

Enable/disable event debugging



129
130
131
# File 'lib/batch-kit/events.rb', line 129

def debug=(dbg)
    @log = dbg ? LogManager.logger('batch.events') : nil
end

.dump_subscribers(show_event = nil, log = @log) ⇒ Object

Dumps a list of events and their subscribers to the logger



135
136
137
138
139
140
141
142
143
144
# File 'lib/batch-kit/events.rb', line 135

def dump_subscribers(show_event = nil, log = @log)
    if log
        subscribers.each do |event, subs|
            if show_event.nil? || show_event == event
                log.info "Subscribers for event '#{event}':"
                subs.each{ |sub| log.detail sub.inspect }
            end
        end
    end
end

.has_subscribers?(source, event) ⇒ Boolean

Returns whether there are any subscribers for the specified event.

Parameters:

  • source (Object)

    The source of the event

  • event (String)

    The name of the event

Returns:

  • (Boolean)

    whether there are any subscribers for the specified event.



55
56
57
58
# File 'lib/batch-kit/events.rb', line 55

def has_subscribers?(source, event)
    subscribers.has_key?(event) && subscribers[event].size > 0 &&
        subscribers[event].find{ |sub| sub === source }
end

.publish(source, event, *payload) ⇒ Object

Publishes an event to all registered subscribers.

Parameters:

  • source (Object)

    The source from which the event has been generated.

  • event (String)

    The name of the event that has occurred.

  • payload (*Object)

    Arguments passed with the event.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/batch-kit/events.rb', line 101

def publish(source, event, *payload)
    @log.trace "Publishing event '#{event}' for #{source}" if @log
    res = true
    count = 0
    if subscribers.has_key?(event)
        subscribers[event].each do |sub|
            if sub === source
                begin
                    r = sub.callback.call(source, *payload)
                    count += 1
                    res &&= r
                rescue StandardError => ex
                    if sub.raise_on_error
                        raise
                    else
                        STDERR.puts "Exception in '#{event}' event listener for #{source}: #{ex}\n" +
                            "  at: #{ex.backtrace[0...10].join("\n")}"
                    end
                end
            end
        end
        @log.debug "Notified #{count} listeners of '#{event}'" if @log
    end
    res
end

.subscribe(source, event, options = {}, &callback) ⇒ Object

Setup a subscription for a particular event. When a matching event occurs, the supplied block will be called with the published arguments.

Parameters:

  • source (Object)

    The type of source object from which to listen for events.

  • event (String)

    The name of the event to subscribe to.

  • options (Hash) (defaults to: {})

    An options hash defining optional settings for the subscription.

  • callback (Proc)

    A block to be invoked when the event occurs.

Options Hash (options):

  • :position (Fixnum)

    The position within the list to insert the subscriber. Default is to add to the end of the list.



73
74
75
76
77
78
79
80
81
# File 'lib/batch-kit/events.rb', line 73

def subscribe(source, event, options = {}, &callback)
    @log.trace "Adding subscriber for #{source} event '#{event}'" if @log
    position = options.fetch(:position, -1)
    if event.is_a?(Array)
        event.each{ |e| subscribers[e].insert(position, Subscription.new(source, e, options, callback)) }
    else
        subscribers[event].insert(position, Subscription.new(source, event, options, callback))
    end
end

.unsubscribe(source, event) ⇒ Object

Remove a subscriber

Parameters:

  • source (Object)

    The object that is the source of the event from which to unsubscribe.

  • event (String)

    The name of the event to unsubscribe from.



89
90
91
92
# File 'lib/batch-kit/events.rb', line 89

def unsubscribe(source, event)
    @log.trace "Removing subscriber(s) for #{source} event '#{event}'" if @log
    subscribers[event].delete_if{ |sub| sub === source }
end