railway-ipc 0.1.3 → 0.1.4
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/.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
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'railway_ipc/rpc/server/server_response_handlers'
|
2
|
+
require 'railway_ipc/rpc/concerns/error_adapter_configurable'
|
3
|
+
require 'railway_ipc/rpc/concerns/message_observation_configurable'
|
4
|
+
|
5
|
+
module RailwayIpc
|
6
|
+
class Server
|
7
|
+
extend RailwayIpc::RPC::ErrorAdapterConfigurable
|
8
|
+
extend RailwayIpc::RPC::MessageObservationConfigurable
|
9
|
+
attr_reader :message, :responder
|
10
|
+
|
11
|
+
def self.respond_to(message_type, with:)
|
12
|
+
RailwayIpc::RPC::ServerResponseHandlers.instance.register(handler: with, message: message_type)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(opts = {automatic_recovery: true}, rabbit_adapter: RailwayIpc::Rabbitmq::Adapter)
|
16
|
+
@rabbit_connection = rabbit_adapter.new(
|
17
|
+
queue_name: self.class.queue_name,
|
18
|
+
exchange_name: self.class.exchange_name,
|
19
|
+
options: opts
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def run
|
24
|
+
rabbit_connection
|
25
|
+
.connect
|
26
|
+
.create_exchange
|
27
|
+
.create_queue(durable: true)
|
28
|
+
.bind_queue_to_exchange
|
29
|
+
subscribe_to_queue
|
30
|
+
end
|
31
|
+
|
32
|
+
def work(payload)
|
33
|
+
decoded_payload = RailwayIpc::Rabbitmq::Payload.decode(payload)
|
34
|
+
case decoded_payload.type
|
35
|
+
when *registered_handlers
|
36
|
+
responder = get_responder(decoded_payload)
|
37
|
+
@message = get_message_class(decoded_payload).decode(decoded_payload.message)
|
38
|
+
responder.respond(message)
|
39
|
+
else
|
40
|
+
@message = LearnIpc::ErrorMessage.decode(decoded_payload.message)
|
41
|
+
raise RailwayIpc::UnhandledMessageError, "#{self.class} does not know how to handle #{decoded_payload.type}"
|
42
|
+
end
|
43
|
+
rescue StandardError => e
|
44
|
+
RailwayIpc.logger.log_exception(
|
45
|
+
feature: 'railway_consumer',
|
46
|
+
error: e.class,
|
47
|
+
error_message: e.message,
|
48
|
+
payload: payload
|
49
|
+
)
|
50
|
+
raise e
|
51
|
+
end
|
52
|
+
|
53
|
+
def handle_request(payload)
|
54
|
+
response = work(payload)
|
55
|
+
rescue StandardError => e
|
56
|
+
RailwayIpc.logger.error(message, "Error responding to message. Error: #{e.class}, #{e.message}")
|
57
|
+
response = self.class.rpc_error_adapter_class.error_message(e, message)
|
58
|
+
ensure
|
59
|
+
if response
|
60
|
+
rabbit_connection.reply(
|
61
|
+
RailwayIpc::Rabbitmq::Payload.encode(response), message.reply_to
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
attr_reader :rabbit_connection
|
69
|
+
|
70
|
+
def get_message_class(decoded_payload)
|
71
|
+
RailwayIpc::RPC::ServerResponseHandlers.instance.get(decoded_payload.type).message
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_responder(decoded_payload)
|
75
|
+
RailwayIpc::RPC::ServerResponseHandlers.instance.get(decoded_payload.type).handler.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def registered_handlers
|
79
|
+
RailwayIpc::RPC::ServerResponseHandlers.instance.registered
|
80
|
+
end
|
81
|
+
|
82
|
+
def subscribe_to_queue
|
83
|
+
rabbit_connection.subscribe do |_delivery_info, _metadata, payload|
|
84
|
+
handle_request(payload)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'railway_ipc/handler_store'
|
2
|
+
module RailwayIpc
|
3
|
+
module RPC
|
4
|
+
class ServerResponseHandlers
|
5
|
+
include Singleton
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :handler_store, :registered, :register, :get
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def handler_store
|
13
|
+
@handler_store ||= RailwayIpc::HandlerStore.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
namespace :railway_ipc do
|
4
|
+
namespace :generate do
|
5
|
+
desc "Generates migrations to store Railway messages"
|
6
|
+
task :migrations do
|
7
|
+
if defined?(ActiveRecord::Base)
|
8
|
+
puts "generating Railway IPC table migrations"
|
9
|
+
seconds = 0
|
10
|
+
gem_path = Gem.loaded_specs['railway-ipc'].full_gem_path
|
11
|
+
folder_dest = "#{Rails.root.to_s}/db/migrate"
|
12
|
+
FileUtils.mkdir_p(folder_dest)
|
13
|
+
|
14
|
+
Dir.glob("#{gem_path}/priv/migrations/*.rb").each do |file_path|
|
15
|
+
file_name = File.basename(file_path)
|
16
|
+
migration_timestamp = (Time.now + seconds).utc.strftime("%Y%m%d%H%M%S") % "%.14d"
|
17
|
+
new_file_name = "#{migration_timestamp}_#{file_name}"
|
18
|
+
FileUtils.copy_file(file_path, "#{folder_dest}/#{new_file_name}")
|
19
|
+
seconds += 1
|
20
|
+
end
|
21
|
+
else
|
22
|
+
raise "Migration generation requires active record"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/railway_ipc/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
class AddRailwayIpcConsumedMessages < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :railway_ipc_consumed_messages, id: false do | t |
|
4
|
+
t.uuid :uuid, null: false
|
5
|
+
t.string :message_type
|
6
|
+
t.uuid :user_uuid
|
7
|
+
t.uuid :correlation_id
|
8
|
+
t.text :encoded_message
|
9
|
+
t.string :status, null: false
|
10
|
+
t.string :queue
|
11
|
+
t.string :exchange
|
12
|
+
|
13
|
+
t.datetime :updated_at
|
14
|
+
t.datetime :inserted_at
|
15
|
+
end
|
16
|
+
|
17
|
+
add_index :railway_ipc_consumed_messages, :uuid, unique: true
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class AddRailwayIpcPublishedMessages < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :railway_ipc_published_messages, id: false do | t |
|
4
|
+
t.uuid :uuid, null: false
|
5
|
+
t.string :message_type
|
6
|
+
t.uuid :user_uuid
|
7
|
+
t.uuid :correlation_id
|
8
|
+
t.text :encoded_message
|
9
|
+
t.string :status, null: false
|
10
|
+
t.string :exchange
|
11
|
+
|
12
|
+
t.datetime :updated_at
|
13
|
+
t.datetime :inserted_at
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :railway_ipc_published_messages, :uuid, unique: true
|
17
|
+
end
|
18
|
+
end
|
data/railway_ipc.gemspec
CHANGED
@@ -3,15 +3,15 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
require "railway_ipc/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name
|
7
|
-
spec.version
|
8
|
-
spec.authors
|
9
|
-
spec.email
|
6
|
+
spec.name = "railway-ipc"
|
7
|
+
spec.version = RailwayIpc::VERSION
|
8
|
+
spec.authors = ""
|
9
|
+
spec.email = ""
|
10
10
|
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
11
|
+
spec.summary = %q{IPC components for Rails}
|
12
|
+
spec.description = %q{IPC components for Rails}
|
13
|
+
spec.homepage = "http://learn.co"
|
14
|
+
spec.license = "MIT"
|
15
15
|
|
16
16
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
17
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
@@ -19,23 +19,32 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
20
20
|
else
|
21
21
|
raise "RubyGems 2.0 or newer is required to protect against " \
|
22
|
-
|
22
|
+
"public gem pushes."
|
23
23
|
end
|
24
24
|
|
25
25
|
# Specify which files should be added to the gem when it is released.
|
26
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
27
|
-
spec.files
|
27
|
+
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
28
28
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
29
29
|
end
|
30
|
-
spec.bindir
|
31
|
-
spec.executables
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
32
|
spec.require_paths = ["lib"]
|
33
33
|
|
34
34
|
spec.add_development_dependency "rake", ">= 10.0.0"
|
35
35
|
spec.add_development_dependency "bundler", "2.0.1"
|
36
36
|
spec.add_development_dependency "rspec", "~> 3.0"
|
37
|
-
spec.add_development_dependency "
|
38
|
-
spec.add_development_dependency
|
39
|
-
spec.
|
40
|
-
spec.add_dependency
|
37
|
+
spec.add_development_dependency "factory_bot", "~> 5.1"
|
38
|
+
spec.add_development_dependency "pry-byebug", "3.4.2"
|
39
|
+
spec.add_development_dependency "google-protobuf", "~> 3.9"
|
40
|
+
spec.add_dependency "sneakers", "~> 2.3.5"
|
41
|
+
spec.add_dependency "bunny", "~> 2.2.0"
|
42
|
+
|
43
|
+
# Setup for testing Rails type code within mock Rails app
|
44
|
+
spec.add_development_dependency "rails", "~> 5.0.7"
|
45
|
+
spec.add_development_dependency "rspec-rails"
|
46
|
+
spec.add_development_dependency "pg", "~> 0.18"
|
47
|
+
spec.add_development_dependency "shoulda-matchers", "~> 4.2"
|
48
|
+
spec.add_development_dependency "database_cleaner", "~> 1.7"
|
49
|
+
spec.add_development_dependency "listen", "~> 3.0.5"
|
41
50
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: railway-ipc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: factory_bot
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.1'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: pry-byebug
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +122,90 @@ dependencies:
|
|
108
122
|
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: 2.2.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rails
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 5.0.7
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 5.0.7
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rspec-rails
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: pg
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.18'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.18'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: shoulda-matchers
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '4.2'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '4.2'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: database_cleaner
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '1.7'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '1.7'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: listen
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 3.0.5
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 3.0.5
|
111
209
|
description: IPC components for Rails
|
112
210
|
email: ''
|
113
211
|
executables: []
|
@@ -116,6 +214,7 @@ extra_rdoc_files: []
|
|
116
214
|
files:
|
117
215
|
- ".gitignore"
|
118
216
|
- ".rspec"
|
217
|
+
- ".tool-versions"
|
119
218
|
- ".travis.yml"
|
120
219
|
- CODE_OF_CONDUCT.md
|
121
220
|
- Gemfile
|
@@ -127,24 +226,40 @@ files:
|
|
127
226
|
- bin/setup
|
128
227
|
- lib/railway_ipc.rb
|
129
228
|
- lib/railway_ipc/Rakefile
|
130
|
-
- lib/railway_ipc/
|
131
|
-
- lib/railway_ipc/
|
132
|
-
- lib/railway_ipc/consumer.rb
|
229
|
+
- lib/railway_ipc/base_message.pb.rb
|
230
|
+
- lib/railway_ipc/consumer/consumer.rb
|
231
|
+
- lib/railway_ipc/consumer/consumer_response_handlers.rb
|
232
|
+
- lib/railway_ipc/errors.rb
|
133
233
|
- lib/railway_ipc/handler.rb
|
234
|
+
- lib/railway_ipc/handler_manifest.rb
|
235
|
+
- lib/railway_ipc/handler_store.rb
|
134
236
|
- lib/railway_ipc/logger.rb
|
237
|
+
- lib/railway_ipc/models/consumed_message.rb
|
238
|
+
- lib/railway_ipc/models/published_message.rb
|
135
239
|
- lib/railway_ipc/null_handler.rb
|
136
240
|
- lib/railway_ipc/null_message.rb
|
137
241
|
- lib/railway_ipc/publisher.rb
|
138
|
-
- lib/railway_ipc/rabbitmq/
|
242
|
+
- lib/railway_ipc/rabbitmq/adapter.rb
|
139
243
|
- lib/railway_ipc/rabbitmq/payload.rb
|
140
244
|
- lib/railway_ipc/railtie.rb
|
141
245
|
- lib/railway_ipc/responder.rb
|
142
246
|
- lib/railway_ipc/response.rb
|
143
|
-
- lib/railway_ipc/
|
247
|
+
- lib/railway_ipc/rpc/client/client.rb
|
248
|
+
- lib/railway_ipc/rpc/client/client_response_handlers.rb
|
249
|
+
- lib/railway_ipc/rpc/client/errors/timeout_error.rb
|
250
|
+
- lib/railway_ipc/rpc/concerns/error_adapter_configurable.rb
|
251
|
+
- lib/railway_ipc/rpc/concerns/message_observation_configurable.rb
|
252
|
+
- lib/railway_ipc/rpc/concerns/publish_location_configurable.rb
|
253
|
+
- lib/railway_ipc/rpc/rpc.rb
|
254
|
+
- lib/railway_ipc/rpc/server/server.rb
|
255
|
+
- lib/railway_ipc/rpc/server/server_response_handlers.rb
|
256
|
+
- lib/railway_ipc/tasks/generate_migrations.rake
|
144
257
|
- lib/railway_ipc/tasks/start_consumers.rake
|
145
258
|
- lib/railway_ipc/tasks/start_servers.rake
|
146
259
|
- lib/railway_ipc/unhandled_message_error.rb
|
147
260
|
- lib/railway_ipc/version.rb
|
261
|
+
- priv/migrations/add_railway_ipc_consumed_messages.rb
|
262
|
+
- priv/migrations/add_railway_ipc_published_messages.rb
|
148
263
|
- railway_ipc.gemspec
|
149
264
|
homepage: http://learn.co
|
150
265
|
licenses:
|
@@ -167,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
282
|
version: '0'
|
168
283
|
requirements: []
|
169
284
|
rubyforge_project:
|
170
|
-
rubygems_version: 2.7.
|
285
|
+
rubygems_version: 2.7.6.2
|
171
286
|
signing_key:
|
172
287
|
specification_version: 4
|
173
288
|
summary: IPC components for Rails
|
data/lib/railway_ipc/client.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
require "railway_ipc/rabbitmq/connection"
|
2
|
-
require "railway_ipc/concerns/message_handling"
|
3
|
-
|
4
|
-
module RailwayIpc
|
5
|
-
class Client
|
6
|
-
include RailwayIpc::Rabbitmq::Connection
|
7
|
-
include RailwayIpc::Concerns::MessageHandling
|
8
|
-
|
9
|
-
class TimeoutError < StandardError; end
|
10
|
-
|
11
|
-
attr_accessor :call_id, :response, :lock, :condition, :reply_queue, :request_message
|
12
|
-
|
13
|
-
def self.request(message)
|
14
|
-
new.request(message)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.publish_to(queue:, exchange:)
|
18
|
-
queue(queue)
|
19
|
-
exchange(exchange)
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(queue=nil, pool=nil, opts={automatic_recovery: false})
|
23
|
-
super
|
24
|
-
setup_exchange
|
25
|
-
end
|
26
|
-
|
27
|
-
def request(request_message, timeout=10)
|
28
|
-
@request_message = request_message
|
29
|
-
setup_reply_queue
|
30
|
-
publish_message
|
31
|
-
poll_for_message(timeout)
|
32
|
-
build_timeout_response unless response
|
33
|
-
response
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def setup_exchange
|
39
|
-
@exchange = Bunny::Exchange.new(channel, :fanout, self.class.exchange_name, durable: true)
|
40
|
-
channel.queue(self.class.queue_name, durable: true).bind(exchange)
|
41
|
-
end
|
42
|
-
|
43
|
-
def setup_reply_queue
|
44
|
-
@reply_queue = channel.queue('', auto_delete: true, exclusive: true)
|
45
|
-
@call_id = request_message.correlation_id
|
46
|
-
request_message.reply_to = reply_queue.name
|
47
|
-
end
|
48
|
-
|
49
|
-
def publish_message
|
50
|
-
RailwayIpc.logger.info(request_message, "Sending request")
|
51
|
-
exchange.publish(RailwayIpc::Rabbitmq::Payload.encode(request_message), routing_key: '')
|
52
|
-
end
|
53
|
-
|
54
|
-
def poll_for_message(timeout)
|
55
|
-
count = 0
|
56
|
-
until response || count >= timeout do
|
57
|
-
delivery_info, properties, payload = reply_queue.pop
|
58
|
-
handle_response(payload) if payload
|
59
|
-
count+= 1
|
60
|
-
sleep(1)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def build_timeout_response
|
65
|
-
error = TimeoutError.new("Client timed out")
|
66
|
-
response_message = rpc_error_adapter.error_message(error, request_message)
|
67
|
-
self.response = RailwayIpc::Response.new(response_message, success: false)
|
68
|
-
self.stop
|
69
|
-
end
|
70
|
-
|
71
|
-
def handle_response(payload)
|
72
|
-
begin
|
73
|
-
response_message = work(payload)
|
74
|
-
if response_message.correlation_id == self.call_id
|
75
|
-
RailwayIpc.logger.info(response_message, "Handling response")
|
76
|
-
self.response = RailwayIpc::Response.new(response_message, success: true)
|
77
|
-
self.stop
|
78
|
-
end
|
79
|
-
rescue StandardError => e
|
80
|
-
RailwayIpc.logger.error(message, "Error handling response. Error #{e.class}, message: #{e.message}")
|
81
|
-
response_message = rpc_error_adapter.error_message(e, message)
|
82
|
-
self.response = RailwayIpc::Response.new(response_message, success: false)
|
83
|
-
self.stop
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|