aggro 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|