aggro 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/.travis.yml +15 -0
- data/Gemfile +9 -0
- data/README.md +5 -1
- data/Rakefile +10 -0
- data/aggro.gemspec +8 -1
- data/lib/aggro.rb +191 -7
- data/lib/aggro/abstract_store.rb +12 -0
- data/lib/aggro/aggregate.rb +98 -0
- data/lib/aggro/aggregate_ref.rb +68 -6
- data/lib/aggro/attribute_dsl.rb +96 -0
- data/lib/aggro/binding_dsl.rb +45 -0
- data/lib/aggro/block_helper.rb +14 -0
- data/lib/aggro/channel.rb +37 -0
- data/lib/aggro/client.rb +12 -0
- data/lib/aggro/cluster_config.rb +57 -0
- data/lib/aggro/command.rb +16 -0
- data/lib/aggro/concurrent_actor.rb +26 -0
- data/lib/aggro/event_bus.rb +94 -0
- data/lib/aggro/event_dsl.rb +53 -0
- data/lib/aggro/event_proxy.rb +23 -0
- data/lib/aggro/event_serializer.rb +14 -0
- data/lib/aggro/file_store.rb +97 -0
- data/lib/aggro/file_store/reader.rb +21 -0
- data/lib/aggro/file_store/writer.rb +27 -0
- data/lib/aggro/handler/command.rb +60 -0
- data/lib/aggro/handler/create_aggregate.rb +42 -0
- data/lib/aggro/handler/get_events.rb +30 -0
- data/lib/aggro/handler/query.rb +60 -0
- data/lib/aggro/handler/start_saga.rb +56 -0
- data/lib/aggro/local_node.rb +28 -0
- data/lib/aggro/locator.rb +32 -0
- data/lib/aggro/message/ask.rb +16 -0
- data/lib/aggro/message/command.rb +36 -0
- data/lib/aggro/message/create_aggregate.rb +16 -0
- data/lib/aggro/message/endpoint.rb +16 -0
- data/lib/aggro/message/events.rb +24 -0
- data/lib/aggro/message/get_events.rb +16 -0
- data/lib/aggro/message/heartbeat.rb +16 -0
- data/lib/aggro/message/invalid_target.rb +20 -0
- data/lib/aggro/message/ok.rb +20 -0
- data/lib/aggro/message/publisher_endpoint_inquiry.rb +16 -0
- data/lib/aggro/message/query.rb +36 -0
- data/lib/aggro/message/result.rb +16 -0
- data/lib/aggro/message/start_saga.rb +28 -0
- data/lib/aggro/message/unhandled_operation.rb +20 -0
- data/lib/aggro/message/unknown_operation.rb +20 -0
- data/lib/aggro/message_parser.rb +10 -0
- data/lib/aggro/message_router.rb +26 -0
- data/lib/aggro/nanomsg_transport.rb +31 -0
- data/lib/aggro/nanomsg_transport/client.rb +35 -0
- data/lib/aggro/nanomsg_transport/connection.rb +98 -0
- data/lib/aggro/nanomsg_transport/publish.rb +17 -0
- data/lib/aggro/nanomsg_transport/publisher.rb +37 -0
- data/lib/aggro/nanomsg_transport/raw_reply.rb +18 -0
- data/lib/aggro/nanomsg_transport/raw_request.rb +18 -0
- data/lib/aggro/nanomsg_transport/reply.rb +17 -0
- data/lib/aggro/nanomsg_transport/request.rb +17 -0
- data/lib/aggro/nanomsg_transport/server.rb +84 -0
- data/lib/aggro/nanomsg_transport/socket_error.rb +20 -0
- data/lib/aggro/nanomsg_transport/subscribe.rb +27 -0
- data/lib/aggro/nanomsg_transport/subscriber.rb +82 -0
- data/lib/aggro/node.rb +29 -0
- data/lib/aggro/node_list.rb +39 -0
- data/lib/aggro/projection.rb +13 -0
- data/lib/aggro/query.rb +11 -0
- data/lib/aggro/saga.rb +94 -0
- data/lib/aggro/saga_runner.rb +87 -0
- data/lib/aggro/saga_runner/start_saga.rb +12 -0
- data/lib/aggro/saga_status.rb +29 -0
- data/lib/aggro/server.rb +88 -0
- data/lib/aggro/subscriber.rb +48 -0
- data/lib/aggro/subscription.rb +41 -0
- data/lib/aggro/transform/boolean.rb +16 -0
- data/lib/aggro/transform/email.rb +26 -0
- data/lib/aggro/transform/id.rb +34 -0
- data/lib/aggro/transform/integer.rb +22 -0
- data/lib/aggro/transform/money.rb +22 -0
- data/lib/aggro/transform/noop.rb +16 -0
- data/lib/aggro/transform/string.rb +16 -0
- data/lib/aggro/transform/time_interval.rb +24 -0
- data/lib/aggro/version.rb +1 -1
- data/spec/lib/aggro/abstract_store_spec.rb +15 -0
- data/spec/lib/aggro/aggregate_ref_spec.rb +63 -12
- data/spec/lib/aggro/aggregate_spec.rb +207 -0
- data/spec/lib/aggro/channel_spec.rb +87 -0
- data/spec/lib/aggro/client_spec.rb +26 -0
- data/spec/lib/aggro/cluster_config_spec.rb +33 -0
- data/spec/lib/aggro/command_spec.rb +52 -0
- data/spec/lib/aggro/concurrent_actor_spec.rb +44 -0
- data/spec/lib/aggro/event_bus_spec.rb +20 -0
- data/spec/lib/aggro/event_serializer_spec.rb +28 -0
- data/spec/lib/aggro/file_store/reader_spec.rb +32 -0
- data/spec/lib/aggro/file_store/writer_spec.rb +67 -0
- data/spec/lib/aggro/file_store_spec.rb +51 -0
- data/spec/lib/aggro/handler/command_spec.rb +78 -0
- data/spec/lib/aggro/handler/create_aggregate_spec.rb +64 -0
- data/spec/lib/aggro/handler/get_events_handler_spec.rb +45 -0
- data/spec/lib/aggro/handler/query_spec.rb +78 -0
- data/spec/lib/aggro/handler/start_saga_spec.rb +64 -0
- data/spec/lib/aggro/local_node_spec.rb +52 -0
- data/spec/lib/aggro/locator_spec.rb +61 -0
- data/spec/lib/aggro/message/ask_spec.rb +23 -0
- data/spec/lib/aggro/message/command_spec.rb +50 -0
- data/spec/lib/aggro/message/create_aggregate_spec.rb +28 -0
- data/spec/lib/aggro/message/endpoint_spec.rb +23 -0
- data/spec/lib/aggro/message/events_spec.rb +37 -0
- data/spec/lib/aggro/message/get_events_spec.rb +33 -0
- data/spec/lib/aggro/message/heartbeat_spec.rb +23 -0
- data/spec/lib/aggro/message/invalid_target_spec.rb +28 -0
- data/spec/lib/aggro/message/ok_spec.rb +27 -0
- data/spec/lib/aggro/message/publisher_endpoint_inquiry_spec.rb +23 -0
- data/spec/lib/aggro/message/query_spec.rb +50 -0
- data/spec/lib/aggro/message/start_saga_spec.rb +37 -0
- data/spec/lib/aggro/message/unhandled_operation_spec.rb +28 -0
- data/spec/lib/aggro/message/unknown_operation_spec.rb +28 -0
- data/spec/lib/aggro/message_parser_spec.rb +16 -0
- data/spec/lib/aggro/message_router_spec.rb +35 -0
- data/spec/lib/aggro/nanomsg_transport/socket_error_spec.rb +21 -0
- data/spec/lib/aggro/nanomsg_transport_spec.rb +37 -0
- data/spec/lib/aggro/node_list_spec.rb +38 -0
- data/spec/lib/aggro/node_spec.rb +44 -0
- data/spec/lib/aggro/projection_spec.rb +22 -0
- data/spec/lib/aggro/query_spec.rb +47 -0
- data/spec/lib/aggro/saga_runner_spec.rb +84 -0
- data/spec/lib/aggro/saga_spec.rb +126 -0
- data/spec/lib/aggro/saga_status_spec.rb +56 -0
- data/spec/lib/aggro/server_spec.rb +118 -0
- data/spec/lib/aggro/subscriber_spec.rb +59 -0
- data/spec/lib/aggro/subscription_spec.rb +50 -0
- data/spec/lib/aggro/transform/boolean_spec.rb +23 -0
- data/spec/lib/aggro/transform/email_spec.rb +13 -0
- data/spec/lib/aggro/transform/id_spec.rb +70 -0
- data/spec/lib/aggro/transform/integer_spec.rb +30 -0
- data/spec/lib/aggro/transform/money_spec.rb +34 -0
- data/spec/lib/aggro/transform/string_spec.rb +15 -0
- data/spec/lib/aggro/transform/time_interval_spec.rb +29 -0
- data/spec/lib/aggro_spec.rb +63 -19
- data/spec/spec_helper.rb +21 -2
- metadata +283 -3
@@ -0,0 +1,23 @@
|
|
1
|
+
module Aggro
|
2
|
+
# Private: Used as a proxy to apply and save events to an aggregate.
|
3
|
+
class EventProxy
|
4
|
+
def initialize(aggregate, id)
|
5
|
+
@aggregate = aggregate
|
6
|
+
@id = id
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(method_sym, *args)
|
10
|
+
details = merge_details_with_command_context(args.pop || {})
|
11
|
+
event = Event.new(method_sym, Time.now, details)
|
12
|
+
|
13
|
+
Aggro.store.write_single @id, event
|
14
|
+
Aggro.event_bus.publish @id, event
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def merge_details_with_command_context(details)
|
20
|
+
@aggregate.instance_variable_get(:@_context).merge(details)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Aggro
|
2
|
+
# Public: Converts events to and from serialized data.
|
3
|
+
module EventSerializer
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def deserialize(serialized)
|
7
|
+
Marshal.load serialized
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialize(deserialized)
|
11
|
+
Marshal.dump deserialized
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'aggro/file_store/reader'
|
2
|
+
require 'aggro/file_store/writer'
|
3
|
+
|
4
|
+
module Aggro
|
5
|
+
# Public: Stores and retrieves events by serializing them to flat files.
|
6
|
+
class FileStore < AbstractStore
|
7
|
+
INDEX_DIRECTORY = 'indexes'.freeze
|
8
|
+
EVENT_DIRECTORY = 'events'.freeze
|
9
|
+
REGISTRY_FILE = 'registry'.freeze
|
10
|
+
|
11
|
+
def initialize(directory)
|
12
|
+
@event_directory = [directory, EVENT_DIRECTORY].join('/')
|
13
|
+
@index_directory = [directory, INDEX_DIRECTORY].join('/')
|
14
|
+
|
15
|
+
FileUtils.mkdir_p @event_directory
|
16
|
+
FileUtils.mkdir_p @index_directory
|
17
|
+
|
18
|
+
@registry_file = [directory, REGISTRY_FILE].join('/')
|
19
|
+
initialize_registry if File.exist? @registry_file
|
20
|
+
end
|
21
|
+
|
22
|
+
def all
|
23
|
+
read registry.keys
|
24
|
+
end
|
25
|
+
|
26
|
+
def create(id, type)
|
27
|
+
File.open(@registry_file, 'ab') do |registry_file|
|
28
|
+
registry_file.write Marshal.dump [id, type]
|
29
|
+
registry[id] = type
|
30
|
+
end
|
31
|
+
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def exists?(id)
|
36
|
+
registry[id] == true
|
37
|
+
end
|
38
|
+
|
39
|
+
def read(ids)
|
40
|
+
ids.map { |id| id_to_event_stream id }
|
41
|
+
end
|
42
|
+
|
43
|
+
def registry
|
44
|
+
@registry ||= {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def write(event_streams)
|
48
|
+
event_streams.each do |stream|
|
49
|
+
FileStore::Writer.new(
|
50
|
+
event_file(stream.id, 'ab'),
|
51
|
+
index_file(stream.id, 'ab')
|
52
|
+
).write stream.events
|
53
|
+
end
|
54
|
+
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def write_single(id, event)
|
59
|
+
FileStore::Writer.new(
|
60
|
+
event_file(id, 'ab'),
|
61
|
+
index_file(id, 'ab')
|
62
|
+
).write [event]
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def event_file(id, flags = 'rb')
|
68
|
+
File.new [@event_directory, id].join('/'), flags
|
69
|
+
end
|
70
|
+
|
71
|
+
def id_to_event_stream(id)
|
72
|
+
EventStream.new id, type_for_id(id), id_to_reader(id).read
|
73
|
+
rescue Errno::ENOENT
|
74
|
+
EventStream.new id, type_for_id(id), []
|
75
|
+
end
|
76
|
+
|
77
|
+
def id_to_reader(id)
|
78
|
+
FileStore::Reader.new event_file(id), index_file(id)
|
79
|
+
end
|
80
|
+
|
81
|
+
def index_file(id, flags = 'rb')
|
82
|
+
File.new [@index_directory, id].join('/'), flags
|
83
|
+
end
|
84
|
+
|
85
|
+
def initialize_registry
|
86
|
+
File.open(@registry_file) do |file|
|
87
|
+
ObjectStream.new(file, type: 'marshal').each do |id, type|
|
88
|
+
registry[id] = type
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def type_for_id(id)
|
94
|
+
registry[id]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Aggro
|
2
|
+
class FileStore < AbstractStore
|
3
|
+
# Private: Deserialized events from an IO object.
|
4
|
+
class Reader
|
5
|
+
def initialize(data_io, index_io)
|
6
|
+
@data_io = data_io
|
7
|
+
@index_io = index_io
|
8
|
+
end
|
9
|
+
|
10
|
+
def read
|
11
|
+
ObjectStream.new(@data_io, type: 'marshal')
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def index
|
17
|
+
@index ||= ObjectStream.new(@index_io, type: 'marshal')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Aggro
|
2
|
+
class FileStore < AbstractStore
|
3
|
+
# Private: Serializes events to an IO object.
|
4
|
+
class Writer
|
5
|
+
def initialize(data_io, index_io)
|
6
|
+
@data_io = data_io
|
7
|
+
@index_io = index_io
|
8
|
+
end
|
9
|
+
|
10
|
+
def write(events)
|
11
|
+
events.each do |event|
|
12
|
+
@data_io.write EventSerializer.serialize(event)
|
13
|
+
write_to_index @data_io.pos
|
14
|
+
end
|
15
|
+
|
16
|
+
@data_io.flush
|
17
|
+
@index_io.flush
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def write_to_index(offset)
|
23
|
+
@index_io.write Marshal.dump(offset)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Aggro
|
2
|
+
module Handler
|
3
|
+
# Private: Handler for incoming command requests.
|
4
|
+
class Command < Struct.new(:message, :server)
|
5
|
+
def call
|
6
|
+
commandee_local? ? handle_local : handle_foreign
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def channel
|
12
|
+
Aggro.channels[commandee_id]
|
13
|
+
end
|
14
|
+
|
15
|
+
def command
|
16
|
+
@command ||= message.to_command
|
17
|
+
end
|
18
|
+
|
19
|
+
def commandee_id
|
20
|
+
message.commandee_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def command_known?
|
24
|
+
!command.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def commandee_local?
|
28
|
+
comandee_locator.local?
|
29
|
+
end
|
30
|
+
|
31
|
+
def comandee_locator
|
32
|
+
@comandee_locator ||= Locator.new(commandee_id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_foreign
|
36
|
+
comandee_locator.primary_node.client.post message
|
37
|
+
end
|
38
|
+
|
39
|
+
def handle_known
|
40
|
+
if channel.handles_command?(command)
|
41
|
+
channel.forward_command command
|
42
|
+
|
43
|
+
Message::OK.new
|
44
|
+
else
|
45
|
+
Message::UnhandledOperation.new
|
46
|
+
end
|
47
|
+
rescue NoMethodError
|
48
|
+
Message::InvalidTarget.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def handle_local
|
52
|
+
command_known? ? handle_known : handle_unknown
|
53
|
+
end
|
54
|
+
|
55
|
+
def handle_unknown
|
56
|
+
Message::UnknownOperation.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Aggro
|
2
|
+
module Handler
|
3
|
+
# Private: Handler for incoming command requests.
|
4
|
+
class CreateAggregate < Struct.new(:message, :server)
|
5
|
+
def call
|
6
|
+
local? ? handle_local : handle_foreign
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def add_to_channels
|
12
|
+
channel = Channel.new(message.id, message.type)
|
13
|
+
Aggro.channels[message.id] = channel
|
14
|
+
end
|
15
|
+
|
16
|
+
def exists_in_channels?
|
17
|
+
Aggro.channels.keys.include?(message.id)
|
18
|
+
end
|
19
|
+
|
20
|
+
def handle_local
|
21
|
+
unless exists_in_channels?
|
22
|
+
Aggro.store.create message.id, message.type
|
23
|
+
add_to_channels
|
24
|
+
end
|
25
|
+
|
26
|
+
Message::OK.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def handle_foreign
|
30
|
+
Message::Ask.new locator.primary_node.id
|
31
|
+
end
|
32
|
+
|
33
|
+
def local?
|
34
|
+
locator.local?
|
35
|
+
end
|
36
|
+
|
37
|
+
def locator
|
38
|
+
@locator ||= Locator.new(message.id)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Aggro
|
2
|
+
module Handler
|
3
|
+
# Private: Handler for incoming command requests.
|
4
|
+
class GetEvents < Struct.new(:message, :server)
|
5
|
+
def call
|
6
|
+
local? ? handle_local : handle_foreign
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def handle_local
|
12
|
+
events = Aggro.store.read([message.id]).first.events
|
13
|
+
|
14
|
+
Message::Events.new(message.id, events.to_a)
|
15
|
+
end
|
16
|
+
|
17
|
+
def handle_foreign
|
18
|
+
Message::Ask.new locator.primary_node.id
|
19
|
+
end
|
20
|
+
|
21
|
+
def local?
|
22
|
+
locator.local?
|
23
|
+
end
|
24
|
+
|
25
|
+
def locator
|
26
|
+
@locator ||= Locator.new(message.id)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Aggro
|
2
|
+
module Handler
|
3
|
+
# Private: Handler for incoming query requests.
|
4
|
+
class Query < Struct.new(:message, :server)
|
5
|
+
def call
|
6
|
+
queryee_local? ? handle_local : handle_foreign
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def channel
|
12
|
+
Aggro.channels[queryable_id]
|
13
|
+
end
|
14
|
+
|
15
|
+
def query
|
16
|
+
@query ||= message.to_query
|
17
|
+
end
|
18
|
+
|
19
|
+
def queryable_id
|
20
|
+
message.queryable_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def query_known?
|
24
|
+
!query.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def queryee_local?
|
28
|
+
comandee_locator.local?
|
29
|
+
end
|
30
|
+
|
31
|
+
def comandee_locator
|
32
|
+
@comandee_locator ||= Locator.new(queryable_id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_foreign
|
36
|
+
comandee_locator.primary_node.client.post message
|
37
|
+
end
|
38
|
+
|
39
|
+
def handle_known
|
40
|
+
if channel.handles_query?(query)
|
41
|
+
result = channel.run_query(query)
|
42
|
+
|
43
|
+
Message::Result.new result.value(5)
|
44
|
+
else
|
45
|
+
Message::UnhandledOperation.new
|
46
|
+
end
|
47
|
+
rescue NoMethodError
|
48
|
+
Message::InvalidTarget.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def handle_local
|
52
|
+
query_known? ? handle_known : handle_unknown
|
53
|
+
end
|
54
|
+
|
55
|
+
def handle_unknown
|
56
|
+
Message::UnknownOperation.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Aggro
|
2
|
+
module Handler
|
3
|
+
# Private: Handler for incoming command requests.
|
4
|
+
class StartSaga < Struct.new(:message, :server)
|
5
|
+
def call
|
6
|
+
locator.local? ? handle_local : handle_foreign
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def create_channel
|
12
|
+
channel = Channel.new message.id, 'Aggro::SagaRunner'
|
13
|
+
|
14
|
+
Aggro.channels[message.id] = channel
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_saga
|
18
|
+
Aggro.store.create message.id, 'Aggro::SagaRunner'
|
19
|
+
end
|
20
|
+
|
21
|
+
def locator
|
22
|
+
@locator ||= Locator.new(message.id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def handle_foreign
|
26
|
+
locator.primary_node.client.post message
|
27
|
+
end
|
28
|
+
|
29
|
+
def handle_known
|
30
|
+
create_saga
|
31
|
+
create_channel
|
32
|
+
|
33
|
+
Aggro.channels[message.id].forward_command start_command
|
34
|
+
|
35
|
+
Message::OK.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def handle_local
|
39
|
+
saga_known? ? handle_known : handle_unknown
|
40
|
+
end
|
41
|
+
|
42
|
+
def handle_unknown
|
43
|
+
Message::UnknownOperation.new
|
44
|
+
end
|
45
|
+
|
46
|
+
def saga_known?
|
47
|
+
ActiveSupport::Inflector.safe_constantize message.name
|
48
|
+
end
|
49
|
+
|
50
|
+
def start_command
|
51
|
+
SagaRunner::StartSaga.new name: message.name, details: message.args,
|
52
|
+
id: message.id
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Aggro
|
2
|
+
# Public: Represents the local aggro server node.
|
3
|
+
class LocalNode < Struct.new(:id)
|
4
|
+
def client
|
5
|
+
@client ||= create_loopback_client
|
6
|
+
end
|
7
|
+
|
8
|
+
def endpoint
|
9
|
+
"tcp://127.0.0.1:#{Aggro.port}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def publisher_endpoint
|
13
|
+
"tcp://127.0.0.1:#{Aggro.publisher_port}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
id
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def create_loopback_client
|
23
|
+
->(msg) { Aggro.server.handle_message msg }.tap do |proc|
|
24
|
+
proc.class_eval { alias_method :post, :call }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|