railway-ipc 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +8 -0
- data/.tool-versions +1 -0
- data/Gemfile.lock +125 -1
- data/README.md +5 -0
- data/lib/railway_ipc.rb +28 -21
- data/lib/railway_ipc/base_message.pb.rb +21 -0
- data/lib/railway_ipc/consumer/consumer.rb +112 -0
- data/lib/railway_ipc/consumer/consumer_response_handlers.rb +14 -0
- data/lib/railway_ipc/errors.rb +1 -0
- data/lib/railway_ipc/handler.rb +2 -0
- data/lib/railway_ipc/handler_manifest.rb +10 -0
- data/lib/railway_ipc/handler_store.rb +21 -0
- data/lib/railway_ipc/models/consumed_message.rb +48 -0
- data/lib/railway_ipc/models/published_message.rb +27 -0
- data/lib/railway_ipc/null_message.rb +1 -1
- data/lib/railway_ipc/publisher.rb +9 -4
- data/lib/railway_ipc/rabbitmq/adapter.rb +93 -0
- data/lib/railway_ipc/rabbitmq/payload.rb +7 -3
- data/lib/railway_ipc/rpc/client/client.rb +104 -0
- data/lib/railway_ipc/rpc/client/client_response_handlers.rb +25 -0
- data/lib/railway_ipc/rpc/client/errors/timeout_error.rb +5 -0
- data/lib/railway_ipc/rpc/concerns/error_adapter_configurable.rb +13 -0
- data/lib/railway_ipc/rpc/concerns/message_observation_configurable.rb +18 -0
- data/lib/railway_ipc/rpc/concerns/publish_location_configurable.rb +13 -0
- data/lib/railway_ipc/rpc/rpc.rb +2 -0
- data/lib/railway_ipc/rpc/server/server.rb +89 -0
- data/lib/railway_ipc/rpc/server/server_response_handlers.rb +17 -0
- data/lib/railway_ipc/tasks/generate_migrations.rake +26 -0
- data/lib/railway_ipc/version.rb +1 -1
- data/priv/migrations/add_railway_ipc_consumed_messages.rb +19 -0
- data/priv/migrations/add_railway_ipc_published_messages.rb +18 -0
- data/railway_ipc.gemspec +25 -16
- metadata +123 -8
- data/lib/railway_ipc/client.rb +0 -87
- data/lib/railway_ipc/concerns/message_handling.rb +0 -118
- data/lib/railway_ipc/consumer.rb +0 -26
- data/lib/railway_ipc/rabbitmq/connection.rb +0 -55
- data/lib/railway_ipc/server.rb +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 945917b242216c009d199f73de3c559b16b005cdae28504273b2ee68d04ed8df
|
4
|
+
data.tar.gz: 39bc88b82f608a2a74de630c334bd6a7021a92666e8843fc4ba81e3f1b3a2b03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42425f432289124825d92ec02bc3350875070da6554c824fc4cb9f802d961817ae65980b6011566be24696abbecf6613e48166373e5d6476e1cf6498ae64057a
|
7
|
+
data.tar.gz: 9d09e840a91d94a02e4551fa44f2d653e40e716e4606288649320709d54c47cccc8240268b38a550466b92ebd0882f4718bd271256ca520b735d283cbbcd3294
|
data/.gitignore
CHANGED
@@ -9,3 +9,11 @@
|
|
9
9
|
|
10
10
|
# rspec failure tracking
|
11
11
|
.rspec_status
|
12
|
+
|
13
|
+
# rails support app files
|
14
|
+
/spec/support/rails_app/.bundle
|
15
|
+
/spec/support/rails_app/log/*
|
16
|
+
/spec/support/rails_app/tmp/*
|
17
|
+
/spec/support/rails_app!/log/.keep
|
18
|
+
/spec/support/rails_app!/tmp/.keep
|
19
|
+
/spec/support/rails_app.byebug_history
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 2.6.3
|
data/Gemfile.lock
CHANGED
@@ -1,28 +1,122 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
railway-ipc (0.1.
|
4
|
+
railway-ipc (0.1.4)
|
5
5
|
bunny (~> 2.2.0)
|
6
6
|
sneakers (~> 2.3.5)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
+
actioncable (5.0.7.2)
|
12
|
+
actionpack (= 5.0.7.2)
|
13
|
+
nio4r (>= 1.2, < 3.0)
|
14
|
+
websocket-driver (~> 0.6.1)
|
15
|
+
actionmailer (5.0.7.2)
|
16
|
+
actionpack (= 5.0.7.2)
|
17
|
+
actionview (= 5.0.7.2)
|
18
|
+
activejob (= 5.0.7.2)
|
19
|
+
mail (~> 2.5, >= 2.5.4)
|
20
|
+
rails-dom-testing (~> 2.0)
|
21
|
+
actionpack (5.0.7.2)
|
22
|
+
actionview (= 5.0.7.2)
|
23
|
+
activesupport (= 5.0.7.2)
|
24
|
+
rack (~> 2.0)
|
25
|
+
rack-test (~> 0.6.3)
|
26
|
+
rails-dom-testing (~> 2.0)
|
27
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
28
|
+
actionview (5.0.7.2)
|
29
|
+
activesupport (= 5.0.7.2)
|
30
|
+
builder (~> 3.1)
|
31
|
+
erubis (~> 2.7.0)
|
32
|
+
rails-dom-testing (~> 2.0)
|
33
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
34
|
+
activejob (5.0.7.2)
|
35
|
+
activesupport (= 5.0.7.2)
|
36
|
+
globalid (>= 0.3.6)
|
37
|
+
activemodel (5.0.7.2)
|
38
|
+
activesupport (= 5.0.7.2)
|
39
|
+
activerecord (5.0.7.2)
|
40
|
+
activemodel (= 5.0.7.2)
|
41
|
+
activesupport (= 5.0.7.2)
|
42
|
+
arel (~> 7.0)
|
43
|
+
activesupport (5.0.7.2)
|
44
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
45
|
+
i18n (>= 0.7, < 2)
|
46
|
+
minitest (~> 5.1)
|
47
|
+
tzinfo (~> 1.1)
|
11
48
|
amq-protocol (2.3.0)
|
49
|
+
arel (7.1.4)
|
50
|
+
builder (3.2.4)
|
12
51
|
bunny (2.2.2)
|
13
52
|
amq-protocol (>= 2.0.1)
|
14
53
|
byebug (9.1.0)
|
15
54
|
coderay (1.1.2)
|
55
|
+
concurrent-ruby (1.1.5)
|
56
|
+
crass (1.0.5)
|
57
|
+
database_cleaner (1.7.0)
|
16
58
|
diff-lcs (1.3)
|
59
|
+
erubis (2.7.0)
|
60
|
+
factory_bot (5.1.1)
|
61
|
+
activesupport (>= 4.2.0)
|
62
|
+
ffi (1.11.3)
|
63
|
+
globalid (0.4.2)
|
64
|
+
activesupport (>= 4.2.0)
|
17
65
|
google-protobuf (3.9.2)
|
66
|
+
i18n (1.7.0)
|
67
|
+
concurrent-ruby (~> 1.0)
|
68
|
+
listen (3.0.8)
|
69
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
70
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
71
|
+
loofah (2.4.0)
|
72
|
+
crass (~> 1.0.2)
|
73
|
+
nokogiri (>= 1.5.9)
|
74
|
+
mail (2.7.1)
|
75
|
+
mini_mime (>= 0.1.1)
|
18
76
|
method_source (0.9.2)
|
77
|
+
mini_mime (1.0.2)
|
78
|
+
mini_portile2 (2.4.0)
|
79
|
+
minitest (5.13.0)
|
80
|
+
nio4r (2.5.2)
|
81
|
+
nokogiri (1.10.7)
|
82
|
+
mini_portile2 (~> 2.4.0)
|
83
|
+
pg (0.21.0)
|
19
84
|
pry (0.12.2)
|
20
85
|
coderay (~> 1.1.0)
|
21
86
|
method_source (~> 0.9.0)
|
22
87
|
pry-byebug (3.4.2)
|
23
88
|
byebug (~> 9.0)
|
24
89
|
pry (~> 0.10)
|
90
|
+
rack (2.0.7)
|
91
|
+
rack-test (0.6.3)
|
92
|
+
rack (>= 1.0)
|
93
|
+
rails (5.0.7.2)
|
94
|
+
actioncable (= 5.0.7.2)
|
95
|
+
actionmailer (= 5.0.7.2)
|
96
|
+
actionpack (= 5.0.7.2)
|
97
|
+
actionview (= 5.0.7.2)
|
98
|
+
activejob (= 5.0.7.2)
|
99
|
+
activemodel (= 5.0.7.2)
|
100
|
+
activerecord (= 5.0.7.2)
|
101
|
+
activesupport (= 5.0.7.2)
|
102
|
+
bundler (>= 1.3.0)
|
103
|
+
railties (= 5.0.7.2)
|
104
|
+
sprockets-rails (>= 2.0.0)
|
105
|
+
rails-dom-testing (2.0.3)
|
106
|
+
activesupport (>= 4.2.0)
|
107
|
+
nokogiri (>= 1.6)
|
108
|
+
rails-html-sanitizer (1.3.0)
|
109
|
+
loofah (~> 2.3)
|
110
|
+
railties (5.0.7.2)
|
111
|
+
actionpack (= 5.0.7.2)
|
112
|
+
activesupport (= 5.0.7.2)
|
113
|
+
method_source
|
114
|
+
rake (>= 0.8.7)
|
115
|
+
thor (>= 0.18.1, < 2.0)
|
25
116
|
rake (13.0.0)
|
117
|
+
rb-fsevent (0.10.3)
|
118
|
+
rb-inotify (0.10.0)
|
119
|
+
ffi (~> 1.0)
|
26
120
|
rspec (3.8.0)
|
27
121
|
rspec-core (~> 3.8.0)
|
28
122
|
rspec-expectations (~> 3.8.0)
|
@@ -35,28 +129,58 @@ GEM
|
|
35
129
|
rspec-mocks (3.8.1)
|
36
130
|
diff-lcs (>= 1.2.0, < 2.0)
|
37
131
|
rspec-support (~> 3.8.0)
|
132
|
+
rspec-rails (3.8.3)
|
133
|
+
actionpack (>= 3.0)
|
134
|
+
activesupport (>= 3.0)
|
135
|
+
railties (>= 3.0)
|
136
|
+
rspec-core (~> 3.8.0)
|
137
|
+
rspec-expectations (~> 3.8.0)
|
138
|
+
rspec-mocks (~> 3.8.0)
|
139
|
+
rspec-support (~> 3.8.0)
|
38
140
|
rspec-support (3.8.2)
|
39
141
|
serverengine (1.5.11)
|
40
142
|
sigdump (~> 0.2.2)
|
143
|
+
shoulda-matchers (4.2.0)
|
144
|
+
activesupport (>= 4.2.0)
|
41
145
|
sigdump (0.2.4)
|
42
146
|
sneakers (2.3.5)
|
43
147
|
bunny (~> 2.2.0)
|
44
148
|
serverengine (~> 1.5.11)
|
45
149
|
thor
|
46
150
|
thread (~> 0.1.7)
|
151
|
+
sprockets (4.0.0)
|
152
|
+
concurrent-ruby (~> 1.0)
|
153
|
+
rack (> 1, < 3)
|
154
|
+
sprockets-rails (3.2.1)
|
155
|
+
actionpack (>= 4.0)
|
156
|
+
activesupport (>= 4.0)
|
157
|
+
sprockets (>= 3.0.0)
|
47
158
|
thor (0.20.3)
|
48
159
|
thread (0.1.7)
|
160
|
+
thread_safe (0.3.6)
|
161
|
+
tzinfo (1.2.5)
|
162
|
+
thread_safe (~> 0.1)
|
163
|
+
websocket-driver (0.6.5)
|
164
|
+
websocket-extensions (>= 0.1.0)
|
165
|
+
websocket-extensions (0.1.4)
|
49
166
|
|
50
167
|
PLATFORMS
|
51
168
|
ruby
|
52
169
|
|
53
170
|
DEPENDENCIES
|
54
171
|
bundler (= 2.0.1)
|
172
|
+
database_cleaner (~> 1.7)
|
173
|
+
factory_bot (~> 5.1)
|
55
174
|
google-protobuf (~> 3.9)
|
175
|
+
listen (~> 3.0.5)
|
176
|
+
pg (~> 0.18)
|
56
177
|
pry-byebug (= 3.4.2)
|
178
|
+
rails (~> 5.0.7)
|
57
179
|
railway-ipc!
|
58
180
|
rake (>= 10.0.0)
|
59
181
|
rspec (~> 3.0)
|
182
|
+
rspec-rails
|
183
|
+
shoulda-matchers (~> 4.2)
|
60
184
|
|
61
185
|
BUNDLED WITH
|
62
186
|
2.0.1
|
data/README.md
CHANGED
@@ -35,7 +35,12 @@ require "railway_ipc"
|
|
35
35
|
RABBITMQ_CONNECTION_URL=amqp://<railway_user>:<railway_password>@localhost:5672
|
36
36
|
```
|
37
37
|
|
38
|
+
* Load table migrations and migrate by executing:
|
38
39
|
|
40
|
+
```bash
|
41
|
+
bundle exec rake railway_ipc:generate:migrations
|
42
|
+
bundle exec rake db:migrate
|
43
|
+
```
|
39
44
|
|
40
45
|
# Publish/Consume
|
41
46
|
|
data/lib/railway_ipc.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
1
|
+
require 'railway_ipc/version'
|
2
|
+
require 'sneakers'
|
3
|
+
require 'bunny'
|
4
|
+
require 'active_record'
|
5
|
+
require 'railway_ipc/version'
|
6
|
+
require 'railway_ipc/errors'
|
7
|
+
require 'railway_ipc/logger'
|
8
|
+
require 'railway_ipc/unhandled_message_error'
|
9
|
+
require 'railway_ipc/response'
|
10
|
+
require 'railway_ipc/rabbitmq/payload'
|
11
|
+
require 'railway_ipc/null_message'
|
12
|
+
require 'railway_ipc/base_message.pb'
|
13
|
+
require 'railway_ipc/rabbitmq/adapter'
|
14
|
+
require 'railway_ipc/handler'
|
15
|
+
require 'railway_ipc/handler_store'
|
16
|
+
require 'railway_ipc/publisher'
|
17
|
+
require 'railway_ipc/null_handler'
|
18
|
+
require 'railway_ipc/responder'
|
19
|
+
require 'railway_ipc/rpc/rpc'
|
20
|
+
require 'railway_ipc/consumer/consumer'
|
21
|
+
require 'railway_ipc/models/published_message'
|
22
|
+
require 'railway_ipc/models/consumed_message'
|
23
|
+
require 'railway_ipc/railtie' if defined?(Rails)
|
20
24
|
|
21
25
|
module RailwayIpc
|
22
26
|
def self.start
|
23
|
-
Rake::Task[
|
27
|
+
Rake::Task['sneakers:run'].invoke
|
24
28
|
end
|
25
29
|
|
26
30
|
def self.configure(logger: ::Logger.new(STDOUT))
|
@@ -36,6 +40,9 @@ module RailwayIpc
|
|
36
40
|
end
|
37
41
|
|
38
42
|
def self.bunny_connection
|
39
|
-
@bunny_connection ||= RailwayIpc::Rabbitmq::
|
43
|
+
@bunny_connection ||= RailwayIpc::Rabbitmq::Adapter.new(
|
44
|
+
exchange_name: 'default',
|
45
|
+
options: { automatic_recovery: true }
|
46
|
+
).connection
|
40
47
|
end
|
41
48
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# source: lib/src/events/base_message.proto
|
3
|
+
|
4
|
+
require 'google/protobuf'
|
5
|
+
|
6
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
7
|
+
add_message "railway_ipc.BaseMessage" do
|
8
|
+
optional :user_uuid, :string, 1
|
9
|
+
optional :correlation_id, :string, 2
|
10
|
+
optional :uuid, :string, 3
|
11
|
+
map :context, :string, :string, 4
|
12
|
+
optional :data, :message, 5, "railway_ipc.BaseMessage.Data"
|
13
|
+
end
|
14
|
+
add_message "railway_ipc.BaseMessage.Data" do
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module RailwayIpc
|
19
|
+
BaseMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("railway_ipc.BaseMessage").msgclass
|
20
|
+
BaseMessage::Data = Google::Protobuf::DescriptorPool.generated_pool.lookup("railway_ipc.BaseMessage.Data").msgclass
|
21
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "json"
|
2
|
+
require "base64"
|
3
|
+
require "railway_ipc/consumer/consumer_response_handlers"
|
4
|
+
|
5
|
+
module RailwayIpc
|
6
|
+
class Consumer
|
7
|
+
include Sneakers::Worker
|
8
|
+
attr_reader :message, :handler, :protobuff_message, :delivery_info, :decoded_payload
|
9
|
+
|
10
|
+
def self.listen_to(queue:, exchange:)
|
11
|
+
from_queue queue,
|
12
|
+
exchange: exchange,
|
13
|
+
durable: true,
|
14
|
+
exchange_type: :fanout,
|
15
|
+
connection: RailwayIpc.bunny_connection
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.handle(message_type, with:)
|
19
|
+
ConsumerResponseHandlers.instance.register(message: message_type, handler: with)
|
20
|
+
end
|
21
|
+
|
22
|
+
def registered_handlers
|
23
|
+
ConsumerResponseHandlers.instance.registered
|
24
|
+
end
|
25
|
+
|
26
|
+
def work_with_params(payload, delivery_info, _metadata)
|
27
|
+
@delivery_info = delivery_info
|
28
|
+
@decoded_payload = RailwayIpc::Rabbitmq::Payload.decode(payload)
|
29
|
+
|
30
|
+
case decoded_payload.type
|
31
|
+
when *registered_handlers
|
32
|
+
@handler = handler_for(decoded_payload)
|
33
|
+
message_klass = message_handler_for(decoded_payload)
|
34
|
+
@protobuff_message = message_klass.decode(decoded_payload.message)
|
35
|
+
process_known_message_type
|
36
|
+
else
|
37
|
+
@handler = RailwayIpc::NullHandler.new
|
38
|
+
@protobuff_message = RailwayIpc::BaseMessage.decode(decoded_payload.message)
|
39
|
+
process_unknown_message_type
|
40
|
+
end
|
41
|
+
|
42
|
+
rescue StandardError => e
|
43
|
+
RailwayIpc.logger.log_exception(
|
44
|
+
feature: "railway_consumer",
|
45
|
+
error: e.class,
|
46
|
+
error_message: e.message,
|
47
|
+
payload: payload,
|
48
|
+
)
|
49
|
+
raise e
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def process_protobuff!(message)
|
55
|
+
if handler.handle(protobuff_message).success?
|
56
|
+
message.status = RailwayIpc::ConsumedMessage::STATUSES[:success]
|
57
|
+
else
|
58
|
+
message.status = RailwayIpc::ConsumedMessage::STATUSES[:failed_to_process]
|
59
|
+
end
|
60
|
+
|
61
|
+
message.save!
|
62
|
+
end
|
63
|
+
|
64
|
+
def process_known_message_type
|
65
|
+
message = RailwayIpc::ConsumedMessage.find_by(uuid: protobuff_message.uuid)
|
66
|
+
|
67
|
+
if message && message.processed?
|
68
|
+
handler.ack!
|
69
|
+
elsif message && !message.processed?
|
70
|
+
message.with_lock("FOR UPDATE NOWAIT") { process_protobuff!(message) }
|
71
|
+
else
|
72
|
+
message = create_message_with_status!(RailwayIpc::ConsumedMessage::STATUSES[:processing])
|
73
|
+
message.with_lock("FOR UPDATE NOWAIT") { process_protobuff!(message) }
|
74
|
+
end
|
75
|
+
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
|
79
|
+
def process_unknown_message_type
|
80
|
+
handler.ack!
|
81
|
+
|
82
|
+
if RailwayIpc::ConsumedMessage.exists?(uuid: protobuff_message.uuid)
|
83
|
+
return
|
84
|
+
else
|
85
|
+
create_message_with_status!(RailwayIpc::ConsumedMessage::STATUSES[:unknown_message_type])
|
86
|
+
end
|
87
|
+
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_message_with_status!(status)
|
92
|
+
RailwayIpc::ConsumedMessage.create!(
|
93
|
+
uuid: protobuff_message.uuid,
|
94
|
+
status: status,
|
95
|
+
message_type: decoded_payload.type,
|
96
|
+
user_uuid: protobuff_message.user_uuid,
|
97
|
+
correlation_id: protobuff_message.correlation_id,
|
98
|
+
queue: delivery_info.consumer.queue.name,
|
99
|
+
exchange: delivery_info.exchange,
|
100
|
+
encoded_message: decoded_payload.message
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def message_handler_for(decoded_payload)
|
105
|
+
ConsumerResponseHandlers.instance.get(decoded_payload.type).message
|
106
|
+
end
|
107
|
+
|
108
|
+
def handler_for(decoded_payload)
|
109
|
+
ConsumerResponseHandlers.instance.get(decoded_payload.type).handler.new
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'railway_ipc/handler_store'
|
2
|
+
module RailwayIpc
|
3
|
+
class ConsumerResponseHandlers
|
4
|
+
include Singleton
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators :handler_store, :registered, :register, :get
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def handler_store
|
11
|
+
@handler_store ||= RailwayIpc::HandlerStore.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
class RailwayIpc::InvalidProtobuf < StandardError; end
|