synapse-core 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/synapse.rb +3 -0
- data/lib/synapse/command/simple_command_bus.rb +2 -2
- data/lib/synapse/common/concurrency/identifier_lock.rb +71 -0
- data/lib/synapse/common/concurrency/public_lock.rb +96 -0
- data/lib/synapse/event_bus/simple_event_bus.rb +1 -1
- data/lib/synapse/event_bus/wiring.rb +0 -4
- data/lib/synapse/event_sourcing/member.rb +0 -4
- data/lib/synapse/event_sourcing/snapshot/count_trigger.rb +2 -2
- data/lib/synapse/event_store.rb +1 -9
- data/lib/synapse/partitioning.rb +0 -2
- data/lib/synapse/process_manager.rb +12 -0
- data/lib/synapse/process_manager/lock_manager.rb +22 -0
- data/lib/synapse/process_manager/pessimistic_lock_manager.rb +23 -0
- data/lib/synapse/process_manager/process.rb +2 -0
- data/lib/synapse/process_manager/process_factory.rb +52 -0
- data/lib/synapse/process_manager/process_manager.rb +170 -0
- data/lib/synapse/process_manager/process_repository.rb +53 -0
- data/lib/synapse/process_manager/repository/in_memory.rb +63 -0
- data/lib/synapse/process_manager/resource_injector.rb +12 -0
- data/lib/synapse/process_manager/simple_process_manager.rb +48 -0
- data/lib/synapse/process_manager/wiring/process.rb +27 -0
- data/lib/synapse/process_manager/wiring/process_manager.rb +72 -0
- data/lib/synapse/repository.rb +1 -0
- data/lib/synapse/repository/locking.rb +1 -1
- data/lib/synapse/repository/optimistic_lock_manager.rb +128 -0
- data/lib/synapse/repository/pessimistic_lock_manager.rb +4 -37
- data/lib/synapse/serialization.rb +1 -1
- data/lib/synapse/serialization/{converter/factory.rb → converter_factory.rb} +0 -0
- data/lib/synapse/serialization/serializer.rb +5 -3
- data/lib/synapse/uow/listener_collection.rb +59 -1
- data/lib/synapse/version.rb +1 -1
- data/lib/synapse/wiring/message_wiring.rb +7 -3
- data/lib/synapse/wiring/wire.rb +7 -2
- data/test/common/concurrency/identifier_lock_test.rb +36 -0
- data/test/common/concurrency/public_lock_test.rb +83 -0
- data/test/partitioning/packing/json_test.rb +2 -1
- data/test/process_manager/in_memory_test.rb +57 -0
- data/test/process_manager/process_factory_test.rb +31 -0
- data/test/process_manager/simple_process_manager_test.rb +130 -0
- data/test/process_manager/wiring/fixtures.rb +42 -0
- data/test/process_manager/wiring/process_manager_test.rb +73 -0
- data/test/process_manager/wiring/process_test.rb +35 -0
- data/test/repository/optimistic_test.rb +41 -0
- data/test/repository/pessimistic_test.rb +20 -0
- data/test/serialization/converter/chain_test.rb +31 -0
- data/test/serialization/lazy_object_test.rb +1 -1
- data/test/serialization/message/serialization_aware_message_test.rb +4 -2
- data/test/serialization/message/serialized_message_builder_test.rb +1 -1
- data/test/serialization/message/serialized_message_test.rb +3 -2
- data/test/serialization/serializer/marshal_test.rb +1 -1
- data/test/serialization/serializer/oj_test.rb +1 -1
- data/test/serialization/serializer/ox_test.rb +1 -1
- data/test/serialization/serializer_test.rb +1 -1
- data/test/test_ext.rb +5 -2
- data/test/wiring/wire_registry_test.rb +10 -10
- data/test/wiring/wire_test.rb +5 -5
- metadata +29 -16
- data/lib/synapse/event_store/mongo.rb +0 -8
- data/lib/synapse/event_store/mongo/cursor_event_stream.rb +0 -63
- data/lib/synapse/event_store/mongo/event_store.rb +0 -86
- data/lib/synapse/event_store/mongo/per_commit_strategy.rb +0 -253
- data/lib/synapse/event_store/mongo/per_event_strategy.rb +0 -143
- data/lib/synapse/event_store/mongo/storage_strategy.rb +0 -113
- data/lib/synapse/event_store/mongo/template.rb +0 -73
- data/lib/synapse/partitioning/amqp.rb +0 -3
- data/lib/synapse/partitioning/amqp/amqp_queue_reader.rb +0 -50
- data/lib/synapse/partitioning/amqp/amqp_queue_writer.rb +0 -31
- data/lib/synapse/partitioning/amqp/key_resolver.rb +0 -26
- data/lib/synapse/serialization/converter/bson.rb +0 -28
@@ -23,9 +23,9 @@ module Synapse
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
require 'synapse/serialization/converter_factory'
|
26
27
|
require 'synapse/serialization/converter'
|
27
28
|
require 'synapse/serialization/converter/chain'
|
28
|
-
require 'synapse/serialization/converter/factory'
|
29
29
|
require 'synapse/serialization/converter/identity'
|
30
30
|
|
31
31
|
require 'synapse/serialization/errors'
|
File without changes
|
@@ -4,13 +4,15 @@ module Synapse
|
|
4
4
|
# @abstract
|
5
5
|
class Serializer
|
6
6
|
# @return [ConverterFactory]
|
7
|
-
|
7
|
+
attr_reader :converter_factory
|
8
8
|
|
9
9
|
# @return [RevisionResolver]
|
10
10
|
attr_accessor :revision_resolver
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
# @param [ConverterFactory] converter_factory
|
13
|
+
# @return [undefined]
|
14
|
+
def initialize(converter_factory)
|
15
|
+
@converter_factory = converter_factory
|
14
16
|
end
|
15
17
|
|
16
18
|
# @param [Object] object
|
@@ -14,6 +14,7 @@ module Synapse
|
|
14
14
|
class UnitOfWorkListenerCollection < UnitOfWorkListener
|
15
15
|
def initialize
|
16
16
|
@listeners = Array.new
|
17
|
+
@logger = Logging.logger[self.class]
|
17
18
|
end
|
18
19
|
|
19
20
|
# Pushes a unit of work listener onto the end of this collection
|
@@ -21,6 +22,10 @@ module Synapse
|
|
21
22
|
# @param [UnitOfWorkListener] listener
|
22
23
|
# @return [undefined]
|
23
24
|
def push(listener)
|
25
|
+
if @logger.debug?
|
26
|
+
@logger.debug 'Registering listener [%s]' % listener.class
|
27
|
+
end
|
28
|
+
|
24
29
|
@listeners.push listener
|
25
30
|
end
|
26
31
|
|
@@ -29,9 +34,17 @@ module Synapse
|
|
29
34
|
# @param [UnitOfWork] unit
|
30
35
|
# @return [undefined]
|
31
36
|
def on_start(unit)
|
37
|
+
@logger.debug 'Notifying listeners that unit of work is starting'
|
38
|
+
|
32
39
|
@listeners.each do |listener|
|
40
|
+
if @logger.debug?
|
41
|
+
@logger.debug 'Notifying [%s] of start' % listener.class
|
42
|
+
end
|
43
|
+
|
33
44
|
listener.on_start unit
|
34
45
|
end
|
46
|
+
|
47
|
+
@logger.debug 'Listeners successfully notified'
|
35
48
|
end
|
36
49
|
|
37
50
|
# @param [UnitOfWork] unit
|
@@ -50,43 +63,88 @@ module Synapse
|
|
50
63
|
# @param [Hash<EventBus, Array>] events
|
51
64
|
# @return [undefined]
|
52
65
|
def on_prepare_commit(unit, aggregates, events)
|
66
|
+
@logger.debug 'Notifying listeners that commit was requested'
|
67
|
+
|
53
68
|
@listeners.each do |listener|
|
69
|
+
if @logger.debug?
|
70
|
+
@logger.debug 'Notifying [%s] of commit' % listener.class
|
71
|
+
end
|
72
|
+
|
54
73
|
listener.on_prepare_commit unit, aggregates, events
|
55
74
|
end
|
75
|
+
|
76
|
+
@logger.debug 'Listeners successfully notified'
|
56
77
|
end
|
57
78
|
|
58
79
|
# @param [UnitOfWork] unit
|
59
80
|
# @param [Object] transaction
|
60
81
|
# @return [undefined]
|
61
82
|
def on_prepare_transaction_commit(unit, transaction)
|
83
|
+
@logger.debug 'Notifying listeners that transactional commit was requested'
|
84
|
+
|
62
85
|
@listeners.each do |listener|
|
86
|
+
if @logger.debug?
|
87
|
+
@logger.debug 'Notifying [%s] of transactional commit' % listener.class
|
88
|
+
end
|
89
|
+
|
63
90
|
listener.on_prepare_transaction_commit unit, transaction
|
64
91
|
end
|
92
|
+
|
93
|
+
@logger.debug 'Listeners successfully notified'
|
65
94
|
end
|
66
95
|
|
67
96
|
# @param [UnitOfWork] unit
|
68
97
|
# @return [undefined]
|
69
98
|
def after_commit(unit)
|
99
|
+
@logger.debug 'Notifying listeners that commit has finished'
|
100
|
+
|
70
101
|
@listeners.reverse_each do |listener|
|
102
|
+
if @logger.debug?
|
103
|
+
@logger.debug 'Notifying [%s] of finished commit' % listener.class
|
104
|
+
end
|
105
|
+
|
71
106
|
listener.after_commit unit
|
72
107
|
end
|
108
|
+
|
109
|
+
@logger.debug 'Listeners successfully notified'
|
73
110
|
end
|
74
111
|
|
75
112
|
# @param [UnitOfWork] unit
|
76
113
|
# @param [Error] cause
|
77
114
|
# @return [undefined]
|
78
115
|
def on_rollback(unit, cause = nil)
|
116
|
+
@logger.debug 'Notifying listeners of rollback'
|
117
|
+
|
79
118
|
@listeners.reverse_each do |listener|
|
119
|
+
if @logger.debug?
|
120
|
+
@logger.debug 'Notifying [%s] of rollback' % listener.class
|
121
|
+
end
|
122
|
+
|
80
123
|
listener.on_rollback unit, cause
|
81
124
|
end
|
125
|
+
|
126
|
+
@logger.debug 'Listeners successfully notified'
|
82
127
|
end
|
83
128
|
|
84
129
|
# @param [UnitOfWork] unit
|
85
130
|
# @return [undefined]
|
86
131
|
def on_cleanup(unit)
|
132
|
+
@logger.debug 'Notifying listeners of cleanup'
|
133
|
+
|
87
134
|
@listeners.reverse_each do |listener|
|
88
|
-
|
135
|
+
if @logger.debug?
|
136
|
+
@logger.debug 'Notifying [%s] of cleanup' % listener.class
|
137
|
+
end
|
138
|
+
|
139
|
+
begin
|
140
|
+
listener.on_cleanup unit
|
141
|
+
rescue => exception
|
142
|
+
# Ignore this exception so that we can continue cleaning up
|
143
|
+
@logger.warn 'Listener raised an exception during cleanup: %s' % exception.inspect
|
144
|
+
end
|
89
145
|
end
|
146
|
+
|
147
|
+
@logger.debug 'Listeners successfully notified'
|
90
148
|
end
|
91
149
|
end
|
92
150
|
end
|
data/lib/synapse/version.rb
CHANGED
@@ -8,21 +8,25 @@ module Synapse
|
|
8
8
|
included do
|
9
9
|
# @return [WireRegistry]
|
10
10
|
class_attribute :wire_registry
|
11
|
+
|
12
|
+
# By default, the wire registry allows duplicates
|
13
|
+
self.wire_registry = Wiring::WireRegistry.new true
|
11
14
|
end
|
12
15
|
|
13
16
|
module ClassMethods
|
14
17
|
def wire(type, *args, &block)
|
15
18
|
options = args.extract_options!
|
16
19
|
|
17
|
-
|
20
|
+
to = options.delete :to
|
21
|
+
unless to
|
18
22
|
unless block
|
19
23
|
raise ArgumentError, 'Expected block or option :to'
|
20
24
|
end
|
21
25
|
|
22
|
-
|
26
|
+
to = block
|
23
27
|
end
|
24
28
|
|
25
|
-
wire = Wire.new type, options
|
29
|
+
wire = Wire.new type, options, to
|
26
30
|
|
27
31
|
self.wire_registry.register wire
|
28
32
|
end
|
data/lib/synapse/wiring/wire.rb
CHANGED
@@ -11,11 +11,16 @@ module Synapse
|
|
11
11
|
# @return [Object] Either a method symbol or block
|
12
12
|
attr_reader :handler
|
13
13
|
|
14
|
+
# @return [Hash] Options specific to the component being wired
|
15
|
+
attr_reader :options
|
16
|
+
|
14
17
|
# @param [Class] type
|
18
|
+
# @param [Hash] options
|
15
19
|
# @param [Object] handler Either a method symbol or block
|
16
|
-
# @return [undefined]
|
17
|
-
def initialize(type, handler)
|
20
|
+
# @return [undefined]
|
21
|
+
def initialize(type, options, handler)
|
18
22
|
@type = type
|
23
|
+
@options = options
|
19
24
|
@handler = handler
|
20
25
|
end
|
21
26
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
class IdentifierLockTest < Test::Unit::TestCase
|
5
|
+
def test_disposal
|
6
|
+
lock = IdentifierLock.new
|
7
|
+
identifier = 'some_id'
|
8
|
+
|
9
|
+
lock.obtain_lock identifier
|
10
|
+
lock.release_lock identifier
|
11
|
+
|
12
|
+
identifiers = lock.instance_variable_get :@identifiers
|
13
|
+
refute identifiers.has_key? identifier
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_owned?
|
17
|
+
lock = IdentifierLock.new
|
18
|
+
identifier = 'some_id'
|
19
|
+
|
20
|
+
refute lock.owned? identifier
|
21
|
+
|
22
|
+
lock.obtain_lock identifier
|
23
|
+
assert lock.owned? identifier
|
24
|
+
|
25
|
+
lock.release_lock identifier
|
26
|
+
refute lock.owned? identifier
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_release_lock
|
30
|
+
lock = IdentifierLock.new
|
31
|
+
assert_raise ThreadError do
|
32
|
+
lock.release_lock 'derp'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
class PublicLockTest < Test::Unit::TestCase
|
5
|
+
def test_lock_raises
|
6
|
+
@lock = PublicLock.new
|
7
|
+
@lock.lock
|
8
|
+
|
9
|
+
assert_raise ThreadError do
|
10
|
+
@lock.lock
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_lock_removes_waiting
|
15
|
+
@lock = PublicLock.new
|
16
|
+
@lock.lock
|
17
|
+
|
18
|
+
t = Thread.new do
|
19
|
+
@lock.lock
|
20
|
+
end
|
21
|
+
|
22
|
+
wait_until do
|
23
|
+
@lock.waiting == [t]
|
24
|
+
end
|
25
|
+
|
26
|
+
t.kill
|
27
|
+
|
28
|
+
wait_until do
|
29
|
+
@lock.waiting == []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_synchronize
|
34
|
+
@lock = PublicLock.new
|
35
|
+
|
36
|
+
refute @lock.owned?
|
37
|
+
refute @lock.owned_by? Thread.current
|
38
|
+
|
39
|
+
@lock.synchronize do
|
40
|
+
assert @lock.owned?
|
41
|
+
assert @lock.owned_by? Thread.current
|
42
|
+
end
|
43
|
+
|
44
|
+
refute @lock.owned?
|
45
|
+
refute @lock.owned_by? Thread.current
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_unlock_raises
|
49
|
+
@lock = PublicLock.new
|
50
|
+
|
51
|
+
assert_raise ThreadError do
|
52
|
+
@lock.unlock
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_try_lock
|
57
|
+
@lock = PublicLock.new
|
58
|
+
|
59
|
+
t = Thread.new do
|
60
|
+
assert @lock.try_lock
|
61
|
+
Thread.stop
|
62
|
+
@lock.unlock
|
63
|
+
end
|
64
|
+
|
65
|
+
wait_until do
|
66
|
+
@lock.owned_by? t
|
67
|
+
end
|
68
|
+
|
69
|
+
refute @lock.try_lock
|
70
|
+
|
71
|
+
t.wakeup
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_try_lock_raises
|
75
|
+
@lock = PublicLock.new
|
76
|
+
@lock.try_lock
|
77
|
+
|
78
|
+
assert_raise ThreadError do
|
79
|
+
@lock.try_lock
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -5,7 +5,8 @@ module Synapse
|
|
5
5
|
|
6
6
|
class JsonPackingTest < Test::Unit::TestCase
|
7
7
|
def setup
|
8
|
-
@
|
8
|
+
@converter_factory = Serialization::ConverterFactory.new
|
9
|
+
@serializer = Serialization::MarshalSerializer.new @converter_factory
|
9
10
|
@packer = JsonMessagePacker.new @serializer
|
10
11
|
@unpacker = JsonMessageUnpacker.new @serializer
|
11
12
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
module ProcessManager
|
5
|
+
|
6
|
+
class InMemoryProcessRepositoryTest < Test::Unit::TestCase
|
7
|
+
def test_find
|
8
|
+
correlation_a = Correlation.new :order_id, 1
|
9
|
+
correlation_b = Correlation.new :order_id, 2
|
10
|
+
|
11
|
+
process_a = Process.new
|
12
|
+
process_a.correlations.add correlation_a
|
13
|
+
process_b = Process.new
|
14
|
+
process_b.correlations.add correlation_b
|
15
|
+
|
16
|
+
repository = InMemoryProcessRepository.new
|
17
|
+
repository.add process_a
|
18
|
+
repository.add process_b
|
19
|
+
|
20
|
+
assert_equal [process_a.id], repository.find(Process, correlation_a)
|
21
|
+
assert_equal [process_b.id], repository.find(Process, correlation_b)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_load
|
25
|
+
repository = InMemoryProcessRepository.new
|
26
|
+
|
27
|
+
process_a = Process.new
|
28
|
+
process_b = Process.new
|
29
|
+
|
30
|
+
repository.add process_a
|
31
|
+
repository.add process_b
|
32
|
+
|
33
|
+
assert_equal process_a, repository.load(process_a.id)
|
34
|
+
assert_equal process_b, repository.load(process_b.id)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_commit
|
38
|
+
repository = InMemoryProcessRepository.new
|
39
|
+
|
40
|
+
process = Process.new
|
41
|
+
repository.commit process
|
42
|
+
|
43
|
+
assert_equal 1, repository.count
|
44
|
+
# Make sure the correlation set was marked as committed
|
45
|
+
assert_equal 0, process.correlations.additions.count
|
46
|
+
assert_equal 0, process.correlations.deletions.count
|
47
|
+
|
48
|
+
process.send :finish
|
49
|
+
|
50
|
+
repository.commit process
|
51
|
+
|
52
|
+
assert_equal 0, repository.count
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
module ProcessManager
|
5
|
+
class GenericProcessFactoryTest < Test::Unit::TestCase
|
6
|
+
def test_create
|
7
|
+
injector = Object.new
|
8
|
+
|
9
|
+
mock(injector).inject_resources(is_a(Process))
|
10
|
+
|
11
|
+
factory = GenericProcessFactory.new
|
12
|
+
factory.resource_injector = injector
|
13
|
+
|
14
|
+
process = factory.create Process
|
15
|
+
|
16
|
+
assert process.is_a? Process
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_supports
|
20
|
+
factory = GenericProcessFactory.new
|
21
|
+
|
22
|
+
assert factory.supports Process
|
23
|
+
refute factory.supports StubProcessWithArguments
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class StubProcessWithArguments < Process
|
28
|
+
def initialize(some_resource); end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
module ProcessManager
|
5
|
+
class SimpleProcessManagerTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@repository = InMemoryProcessRepository.new
|
8
|
+
@factory = GenericProcessFactory.new
|
9
|
+
@resolver = MetadataCorrelationResolver.new :order_id
|
10
|
+
@lock_manager = Object.new
|
11
|
+
@manager = SimpleProcessManager.new @repository, @factory, @lock_manager, @resolver, TestProcess
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_notify_new_process
|
15
|
+
@manager.optionally_create_events << CauseProcessCreationEvent
|
16
|
+
|
17
|
+
correlation = Correlation.new :order_id, 123
|
18
|
+
|
19
|
+
mock(@lock_manager).obtain_lock(is_a(String))
|
20
|
+
mock(@lock_manager).release_lock(is_a(String))
|
21
|
+
|
22
|
+
@manager.notify create_event 123, CauseProcessCreationEvent.new
|
23
|
+
|
24
|
+
assert_equal 1, @repository.count
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_notify_existing_process
|
28
|
+
process = TestProcess.new
|
29
|
+
process.correlations.add Correlation.new :order_id, 123
|
30
|
+
|
31
|
+
@repository.add process
|
32
|
+
|
33
|
+
mock(@lock_manager).obtain_lock(process.id)
|
34
|
+
mock(@lock_manager).release_lock(process.id)
|
35
|
+
|
36
|
+
@manager.notify create_event 123, CauseProcessNotificationEvent.new
|
37
|
+
|
38
|
+
assert_equal 1, @repository.count
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_notify_process_raises_but_suppressed
|
42
|
+
process = TestProcess.new
|
43
|
+
process.correlations.add Correlation.new :order_id, 123
|
44
|
+
|
45
|
+
@repository.add process
|
46
|
+
|
47
|
+
mock(@lock_manager).obtain_lock(process.id)
|
48
|
+
mock(@lock_manager).release_lock(process.id)
|
49
|
+
|
50
|
+
@manager.notify create_event 123, CauseProcessRaiseExceptionEvent.new
|
51
|
+
|
52
|
+
assert_equal 1, @repository.count
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_notify_process_raises
|
56
|
+
process = TestProcess.new
|
57
|
+
process.correlations.add Correlation.new :order_id, 123
|
58
|
+
|
59
|
+
@repository.add process
|
60
|
+
|
61
|
+
mock(@lock_manager).obtain_lock(process.id)
|
62
|
+
mock(@lock_manager).release_lock(process.id)
|
63
|
+
|
64
|
+
@manager.suppress_exceptions = false
|
65
|
+
|
66
|
+
assert_raise RuntimeError do
|
67
|
+
@manager.notify create_event 123, CauseProcessRaiseExceptionEvent.new
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_always_create
|
72
|
+
@manager.always_create_events << CauseProcessCreationEvent
|
73
|
+
|
74
|
+
correlation = Correlation.new :order_id, 123
|
75
|
+
|
76
|
+
# Lock is obtain/released for the 2 being created and once for the first being changed
|
77
|
+
mock(@lock_manager).obtain_lock(is_a(String)).times(3)
|
78
|
+
mock(@lock_manager).release_lock(is_a(String)).times(3)
|
79
|
+
|
80
|
+
@manager.notify create_event 123, CauseProcessCreationEvent.new
|
81
|
+
@manager.notify create_event 123, CauseProcessCreationEvent.new
|
82
|
+
|
83
|
+
assert_equal 2, @repository.count
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def create_event(order_id, event)
|
89
|
+
Domain::EventMessage.build do |builder|
|
90
|
+
builder.payload = event
|
91
|
+
builder.metadata = {
|
92
|
+
order_id: order_id
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Example correlation resolver
|
99
|
+
class MetadataCorrelationResolver < CorrelationResolver
|
100
|
+
def initialize(property)
|
101
|
+
@property = property
|
102
|
+
end
|
103
|
+
|
104
|
+
def resolve(event)
|
105
|
+
value = event.metadata[@property]
|
106
|
+
if value
|
107
|
+
Correlation.new @property, value
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Test process that has all sorts of trigger events
|
113
|
+
class TestProcess < Process
|
114
|
+
attr_accessor :handled
|
115
|
+
|
116
|
+
def handle(event)
|
117
|
+
if event.payload_type == CauseProcessRaiseExceptionEvent
|
118
|
+
raise 'ohgodimnotgoodwithcomputers'
|
119
|
+
end
|
120
|
+
|
121
|
+
@handled ||= 0
|
122
|
+
@handled = @handled.next
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class CauseProcessCreationEvent; end
|
127
|
+
class CauseProcessNotificationEvent; end
|
128
|
+
class CauseProcessRaiseExceptionEvent; end
|
129
|
+
end
|
130
|
+
end
|