Class: PgEventstore::Callbacks

Inherits:
Object
  • Object
show all
Defined in:
lib/pg_eventstore/callbacks.rb

Overview

Allows you to define before, around and after callbacks withing the certain action. It is especially useful during asynchronous programming when you need to be able to react on asynchronous actions from the outside. Example:

class MyAwesomeClass
  attr_reader :callbacks

  def initialize
    @callbacks = PgEventstore::Callbacks.new
  end

  def do_something
    Thread.new do
      @callbacks.run_callbacks(:something_happened) do
        puts "I did something useful!"
      end
    end
  end

  def do_something_else
    @callbacks.run_callbacks(:something_else_happened, :foo, bar: :baz) do
      puts "Something else happened!"
    end
  end
end

obj = MyAwesomeClass.new
obj.callbacks.define_callback(:something_happened, :before, proc { puts "In before callback" })
obj.callbacks.define_callback(:something_happened, :after, proc { puts "In after callback" })
obj.callbacks.define_callback(
  :something_happened, :around,
  proc { |action| puts "In around before action"; action.call; puts "In around after action" }
)
obj.do_something

Outputs:

In before callback
In around callback before action
I did something useful!
In around callback after action
In after callback

Please note, that it is important to call action.call in around callback. Otherwise action simply won’t be called.

Optionally you can provide any set of arguments to #run_callbacks method. They will be passed to your callbacks functions then. Example:

obj = MyAwesomeClass.new
obj.callbacks.define_callback(
  :something_else_happened, :before,
  proc { |*args, **kwargs| puts "In before callback. Args: #{args}, kwargs: #{kwargs}." }
)
obj.callbacks.define_callback(
  :something_else_happened, :after,
  proc { |*args, **kwargs| puts "In after callback. Args: #{args}, kwargs: #{kwargs}." }
)
obj.callbacks.define_callback(
  :something_else_happened, :around,
  proc { |action, *args, **kwargs|
    puts "In around before action. Args: #{args}, kwargs: #{kwargs}."
    action.call
    puts "In around after action. Args: #{args}, kwargs: #{kwargs}."
  }
)
obj.do_something_else

Outputs:

In before callback. Args: [:foo], kwargs: {:bar=>:baz}.
In around before action. Args: [:foo], kwargs: {:bar=>:baz}.
I did something useful!
In around after action. Args: [:foo], kwargs: {:bar=>:baz}.
In after callback. Args: [:foo], kwargs: {:bar=>:baz}.

Instance Method Summary collapse

Constructor Details

#initializeCallbacks

Returns a new instance of Callbacks.



73
74
75
# File 'lib/pg_eventstore/callbacks.rb', line 73

def initialize
  @callbacks = {}
end

Instance Method Details

#clearvoid

This method returns an undefined value.

Clear all defined callbacks



110
111
112
# File 'lib/pg_eventstore/callbacks.rb', line 110

def clear
  @callbacks.clear
end

#define_callback(action, filter, callback) ⇒ void

This method returns an undefined value.

Parameters:

  • action (Object)

    an object, that represents your action. In most cases you want to use a symbol there

  • filter (Symbol)

    callback filter. Supported values are :before, :after and :around

  • callback (#call)


81
82
83
84
85
# File 'lib/pg_eventstore/callbacks.rb', line 81

def define_callback(action, filter, callback)
  @callbacks[action] ||= {}
  @callbacks[action][filter] ||= []
  @callbacks[action][filter].push(callback)
end

#remove_callback(action, filter, callback) ⇒ void

This method returns an undefined value.

Parameters:

  • action (Object)
  • filter (Symbol)
  • callback (#call)


102
103
104
105
106
# File 'lib/pg_eventstore/callbacks.rb', line 102

def remove_callback(action, filter, callback)
  return unless @callbacks.dig(action, filter)

  @callbacks[action][filter].delete(callback)
end

#run_callbacks(action, *args, **kwargs, &blk) ⇒ Object

Returns the result of passed block.

Parameters:

  • action (Object)

    an action to run

Returns:

  • (Object)

    the result of passed block



89
90
91
92
93
94
95
96
# File 'lib/pg_eventstore/callbacks.rb', line 89

def run_callbacks(action, *args, **kwargs, &blk)
  return (yield if block_given?) unless @callbacks[action]

  run_before_callbacks(action, *args, **kwargs)
  result = run_around_callbacks(action, *args, **kwargs, &blk)
  run_after_callbacks(action, *args, **kwargs)
  result
end