-
Notifications
You must be signed in to change notification settings - Fork 127
Closed
Description
Current implementation of PubSub Broker is not fault tolerant, which means that if one error handler will fail the "broadcasting" will stop processing event by other handlers which were added after failing one.
Because of current implementation of the broker I had to install such error isolation layer:
Configuration:
...
def setup_event_handler_strategy
Rails.configuration.event_handler_strategy =
%w[development test].include?(Rails.env) ? :throw : :notify
end
....Usage of Error handling strategy:
module Infra
module EventHandlers
include Contracts::Core
include Contracts::Builtin
class UnknownHandlerStrategy < StandardError
end
Contract Config => Any
def connect(event_handler_config)
@configs ||= []
@configs << event_handler_config.handlers
end
Contract KeywordArgs[event_store: RailsEventStore::Client,
event_handler_error_strategy: Optional[EventHandlerErrorStrategy]] => Any
def register(event_store: Rails.configuration.core.event_store,
event_handler_error_strategy: EventHandlerErrorStrategy.new)
configs.flatten.each do |c|
events = c.fetch(:events)
handler = event_handler_error_strategy.build_error_handler(c.fetch(:handler), events)
event_store.subscribe(handler, events)
end
end
attr_reader :configs
end
endImplementation of Error handling strategy :
module Infra
class EventHandlerErrorStrategy
def initialize(event_handler_strategy: Rails.configuration.event_handler_strategy)
@strategy = event_handler_strategy
end
def build_error_handler(handler, events)
send_handler_info(handler, events)
case strategy
when :notify
->(event) { notify_error_handler(handler, event) }
when :throw
->(event) { handler.call(event) }
else
raise UnknownHandlerStrategy
end
end
private
def send_handler_info(handler, events)
for_events = " - for events: #{events.inspect}"
with_strategy = " - with '#{strategy}' strategy"
message = "event handler registered #{handler}\n#{for_events}\n#{with_strategy}"
if %w[development test].include?(Rails.env)
puts message
else
Rails.logger.info message
end
end
def notify_error_handler(handler, event)
handler.call(event)
rescue StandardError => ex
Airbrake.notify(ex)
end
attr_reader :strategy
end
endMetadata
Metadata
Assignees
Labels
No labels