Skip to content

Commit

Permalink
Event notification hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Rustam Ibragimov committed Jan 13, 2018
1 parent 5325e06 commit d98c828
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 1 deletion.
5 changes: 5 additions & 0 deletions lib/evil_events/core/events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ module Events
require_relative 'events/event_extensions/class_signature'
require_relative 'events/event_extensions/class_signature/signature'
require_relative 'events/event_extensions/class_signature/equalizer'
require_relative 'events/event_extensions/hookable'
require_relative 'events/event_extensions/hookable/abstract_hook'
require_relative 'events/event_extensions/hookable/after_hook'
require_relative 'events/event_extensions/hookable/before_hook'
require_relative 'events/event_extensions/hookable/on_error_hook'
require_relative 'events/abstract_event'
require_relative 'events/manager'
require_relative 'events/manager/notifier'
Expand Down
2 changes: 2 additions & 0 deletions lib/evil_events/core/events/abstract_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class AbstractEvent
include EventExtensions::MetadataExtendable
# @sicne 0.2.0
include EventExtensions::ClassSignature
# @since 0.3.0
include EventExtensions::Hookable
# @since 0.1.0
extend EvilEvents::Shared::CombinedContext::Mixin

Expand Down
91 changes: 91 additions & 0 deletions lib/evil_events/core/events/event_extensions/hookable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# frozen_string_literal: true

module EvilEvents::Core::Events::EventExtensions
# @api private
# @since 0.3.0
module Hookable
class << self
# @param base_class [Class]
#
# @since 0.3.0
def included(base_class)
base_class.extend(ClassMethods)
end
end

# @api private
# @since 0.3.0
def __call_on_error_hooks__
self.class.__on_error_hooks__.each do |hook|
hook.call(self)
end
end

# @api private
# @since 0.3.0
def __call_before_hooks__
self.class.__before_hooks__.each do |hook|
hook.call(self)
end
end

# @api private
# @since 0.3.0
def __call_after_hooks__
self.class.__after_hooks__.each do |hook|
hook.call(self)
end
end

# @since 0.3.0
module ClassMethods
# @param hook [#call]
#
# @api public
# @since 0.3.0
def before_emit(hook)
__before_hooks__ << BeforeHook.new(hook)
end

# @param hook [#call]
#
# @api public
# @since 0.3.0
def after_emit(hook)
__after_hooks__ << AfterHook.new(hook)
end

# @param hook [#call]
#
# @api public
# @since 0.3.0
def on_error(hook)
__on_error_hooks__ << OnErrorHook.new(hook)
end

# @return [Concurrent::Array<BeforeHook>]
#
# @api private
# @since 0.3.0
def __before_hooks__
@__before_hooks__ ||= Concurrent::Array.new
end

# @return [Concurrent::Array<AfterHook>]
#
# @api private
# @since 0.3.0
def __after_hooks__
@__after_hooks__ ||= Concurrent::Array.new
end

# @return [Concurrent::Array<OnErrorHook>]
#
# @api private
# @since 0.3.0
def __on_error_hooks__
@__on_error_hooks__ ||= Concurrent::Array.new
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

module EvilEvents::Core::Events::EventExtensions::Hookable
# @api private
# @since 0.3.0
class AbstractHook
# @return [#call]
#
# @since 0.3.0
attr_reader :callable

# @param callable [#call]
#
# @since 0.3.0
def initialize(callable)
@callable = callable
end

# @param event [EvilEvents::Core::Events::AbstractEvent]
# @return void
#
# @since 0.3.0
def call(event)
callable.call(event)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module EvilEvents::Core::Events::EventExtensions::Hookable
# @api private
# @since 0.3.0
AfterHook = Class.new(AbstractHook)
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module EvilEvents::Core::Events::EventExtensions::Hookable
# @api private
# @since 0.3.0
BeforeHook = Class.new(AbstractHook)
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module EvilEvents::Core::Events::EventExtensions::Hookable
# @api private
# @since 0.3.0
OnErrorHook = Class.new(AbstractHook)
end
7 changes: 7 additions & 0 deletions lib/evil_events/core/events/manager/notifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,16 @@ def run(manager, event)

manager.subscribers.each do |subscriber|
begin
event.__call_before_hooks__

subscriber.notify(event)

event.__call_after_hooks__

log_activity(event, subscriber, :successful)
rescue StandardError => error
event.__call_on_error_hooks__

errors_stack << error
log_activity(event, subscriber, :failed)
end
Expand Down
10 changes: 10 additions & 0 deletions spec/integration/event_creation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ def process_event(event); end
# method that will be invoked on observers by default (delegator: option)
default_delegator :process_event

# emition hooks
before_emit -> {}
after_emit -> {}
on_error -> {}

# payload keys
payload :user_id, EvilEvents::Types::Strict::Int
payload :utm_link, EvilEvents::Types::Strict::String
Expand Down Expand Up @@ -118,6 +123,11 @@ class UserRegistered < EvilEvents::Event['user_registered']
# method that will be invoked on observers by default (delegator: option)
default_delegator :process_event

# emition hooks
before_emit -> {}
after_emit -> {}
on_error -> {}

# payload keys
payload :user_id, EvilEvents::Types::Strict::Int
payload :utm_link, EvilEvents::Types::Strict::String
Expand Down
2 changes: 1 addition & 1 deletion spec/units/evil_events/core/system/mock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
mocked_method_params = mocked_method_object.parameters

# 2. mocked method signature equals to original method signature
expect(method_params).to match(method_params)
expect(mocked_method_params).to match(method_params)
end
end
end
Expand Down

0 comments on commit d98c828

Please sign in to comment.