ruby_event_store 0.30.0 → 0.31.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Makefile +6 -1
- data/lib/ruby_event_store.rb +5 -0
- data/lib/ruby_event_store/async_dispatcher.rb +20 -0
- data/lib/ruby_event_store/async_proxy_strategy.rb +9 -0
- data/lib/ruby_event_store/client.rb +204 -45
- data/lib/ruby_event_store/correlated_commands.rb +37 -0
- data/lib/ruby_event_store/event.rb +68 -1
- data/lib/ruby_event_store/link_by_metadata.rb +55 -0
- data/lib/ruby_event_store/mappers/null_mapper.rb +0 -1
- data/lib/ruby_event_store/mappers/protobuf.rb +13 -5
- data/lib/ruby_event_store/pub_sub/broker.rb +22 -50
- data/lib/ruby_event_store/pub_sub/dispatcher.rb +1 -1
- data/lib/ruby_event_store/pub_sub/subscriptions.rb +110 -0
- data/lib/ruby_event_store/spec/broker_lint.rb +76 -0
- data/lib/ruby_event_store/spec/dispatcher_lint.rb +8 -9
- data/lib/ruby_event_store/spec/event_repository_lint.rb +1 -0
- data/lib/ruby_event_store/spec/subscriptions_lint.rb +111 -0
- data/lib/ruby_event_store/specification.rb +60 -0
- data/lib/ruby_event_store/version.rb +1 -1
- metadata +9 -3
- data/lib/ruby_event_store/spec/event_broker_lint.rb +0 -211
@@ -0,0 +1,76 @@
|
|
1
|
+
RSpec.shared_examples :broker do |broker_klass|
|
2
|
+
let(:event) { instance_double(::RubyEventStore::Event, type: 'EventType') }
|
3
|
+
let(:serialized_event) { instance_double(::RubyEventStore::SerializedRecord) }
|
4
|
+
let(:handler) { HandlerClass.new }
|
5
|
+
let(:subscriptions) { ::RubyEventStore::PubSub::Subscriptions.new }
|
6
|
+
let(:dispatcher) { ::RubyEventStore::PubSub::Dispatcher.new }
|
7
|
+
let(:broker) { broker_klass.new(subscriptions: subscriptions, dispatcher: dispatcher) }
|
8
|
+
|
9
|
+
specify "no dispatch when no subscriptions" do
|
10
|
+
expect(subscriptions).to receive(:all_for).with('EventType').and_return([])
|
11
|
+
expect(dispatcher).not_to receive(:call)
|
12
|
+
broker.call(event, serialized_event)
|
13
|
+
end
|
14
|
+
|
15
|
+
specify "calls subscription" do
|
16
|
+
expect(subscriptions).to receive(:all_for).with('EventType').and_return([handler])
|
17
|
+
expect(dispatcher).to receive(:call).with(handler, event, serialized_event)
|
18
|
+
broker.call(event, serialized_event)
|
19
|
+
end
|
20
|
+
|
21
|
+
specify "calls subscribed class" do
|
22
|
+
expect(subscriptions).to receive(:all_for).with('EventType').and_return([HandlerClass])
|
23
|
+
expect(dispatcher).to receive(:call).with(HandlerClass, event, serialized_event)
|
24
|
+
broker.call(event, serialized_event)
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "calls all subscriptions" do
|
28
|
+
expect(subscriptions).to receive(:all_for).with('EventType').and_return([handler, HandlerClass])
|
29
|
+
expect(dispatcher).to receive(:call).with(handler, event, serialized_event)
|
30
|
+
expect(dispatcher).to receive(:call).with(HandlerClass, event, serialized_event)
|
31
|
+
broker.call(event, serialized_event)
|
32
|
+
end
|
33
|
+
|
34
|
+
specify 'raise error when no subscriber' do
|
35
|
+
expect { broker.add_subscription(nil, [])}.to raise_error(RubyEventStore::SubscriberNotExist, "subscriber must be first argument or block")
|
36
|
+
expect { broker.add_global_subscription(nil)}.to raise_error(RubyEventStore::SubscriberNotExist), "subscriber must be first argument or block"
|
37
|
+
expect { broker.add_thread_subscription(nil, []).call}.to raise_error(RubyEventStore::SubscriberNotExist), "subscriber must be first argument or block"
|
38
|
+
expect { broker.add_thread_global_subscription(nil).call}.to raise_error(RubyEventStore::SubscriberNotExist), "subscriber must be first argument or block"
|
39
|
+
end
|
40
|
+
|
41
|
+
specify "verify and add - local subscriptions" do
|
42
|
+
expect(dispatcher).to receive(:verify).with(handler)
|
43
|
+
expect(subscriptions).to receive(:add_subscription).with(handler, ['EventType'])
|
44
|
+
broker.add_subscription(handler, ['EventType'])
|
45
|
+
end
|
46
|
+
|
47
|
+
specify "verify and add - global subscriptions" do
|
48
|
+
expect(dispatcher).to receive(:verify).with(handler)
|
49
|
+
expect(subscriptions).to receive(:add_global_subscription).with(handler)
|
50
|
+
broker.add_global_subscription(handler)
|
51
|
+
end
|
52
|
+
|
53
|
+
specify "verify and add - thread local subscriptions" do
|
54
|
+
expect(dispatcher).to receive(:verify).with(handler)
|
55
|
+
expect(subscriptions).to receive(:add_thread_subscription).with(handler, ['EventType'])
|
56
|
+
broker.add_thread_subscription(handler, ['EventType'])
|
57
|
+
end
|
58
|
+
|
59
|
+
specify "verify and add - thread global subscriptions" do
|
60
|
+
expect(dispatcher).to receive(:verify).with(handler)
|
61
|
+
expect(subscriptions).to receive(:add_thread_global_subscription).with(handler)
|
62
|
+
broker.add_thread_global_subscription(handler)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
class HandlerClass
|
68
|
+
@@received = nil
|
69
|
+
def self.received
|
70
|
+
@@received
|
71
|
+
end
|
72
|
+
def call(event)
|
73
|
+
@@received = event
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
RSpec.shared_examples :dispatcher do |dispatcher|
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
let(:event) { instance_double(::RubyEventStore::Event) }
|
3
|
+
let(:serialized_event) { instance_double(::RubyEventStore::SerializedRecord) }
|
4
|
+
let(:handler) { HandlerClass.new }
|
5
5
|
|
6
|
+
specify "calls subscribed instance" do
|
6
7
|
expect(handler).to receive(:call).with(event)
|
7
|
-
dispatcher.(handler, event)
|
8
|
+
dispatcher.call(handler, event, serialized_event)
|
8
9
|
end
|
9
10
|
|
10
11
|
specify "calls subscribed class" do
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
expect(h).to receive(:call).with(event)
|
15
|
-
dispatcher.(HandlerClass, event)
|
12
|
+
expect(HandlerClass).to receive(:new).and_return(handler)
|
13
|
+
expect(handler).to receive(:call).with(event)
|
14
|
+
dispatcher.call(HandlerClass, event, serialized_event)
|
16
15
|
end
|
17
16
|
|
18
17
|
specify "allows callable classes and instances" do
|
@@ -0,0 +1,111 @@
|
|
1
|
+
RSpec.shared_examples :subscriptions do |subscriptions_class|
|
2
|
+
Test1DomainEvent = Class.new(RubyEventStore::Event)
|
3
|
+
Test2DomainEvent = Class.new(RubyEventStore::Event)
|
4
|
+
Test3DomainEvent = Class.new(RubyEventStore::Event)
|
5
|
+
|
6
|
+
class TestHandler
|
7
|
+
def initialize
|
8
|
+
@events = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(event)
|
12
|
+
@events << event
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :events
|
16
|
+
end
|
17
|
+
|
18
|
+
subject(:subscriptions) { subscriptions_class.new }
|
19
|
+
|
20
|
+
it 'returns all subscribed handlers' do
|
21
|
+
handler = TestHandler.new
|
22
|
+
another_handler = TestHandler.new
|
23
|
+
global_handler = TestHandler.new
|
24
|
+
|
25
|
+
subscriptions.add_subscription(handler, [Test1DomainEvent, Test3DomainEvent])
|
26
|
+
subscriptions.add_subscription(another_handler, [Test2DomainEvent])
|
27
|
+
subscriptions.add_global_subscription(global_handler)
|
28
|
+
|
29
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, global_handler])
|
30
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([another_handler, global_handler])
|
31
|
+
expect(subscriptions.all_for('Test3DomainEvent')).to eq([handler, global_handler])
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns subscribed thread handlers' do
|
35
|
+
handler = TestHandler.new
|
36
|
+
another_handler = TestHandler.new
|
37
|
+
global_handler = TestHandler.new
|
38
|
+
|
39
|
+
subscriptions.add_thread_subscription(handler, [Test1DomainEvent, Test3DomainEvent])
|
40
|
+
subscriptions.add_thread_subscription(another_handler, [Test2DomainEvent])
|
41
|
+
subscriptions.add_thread_global_subscription(global_handler)
|
42
|
+
|
43
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([global_handler, handler])
|
44
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([global_handler, another_handler])
|
45
|
+
expect(subscriptions.all_for('Test3DomainEvent')).to eq([global_handler, handler])
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns lambda as an output of global subscribe methods' do
|
49
|
+
handler = TestHandler.new
|
50
|
+
result = subscriptions.add_global_subscription(handler)
|
51
|
+
expect(result).to respond_to(:call)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns lambda as an output of subscribe methods' do
|
55
|
+
handler = TestHandler.new
|
56
|
+
result = subscriptions.add_subscription(handler, [Test1DomainEvent, Test2DomainEvent])
|
57
|
+
expect(result).to respond_to(:call)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'revokes global subscription' do
|
61
|
+
handler = TestHandler.new
|
62
|
+
|
63
|
+
revoke = subscriptions.add_global_subscription(handler)
|
64
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler])
|
65
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([handler])
|
66
|
+
revoke.()
|
67
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([])
|
68
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([])
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'revokes subscription' do
|
72
|
+
handler = TestHandler.new
|
73
|
+
|
74
|
+
revoke = subscriptions.add_subscription(handler, [Test1DomainEvent, Test2DomainEvent])
|
75
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler])
|
76
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([handler])
|
77
|
+
revoke.()
|
78
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([])
|
79
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([])
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'revokes thread global subscription' do
|
83
|
+
handler = TestHandler.new
|
84
|
+
|
85
|
+
revoke = subscriptions.add_thread_global_subscription(handler)
|
86
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler])
|
87
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([handler])
|
88
|
+
revoke.()
|
89
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([])
|
90
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([])
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'revokes thread subscription' do
|
94
|
+
handler = TestHandler.new
|
95
|
+
|
96
|
+
revoke = subscriptions.add_thread_subscription(handler, [Test1DomainEvent, Test2DomainEvent])
|
97
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler])
|
98
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([handler])
|
99
|
+
revoke.()
|
100
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([])
|
101
|
+
expect(subscriptions.all_for('Test2DomainEvent')).to eq([])
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'subscribes by type of event which is a String' do
|
105
|
+
handler = TestHandler.new
|
106
|
+
subscriptions.add_subscription(handler, ["Test1DomainEvent"])
|
107
|
+
subscriptions.add_thread_subscription(handler, ["Test1DomainEvent"])
|
108
|
+
|
109
|
+
expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, handler])
|
110
|
+
end
|
111
|
+
end
|
@@ -1,6 +1,12 @@
|
|
1
1
|
module RubyEventStore
|
2
|
+
|
3
|
+
# Used for building and executing the query specification.
|
2
4
|
class Specification
|
5
|
+
# @private
|
6
|
+
# @api private
|
3
7
|
NO_LIMIT = Object.new.freeze
|
8
|
+
# @private
|
9
|
+
# @api private
|
4
10
|
NO_BATCH = Object.new.freeze
|
5
11
|
DEFAULT_BATCH_SIZE = 100
|
6
12
|
|
@@ -35,18 +41,34 @@ module RubyEventStore
|
|
35
41
|
end
|
36
42
|
private_constant :Result
|
37
43
|
|
44
|
+
# @api private
|
45
|
+
# @private
|
38
46
|
attr_reader :result
|
39
47
|
|
48
|
+
# @api private
|
49
|
+
# @private
|
40
50
|
def initialize(repository, mapper, result = Result.new(:forward, :head, NO_LIMIT, Stream.new(GLOBAL_STREAM), NO_BATCH))
|
41
51
|
@mapper = mapper
|
42
52
|
@repository = repository
|
43
53
|
@result = result
|
44
54
|
end
|
45
55
|
|
56
|
+
# Limits the query to certain stream.
|
57
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
58
|
+
#
|
59
|
+
# @param stream_name [String] name of the stream to get events from
|
60
|
+
# @return [Specification]
|
46
61
|
def stream(stream_name)
|
47
62
|
Specification.new(repository, mapper, result.dup.tap { |r| r.stream = Stream.new(stream_name) })
|
48
63
|
end
|
49
64
|
|
65
|
+
# Limits the query to events before or after another event.
|
66
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
67
|
+
#
|
68
|
+
# @param start [:head, String] id of event to start reading from.
|
69
|
+
# :head can mean the beginning or end of the stream, depending on the
|
70
|
+
# #direction
|
71
|
+
# @return [Specification]
|
50
72
|
def from(start)
|
51
73
|
case start
|
52
74
|
when Symbol
|
@@ -58,19 +80,38 @@ module RubyEventStore
|
|
58
80
|
Specification.new(repository, mapper, result.dup.tap { |r| r.start = start })
|
59
81
|
end
|
60
82
|
|
83
|
+
# Sets the order of reading events to ascending (forward from the start).
|
84
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
85
|
+
#
|
86
|
+
# @return [Specification]
|
61
87
|
def forward
|
62
88
|
Specification.new(repository, mapper, result.dup.tap { |r| r.direction = :forward })
|
63
89
|
end
|
64
90
|
|
91
|
+
# Sets the order of reading events to descending (backward from the start).
|
92
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
93
|
+
#
|
94
|
+
# @return [Specification]
|
65
95
|
def backward
|
66
96
|
Specification.new(repository, mapper, result.dup.tap { |r| r.direction = :backward })
|
67
97
|
end
|
68
98
|
|
99
|
+
# Limits the query to specified number of events.
|
100
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
101
|
+
#
|
102
|
+
# @param count [Integer] maximal number of events to retrieve
|
103
|
+
# @return [Specification]
|
69
104
|
def limit(count)
|
70
105
|
raise InvalidPageSize unless count && count > 0
|
71
106
|
Specification.new(repository, mapper, result.dup.tap { |r| r.count = count })
|
72
107
|
end
|
73
108
|
|
109
|
+
# Executes the query based on the specification built up to this point.
|
110
|
+
# Yields each batch of records that was retrieved from the store.
|
111
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
112
|
+
#
|
113
|
+
# @yield [Array<Event, Proto>] batch of events
|
114
|
+
# @return [Enumerator, nil] Enumerator is returned when block not given
|
74
115
|
def each_batch
|
75
116
|
return to_enum(:each_batch) unless block_given?
|
76
117
|
|
@@ -80,6 +121,12 @@ module RubyEventStore
|
|
80
121
|
end
|
81
122
|
end
|
82
123
|
|
124
|
+
# Executes the query based on the specification built up to this point.
|
125
|
+
# Yields events read from the store if block given. Otherwise, returns enumerable collection.
|
126
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
127
|
+
#
|
128
|
+
# @yield [Event, Proto] event
|
129
|
+
# @return [Enumerator, nil] Enumerator is returned when block not given
|
83
130
|
def each
|
84
131
|
return to_enum unless block_given?
|
85
132
|
|
@@ -88,6 +135,19 @@ module RubyEventStore
|
|
88
135
|
end
|
89
136
|
end
|
90
137
|
|
138
|
+
# Specifies that events should be obtained in batches.
|
139
|
+
# {http://railseventstore.org/docs/read/ Find out more}.
|
140
|
+
#
|
141
|
+
# Looping through a collection of events from the store
|
142
|
+
# can be inefficient since it will try to instantiate all
|
143
|
+
# the events at once.
|
144
|
+
#
|
145
|
+
# In that case, batch processing methods allow you to work
|
146
|
+
# with the records in batches, thereby greatly reducing
|
147
|
+
# memory consumption.
|
148
|
+
#
|
149
|
+
# @param batch_size [Integer] number of events to read in a single batch
|
150
|
+
# @return [Specification]
|
91
151
|
def in_batches(batch_size = DEFAULT_BATCH_SIZE)
|
92
152
|
Specification.new(repository, mapper, result.dup.tap { |r| r.batch_size = batch_size })
|
93
153
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_event_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.31.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arkency
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -150,9 +150,12 @@ files:
|
|
150
150
|
- README.md
|
151
151
|
- exe/res-deprecated-read-api-migrator
|
152
152
|
- lib/ruby_event_store.rb
|
153
|
+
- lib/ruby_event_store/async_dispatcher.rb
|
154
|
+
- lib/ruby_event_store/async_proxy_strategy.rb
|
153
155
|
- lib/ruby_event_store/batch_enumerator.rb
|
154
156
|
- lib/ruby_event_store/client.rb
|
155
157
|
- lib/ruby_event_store/constants.rb
|
158
|
+
- lib/ruby_event_store/correlated_commands.rb
|
156
159
|
- lib/ruby_event_store/deprecated_read_api_rewriter.rb
|
157
160
|
- lib/ruby_event_store/deprecated_read_api_runner.rb
|
158
161
|
- lib/ruby_event_store/deprecations.rb
|
@@ -160,6 +163,7 @@ files:
|
|
160
163
|
- lib/ruby_event_store/event.rb
|
161
164
|
- lib/ruby_event_store/expected_version.rb
|
162
165
|
- lib/ruby_event_store/in_memory_repository.rb
|
166
|
+
- lib/ruby_event_store/link_by_metadata.rb
|
163
167
|
- lib/ruby_event_store/mappers/default.rb
|
164
168
|
- lib/ruby_event_store/mappers/null_mapper.rb
|
165
169
|
- lib/ruby_event_store/mappers/protobuf.rb
|
@@ -167,10 +171,12 @@ files:
|
|
167
171
|
- lib/ruby_event_store/projection.rb
|
168
172
|
- lib/ruby_event_store/pub_sub/broker.rb
|
169
173
|
- lib/ruby_event_store/pub_sub/dispatcher.rb
|
174
|
+
- lib/ruby_event_store/pub_sub/subscriptions.rb
|
170
175
|
- lib/ruby_event_store/serialized_record.rb
|
176
|
+
- lib/ruby_event_store/spec/broker_lint.rb
|
171
177
|
- lib/ruby_event_store/spec/dispatcher_lint.rb
|
172
|
-
- lib/ruby_event_store/spec/event_broker_lint.rb
|
173
178
|
- lib/ruby_event_store/spec/event_repository_lint.rb
|
179
|
+
- lib/ruby_event_store/spec/subscriptions_lint.rb
|
174
180
|
- lib/ruby_event_store/specification.rb
|
175
181
|
- lib/ruby_event_store/stream.rb
|
176
182
|
- lib/ruby_event_store/version.rb
|
@@ -1,211 +0,0 @@
|
|
1
|
-
RSpec.shared_examples :event_broker do |broker_class|
|
2
|
-
Test1DomainEvent = Class.new(RubyEventStore::Event)
|
3
|
-
Test2DomainEvent = Class.new(RubyEventStore::Event)
|
4
|
-
Test3DomainEvent = Class.new(RubyEventStore::Event)
|
5
|
-
|
6
|
-
class InvalidTestHandler
|
7
|
-
end
|
8
|
-
class TestHandler
|
9
|
-
def initialize
|
10
|
-
@events = []
|
11
|
-
end
|
12
|
-
|
13
|
-
def call(event)
|
14
|
-
@events << event
|
15
|
-
end
|
16
|
-
|
17
|
-
attr_reader :events
|
18
|
-
end
|
19
|
-
class TestDispatcher
|
20
|
-
attr_reader :dispatched
|
21
|
-
|
22
|
-
def initialize
|
23
|
-
@dispatched = []
|
24
|
-
end
|
25
|
-
|
26
|
-
def verify(_subscriber)
|
27
|
-
end
|
28
|
-
|
29
|
-
def call(subscriber, event)
|
30
|
-
@dispatched << {subscriber: subscriber, event: event}
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
subject(:broker) { broker_class.new }
|
35
|
-
|
36
|
-
it 'raise error when no subscriber' do
|
37
|
-
expect { broker.add_subscriber(nil, [])}.to raise_error(RubyEventStore::SubscriberNotExist)
|
38
|
-
expect { broker.add_thread_subscriber(nil, [])}.to raise_error(RubyEventStore::SubscriberNotExist)
|
39
|
-
expect { broker.add_global_subscriber(nil)}.to raise_error(RubyEventStore::SubscriberNotExist)
|
40
|
-
expect { broker.add_thread_global_subscriber(nil)}.to raise_error(RubyEventStore::SubscriberNotExist)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'notifies subscribed handlers' do
|
44
|
-
handler = TestHandler.new
|
45
|
-
another_handler = TestHandler.new
|
46
|
-
global_handler = TestHandler.new
|
47
|
-
|
48
|
-
broker.add_subscriber(handler, [Test1DomainEvent, Test3DomainEvent])
|
49
|
-
broker.add_subscriber(another_handler, [Test2DomainEvent])
|
50
|
-
broker.add_global_subscriber(global_handler)
|
51
|
-
|
52
|
-
event1 = Test1DomainEvent.new
|
53
|
-
event2 = Test2DomainEvent.new
|
54
|
-
event3 = Test3DomainEvent.new
|
55
|
-
|
56
|
-
[event1, event2, event3].each do |ev|
|
57
|
-
broker.notify_subscribers(ev)
|
58
|
-
end
|
59
|
-
|
60
|
-
expect(handler.events).to eq([event1,event3])
|
61
|
-
expect(another_handler.events).to eq([event2])
|
62
|
-
expect(global_handler.events).to eq([event1,event2,event3])
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'notifies subscribed thread handlers' do
|
66
|
-
handler = TestHandler.new
|
67
|
-
another_handler = TestHandler.new
|
68
|
-
global_handler = TestHandler.new
|
69
|
-
|
70
|
-
broker.add_thread_subscriber(handler, [Test1DomainEvent, Test3DomainEvent])
|
71
|
-
broker.add_thread_subscriber(another_handler, [Test2DomainEvent])
|
72
|
-
broker.add_thread_global_subscriber(global_handler)
|
73
|
-
|
74
|
-
event1 = Test1DomainEvent.new
|
75
|
-
event2 = Test2DomainEvent.new
|
76
|
-
event3 = Test3DomainEvent.new
|
77
|
-
|
78
|
-
[event1, event2, event3].each do |ev|
|
79
|
-
broker.notify_subscribers(ev)
|
80
|
-
end
|
81
|
-
|
82
|
-
expect(handler.events).to eq([event1,event3])
|
83
|
-
expect(another_handler.events).to eq([event2])
|
84
|
-
expect(global_handler.events).to eq([event1,event2,event3])
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'raises error when no valid method on handler' do
|
88
|
-
subscriber = InvalidTestHandler.new
|
89
|
-
expect do
|
90
|
-
broker.add_subscriber(subscriber, [Test1DomainEvent])
|
91
|
-
end.to raise_error(RubyEventStore::InvalidHandler)
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'raises error when no valid method on global handler' do
|
95
|
-
subscriber = InvalidTestHandler.new
|
96
|
-
expect do
|
97
|
-
broker.add_global_subscriber(subscriber)
|
98
|
-
end.to raise_error(RubyEventStore::InvalidHandler)
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'raises error when no valid method on thread handler' do
|
102
|
-
subscriber = InvalidTestHandler.new
|
103
|
-
expect do
|
104
|
-
broker.add_thread_subscriber(subscriber, [Test1DomainEvent])
|
105
|
-
end.to raise_error(RubyEventStore::InvalidHandler)
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'raises error when no valid method on global thread handler' do
|
109
|
-
subscriber = InvalidTestHandler.new
|
110
|
-
expect do
|
111
|
-
broker.add_thread_global_subscriber(subscriber)
|
112
|
-
end.to raise_error(RubyEventStore::InvalidHandler)
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'returns lambda as an output of global subscribe methods' do
|
116
|
-
handler = TestHandler.new
|
117
|
-
result = broker.add_global_subscriber(handler)
|
118
|
-
expect(result).to respond_to(:call)
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'returns lambda as an output of subscribe methods' do
|
122
|
-
handler = TestHandler.new
|
123
|
-
result = broker.add_subscriber(handler, [Test1DomainEvent, Test2DomainEvent])
|
124
|
-
expect(result).to respond_to(:call)
|
125
|
-
end
|
126
|
-
|
127
|
-
it 'revokes global subscription' do
|
128
|
-
handler = TestHandler.new
|
129
|
-
event1 = Test1DomainEvent.new
|
130
|
-
event2 = Test2DomainEvent.new
|
131
|
-
|
132
|
-
revoke = broker.add_global_subscriber(handler)
|
133
|
-
broker.notify_subscribers(event1)
|
134
|
-
expect(handler.events).to eq([event1])
|
135
|
-
revoke.()
|
136
|
-
broker.notify_subscribers(event2)
|
137
|
-
expect(handler.events).to eq([event1])
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'revokes subscription' do
|
141
|
-
handler = TestHandler.new
|
142
|
-
event1 = Test1DomainEvent.new
|
143
|
-
event2 = Test2DomainEvent.new
|
144
|
-
|
145
|
-
revoke = broker.add_subscriber(handler, [Test1DomainEvent, Test2DomainEvent])
|
146
|
-
broker.notify_subscribers(event1)
|
147
|
-
expect(handler.events).to eq([event1])
|
148
|
-
revoke.()
|
149
|
-
broker.notify_subscribers(event2)
|
150
|
-
expect(handler.events).to eq([event1])
|
151
|
-
end
|
152
|
-
|
153
|
-
it 'revokes thread global subscription' do
|
154
|
-
handler = TestHandler.new
|
155
|
-
event1 = Test1DomainEvent.new
|
156
|
-
event2 = Test2DomainEvent.new
|
157
|
-
|
158
|
-
revoke = broker.add_thread_global_subscriber(handler)
|
159
|
-
broker.notify_subscribers(event1)
|
160
|
-
expect(handler.events).to eq([event1])
|
161
|
-
revoke.()
|
162
|
-
broker.notify_subscribers(event2)
|
163
|
-
expect(handler.events).to eq([event1])
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'revokes thread subscription' do
|
167
|
-
handler = TestHandler.new
|
168
|
-
event1 = Test1DomainEvent.new
|
169
|
-
event2 = Test2DomainEvent.new
|
170
|
-
|
171
|
-
revoke = broker.add_thread_subscriber(handler, [Test1DomainEvent, Test2DomainEvent])
|
172
|
-
broker.notify_subscribers(event1)
|
173
|
-
expect(handler.events).to eq([event1])
|
174
|
-
revoke.()
|
175
|
-
broker.notify_subscribers(event2)
|
176
|
-
expect(handler.events).to eq([event1])
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'allows to provide a custom dispatcher' do
|
180
|
-
dispatcher = TestDispatcher.new
|
181
|
-
handler = TestHandler.new
|
182
|
-
event1 = Test1DomainEvent.new
|
183
|
-
broker_with_custom_dispatcher = broker_class.new(dispatcher: dispatcher)
|
184
|
-
broker_with_custom_dispatcher.add_subscriber(handler, [Test1DomainEvent])
|
185
|
-
broker_with_custom_dispatcher.notify_subscribers(event1)
|
186
|
-
expect(dispatcher.dispatched).to eq([{subscriber: handler, event: event1}])
|
187
|
-
end
|
188
|
-
|
189
|
-
it 'subscribes by type of event which is a String' do
|
190
|
-
handler = TestHandler.new
|
191
|
-
broker.add_subscriber(handler, ["Test1DomainEvent"])
|
192
|
-
broker.add_thread_subscriber(handler, ["Test1DomainEvent"])
|
193
|
-
|
194
|
-
event1 = Test1DomainEvent.new
|
195
|
-
broker.notify_subscribers(event1)
|
196
|
-
|
197
|
-
expect(handler.events).to eq([event1,event1])
|
198
|
-
end
|
199
|
-
|
200
|
-
private
|
201
|
-
|
202
|
-
class HandlerClass
|
203
|
-
@@received = nil
|
204
|
-
def self.received
|
205
|
-
@@received
|
206
|
-
end
|
207
|
-
def call(event)
|
208
|
-
@@received = event
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|