Skip to content

Commit

Permalink
Allow to specify event type resolver for subscriptions
Browse files Browse the repository at this point in the history
Make implicit explicit. Type resolver is reponsible
for converting event type from anything (class, string, etc)
to event type (string preffered here).

Default implementation (backward compatible) is just
lambda using to_s method to convert event type
given as class or string to string.
  • Loading branch information
mpraglowski authored and mostlyobvious committed Dec 7, 2020
1 parent e272342 commit 094e771
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
19 changes: 19 additions & 0 deletions ruby_event_store/lib/ruby_event_store/spec/subscriptions_lint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,23 @@ def call(event)

expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, handler])
end

it 'subscribes by type of event which is a class' do
handler = TestHandler.new
subscriptions.add_subscription(handler, [Test1DomainEvent])
subscriptions.add_thread_subscription(handler, [Test1DomainEvent])

expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, handler])
expect(subscriptions.all_for(Test1DomainEvent)).to eq([handler, handler])
end

it 'subscribes by type of event which is a class or string with custom type resolver' do
subscriptions = subscriptions_class.new(event_type_resolver: ->(type) { type.to_s.reverse })
handler = TestHandler.new
subscriptions.add_subscription(handler, [Test1DomainEvent])
subscriptions.add_thread_subscription(handler, ['Test1DomainEvent'])

expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, handler])
expect(subscriptions.all_for(Test1DomainEvent)).to eq([handler, handler])
end
end
32 changes: 23 additions & 9 deletions ruby_event_store/lib/ruby_event_store/subscriptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,49 @@

module RubyEventStore
class Subscriptions
def initialize
def initialize(event_type_resolver: default_event_type_resolver)
@event_type_resolver = event_type_resolver
@local = LocalSubscriptions.new
@global = GlobalSubscriptions.new
@thread = ThreadSubscriptions.new
@thread = ThreadSubscriptions.new
end

def add_subscription(subscriber, event_types)
local.add(subscriber, event_types)
local.add(subscriber, resolve_event_types(event_types))
end

def add_global_subscription(subscriber)
global.add(subscriber)
end

def add_thread_subscription(subscriber, event_types)
thread.local.add(subscriber, event_types)
thread.local.add(subscriber, resolve_event_types(event_types))
end

def add_thread_global_subscription(subscriber)
thread.global.add(subscriber)
end

def all_for(event_type)
[local, global, thread].map{|r| r.all_for(event_type)}.reduce(&:+)
resolved_event_type = resolve_event_type(event_type)
[local, global, thread].map{|r| r.all_for(resolved_event_type)}.reduce(&:+)
end

private
attr_reader :local, :global, :thread

def default_event_type_resolver
->(value) { value.to_s }
end

def resolve_event_types(event_types)
event_types.map(&method(:resolve_event_type))
end

def resolve_event_type(type)
@event_type_resolver.call(type)
end

class ThreadSubscriptions
def initialize
@local = ThreadLocalSubscriptions.new
Expand All @@ -51,8 +65,8 @@ def initialize
end

def add(subscription, event_types)
event_types.each{ |type| @subscriptions[type.to_s] << subscription }
->() {event_types.each{ |type| @subscriptions.fetch(type.to_s).delete(subscription) } }
event_types.each{ |type| @subscriptions[type] << subscription }
->() {event_types.each{ |type| @subscriptions.fetch(type).delete(subscription) } }
end

def all_for(event_type)
Expand Down Expand Up @@ -83,8 +97,8 @@ def initialize
end

def add(subscription, event_types)
event_types.each{ |type| @subscriptions.value[type.to_s] << subscription }
->() {event_types.each{ |type| @subscriptions.value.fetch(type.to_s).delete(subscription) } }
event_types.each{ |type| @subscriptions.value[type] << subscription }
->() {event_types.each{ |type| @subscriptions.value.fetch(type).delete(subscription) } }
end

def all_for(event_type)
Expand Down

0 comments on commit 094e771

Please sign in to comment.