Skip to content

Commit

Permalink
Synchronize events within a single thread
Browse files Browse the repository at this point in the history
  • Loading branch information
derekkraan committed Oct 30, 2017
1 parent b2e0441 commit 9344491
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions lib/sequent/core/event_publisher.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
module Sequent
module Core
class EventPublisher
#
# EventPublisher ensures that, for every thread, events will be published in the order in which they are meant to be published.
#
# This potentially introduces a wrinkle into your plans: You therefore should not split a "unit of work" across multiple threads.
#
# If you do not want this, you are free to implement your own version of EventPublisher and configure sequent to use it.
#
class PublishEventError < RuntimeError
attr_reader :event_handler_class, :event

Expand All @@ -15,25 +22,34 @@ def message
end

def initialize
@events_queue = Queue.new
@mutex = Mutex.new
Thread.current[:events_queue] = Queue.new
Thread.current[:events_queue_locked] = false
end

def publish_events(events)
return if configuration.disable_event_handlers
events.each { |event| @events_queue.push(event) }
events.each { |event| events_queue.push(event) }
process_events
end

private

def process_events
# only process events at the highest level
return if @mutex.locked?
def events_queue
Thread.current[:events_queue]
end

@mutex.synchronize do
while(!@events_queue.empty?) do
event = @events_queue.pop
def skip_if_locked(&block)
return if Thread.current[:events_queue_locked]
Thread.current[:events_queue_locked] = true
block.yield
ensure
Thread.current[:events_queue_locked] = false
end

def process_events
skip_if_locked do
while(!events_queue.empty?) do
event = events_queue.pop
configuration.event_handlers.each do |handler|
begin
handler.handle_message event
Expand Down

0 comments on commit 9344491

Please sign in to comment.