Class: PgEventstore::Callbacks
- Inherits:
-
Object
- Object
- PgEventstore::Callbacks
- Defined in:
- lib/pg_eventstore/callbacks.rb,
sig/pg_eventstore/callbacks.rbs
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
-
#clear ⇒ void
Clear all defined callbacks.
-
#define_callback(action, filter, callback) ⇒ void
@param
action— an object, that represents your action. -
#initialize ⇒ Callbacks
constructor
A new instance of Callbacks.
- #remove_callback(action, filter, callback) ⇒ void
- #run_after_callbacks(action, *args, **kwargs) ⇒ void
-
#run_around_callbacks(action, *args, **kwargs) ⇒ Object
The result of the passed block.
- #run_before_callbacks(action, *args, **kwargs) ⇒ void
-
#run_callbacks(action) ⇒ void
@param
action— an action to run.
Constructor Details
#initialize ⇒ Callbacks
Returns a new instance of Callbacks.
73 74 75 |
# File 'lib/pg_eventstore/callbacks.rb', line 73 def initialize @callbacks = {} end |
Instance Method Details
#clear ⇒ void
This method returns an undefined value.
Clear all defined callbacks
112 113 114 |
# File 'lib/pg_eventstore/callbacks.rb', line 112 def clear @callbacks.clear end |
#define_callback(action, filter, callback) ⇒ void
This method returns an undefined value.
@param action — an object, that represents your action. In most cases you want to use a symbol there
@param filter — callback filter. Supported values are :before, :after and :around
@param callback
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.
104 105 106 107 108 |
# File 'lib/pg_eventstore/callbacks.rb', line 104 def remove_callback(action, filter, callback) return unless @callbacks.dig(action, filter) @callbacks[action][filter].delete(callback) end |
#run_after_callbacks(action, *args, **kwargs) ⇒ void
This method returns an undefined value.
142 143 144 145 146 |
# File 'lib/pg_eventstore/callbacks.rb', line 142 def run_after_callbacks(action, *args, **kwargs) @callbacks[action][:after]&.each do |callback| callback.call(*args, **kwargs) end end |
#run_around_callbacks(action, *args, **kwargs) ⇒ Object
Returns the result of the passed block.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/pg_eventstore/callbacks.rb', line 126 def run_around_callbacks(action, *args, **kwargs, &) result = nil stack = [proc { result = yield if block_given? }] @callbacks[action][:around]&.reverse_each&.with_index do |callback, index| stack.push( proc { callback.call(stack[index], *args, **kwargs) result } ) end stack.last.call(*args, **kwargs) result end |
#run_before_callbacks(action, *args, **kwargs) ⇒ void
This method returns an undefined value.
119 120 121 122 123 |
# File 'lib/pg_eventstore/callbacks.rb', line 119 def run_before_callbacks(action, *args, **kwargs) @callbacks[action][:before]&.each do |callback| callback.call(*args, **kwargs) end end |
#run_callbacks(action) ⇒ void
This method returns an undefined value.
@param action — an action to run
90 91 92 93 94 95 96 97 |
# File 'lib/pg_eventstore/callbacks.rb', line 90 def run_callbacks(action, *, **, &) return (yield if block_given?) unless @callbacks[action] run_before_callbacks(action, *, **) result = run_around_callbacks(action, *, **, &) run_after_callbacks(action, *, **) result end |