railway-ipc 1.1.0 → 2.0.0
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/CHANGELOG.md +11 -0
- data/README.md +1 -1
- data/lib/railway_ipc.rb +3 -7
- data/lib/railway_ipc/consumer/consumer.rb +5 -3
- data/lib/railway_ipc/consumer/process_incoming_message.rb +13 -5
- data/lib/railway_ipc/handler.rb +15 -3
- data/lib/railway_ipc/logger.rb +30 -25
- data/lib/railway_ipc/publisher.rb +24 -7
- data/lib/railway_ipc/rabbitmq/adapter.rb +1 -1
- data/lib/railway_ipc/responder.rb +5 -1
- data/lib/railway_ipc/rpc/client/client.rb +20 -5
- data/lib/railway_ipc/rpc/server/server.rb +17 -4
- data/lib/railway_ipc/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11e49c11ff3e5815f7c8050ad5fcdfde1510cf7646d10cfa5d1104a5c1868422
|
4
|
+
data.tar.gz: 3fbdeab2e555f9c4b3402cf27e3b072d33c833f85659eaccc09f31d11fddc219
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70d3834ac2a0db7b1a9a53c52edb3718b34a821d3b0d42e49ebe01f1c76c00188b928734a5969ef621e9609a3852117fd8190706566777c870b2b8b3d9592ccd
|
7
|
+
data.tar.gz: 297bbf2e92f9a77d85661849f3bbada5b18eff08b213ec6a48089dea112ab65b70a47b196e8ddc59b475e61cb9e6ecfc8648bb5dcbcd2836e341079d81b2fd92
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
10
10
|
### Removed
|
11
11
|
### Fixed
|
12
12
|
|
13
|
+
## [2.0.0] - 2020-08-20
|
14
|
+
### Added
|
15
|
+
* Several additions to internal logging:
|
16
|
+
- Log messages now include a `feature` key. This can be used by logging aggregator tools to group log messages across different systems that use the gem. If one isn't provided a default value of `railway_ipc` is used.
|
17
|
+
- Protobufs are logged as a sub-hash which contains both the protobuf type and payload.
|
18
|
+
- Exchange and queue names are logged where applicable.
|
19
|
+
- The internal Bunny connection now uses the `RailwayIpc::Logger` instead of a generic `Logger`.
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
* *Breaking Change* `RailwayIpc.configure` now takes `device`, `level`, and `formatter` instead of a complete `Logger` instance. The instance is now managed internally by Railway. This is a breaking change to the `RailwayIpc.configure` API, clients will need to be updated to use the new syntax.
|
23
|
+
|
13
24
|
## [1.1.0] - 2020-08-07
|
14
25
|
### Changed
|
15
26
|
* allow multiple consumers to handle the same message
|
data/README.md
CHANGED
data/lib/railway_ipc.rb
CHANGED
@@ -29,16 +29,12 @@ module RailwayIpc
|
|
29
29
|
Rake::Task['sneakers:run'].invoke
|
30
30
|
end
|
31
31
|
|
32
|
-
def self.configure(
|
33
|
-
@logger = RailwayIpc::Logger.new(
|
32
|
+
def self.configure(log_device=STDOUT, level=::Logger::INFO, log_formatter=nil)
|
33
|
+
@logger = RailwayIpc::Logger.new(log_device, level, log_formatter)
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.logger
|
37
|
-
@logger || RailwayIpc::Logger.new(
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.bunny_logger
|
41
|
-
logger.logger
|
37
|
+
@logger || RailwayIpc::Logger.new(STDOUT)
|
42
38
|
end
|
43
39
|
|
44
40
|
def self.bunny_connection
|
@@ -44,10 +44,12 @@ module RailwayIpc
|
|
44
44
|
RailwayIpc::ProcessIncomingMessage.call(self, message)
|
45
45
|
ack!
|
46
46
|
rescue StandardError => e
|
47
|
-
RailwayIpc.logger.
|
48
|
-
|
47
|
+
RailwayIpc.logger.error(
|
48
|
+
e.message,
|
49
|
+
feature: 'railway_ipc_consumer',
|
50
|
+
exchange: exchange_name,
|
51
|
+
queue: queue_name,
|
49
52
|
error: e.class,
|
50
|
-
error_message: e.message,
|
51
53
|
payload: payload
|
52
54
|
)
|
53
55
|
raise e
|
@@ -16,8 +16,9 @@ module RailwayIpc
|
|
16
16
|
|
17
17
|
def run
|
18
18
|
logger.warn(
|
19
|
-
incoming_message.
|
20
|
-
|
19
|
+
"Ignoring unknown message of type '#{incoming_message.type}'",
|
20
|
+
feature: 'railway_ipc_consumer',
|
21
|
+
protobuf: { type: incoming_message.type, data: incoming_message.decoded }
|
21
22
|
)
|
22
23
|
end
|
23
24
|
end
|
@@ -36,8 +37,9 @@ module RailwayIpc
|
|
36
37
|
|
37
38
|
def run
|
38
39
|
logger.warn(
|
39
|
-
incoming_message.
|
40
|
-
|
40
|
+
"Ignoring message, no registered handler for '#{incoming_message.type}'",
|
41
|
+
feature: 'railway_ipc_consumer',
|
42
|
+
protobuf: { type: incoming_message.type, data: incoming_message.decoded }
|
41
43
|
)
|
42
44
|
end
|
43
45
|
end
|
@@ -81,7 +83,13 @@ module RailwayIpc
|
|
81
83
|
|
82
84
|
def raise_message_invalid_error
|
83
85
|
error = "Message is invalid: #{incoming_message.stringify_errors}."
|
84
|
-
logger.error(
|
86
|
+
logger.error(
|
87
|
+
error,
|
88
|
+
feature: 'railway_ipc_consumer',
|
89
|
+
exchange: consumer.exchange_name,
|
90
|
+
queue: consumer.queue_name,
|
91
|
+
protobuf: { type: incoming_message.class, data: incoming_message.decoded }
|
92
|
+
)
|
85
93
|
raise RailwayIpc::IncomingMessage::InvalidMessage.new(error)
|
86
94
|
end
|
87
95
|
|
data/lib/railway_ipc/handler.rb
CHANGED
@@ -11,15 +11,27 @@ module RailwayIpc
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def handle(message)
|
14
|
-
RailwayIpc.logger.info(
|
14
|
+
RailwayIpc.logger.info('Handling message', log_message_options(message))
|
15
15
|
response = self.class.block.call(message)
|
16
16
|
if response.success?
|
17
|
-
RailwayIpc.logger.info(
|
17
|
+
RailwayIpc.logger.info('Successfully handled message', log_message_options(message))
|
18
18
|
else
|
19
|
-
RailwayIpc.logger.error(
|
19
|
+
RailwayIpc.logger.error('Failed to handle message', log_message_options(message))
|
20
20
|
end
|
21
21
|
|
22
22
|
response
|
23
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def log_message_options(message)
|
28
|
+
{
|
29
|
+
feature: 'railway_ipc_consumer',
|
30
|
+
protobuf: {
|
31
|
+
type: message.class.name,
|
32
|
+
data: message
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
24
36
|
end
|
25
37
|
end
|
data/lib/railway_ipc/logger.rb
CHANGED
@@ -1,36 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailwayIpc
|
4
|
+
# Custom logger that accepts a `device`, `level`, and `formatter`.
|
5
|
+
# `formatter` can be any object that responds to `call`; a
|
6
|
+
# `Logger::Formatter` is used if the argument is not provided.
|
7
|
+
#
|
8
|
+
# Here is an example formatter that uses `Oj` to format structured log
|
9
|
+
# messages:
|
10
|
+
#
|
11
|
+
# require 'oj'
|
12
|
+
# OjFormatter = proc do |severity, datetime, progname, data|
|
13
|
+
# data.merge!(
|
14
|
+
# name: progname,
|
15
|
+
# timestamp: datetime,
|
16
|
+
# severity: severity
|
17
|
+
# )
|
18
|
+
# Oj.dump(data, { mode: :compat, time_format: :xmlschema })
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# logger = RailwayIpc::Logger.new(STDOUT, Logger::INFO, OjFormatter)
|
22
|
+
#
|
4
23
|
class Logger
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@logger =
|
9
|
-
end
|
10
|
-
|
11
|
-
def info(message, statement)
|
12
|
-
logger.info("[#{message_header(message)}] #{statement}")
|
24
|
+
def initialize(device=STDOUT, level=::Logger::INFO, formatter=nil)
|
25
|
+
@logger = ::Logger.new(device)
|
26
|
+
@logger.level = level
|
27
|
+
@logger.formatter = formatter if formatter
|
13
28
|
end
|
14
29
|
|
15
|
-
|
16
|
-
|
30
|
+
%w[fatal error warn info debug].each do |level|
|
31
|
+
define_method(level) do |message, data={}|
|
32
|
+
data.merge!(feature: 'railway_ipc') unless data.key?(:feature)
|
33
|
+
logger.send(level, data.merge(message: message))
|
34
|
+
end
|
17
35
|
end
|
18
36
|
|
19
|
-
|
20
|
-
logger.debug("[#{message_header(message)}] #{statement}")
|
21
|
-
end
|
37
|
+
private
|
22
38
|
|
23
|
-
|
24
|
-
logger.error("[#{message_header(message)}] #{statement}")
|
25
|
-
end
|
26
|
-
|
27
|
-
def log_exception(exception)
|
28
|
-
logger.error(exception)
|
29
|
-
end
|
30
|
-
|
31
|
-
def message_header(message)
|
32
|
-
log_statement = "message type: #{message.class}, uuid: #{message.uuid}, correlation_id: #{message.correlation_id}"
|
33
|
-
message.respond_to?(:user_uuid) ? "#{log_statement}, user_uuid: #{message.user_uuid}" : log_statement
|
34
|
-
end
|
39
|
+
attr_reader :logger
|
35
40
|
end
|
36
41
|
end
|
@@ -21,16 +21,15 @@ module RailwayIpc
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def publish(message, published_message_store=RailwayIpc::PublishedMessage)
|
24
|
-
RailwayIpc.logger.
|
24
|
+
RailwayIpc.logger.warn('DEPRECATED: Use new PublisherInstance class', log_message_options)
|
25
25
|
ensure_message_uuid(message)
|
26
26
|
ensure_correlation_id(message)
|
27
|
-
RailwayIpc.logger.info(
|
28
|
-
|
27
|
+
RailwayIpc.logger.info('Publishing message', log_message_options(message))
|
29
28
|
result = super(RailwayIpc::Rabbitmq::Payload.encode(message))
|
30
29
|
published_message_store.store_message(self.class.exchange_name, message)
|
31
30
|
result
|
32
31
|
rescue RailwayIpc::InvalidProtobuf => e
|
33
|
-
RailwayIpc.logger.error(
|
32
|
+
RailwayIpc.logger.error('Invalid protobuf', log_message_options(message))
|
34
33
|
raise e
|
35
34
|
end
|
36
35
|
|
@@ -45,6 +44,11 @@ module RailwayIpc
|
|
45
44
|
message.correlation_id = SecureRandom.uuid if message.correlation_id.blank?
|
46
45
|
message
|
47
46
|
end
|
47
|
+
|
48
|
+
def log_message_options(message=nil)
|
49
|
+
options = { feature: 'railway_ipc_publisher', exchange: self.class.exchange_name }
|
50
|
+
message.nil? ? options : options.merge(protobuf: { type: message.class, data: message })
|
51
|
+
end
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -68,20 +72,33 @@ module RailwayIpc
|
|
68
72
|
def publish(message)
|
69
73
|
message.uuid = SecureRandom.uuid if message.uuid.blank?
|
70
74
|
message.correlation_id = SecureRandom.uuid if message.correlation_id.blank?
|
71
|
-
RailwayIpc.logger.info(
|
75
|
+
RailwayIpc.logger.info('Publishing message', log_message_options(message))
|
72
76
|
|
73
77
|
stored_message = message_store.store_message(exchange_name, message)
|
74
78
|
super(RailwayIpc::Rabbitmq::Payload.encode(message))
|
75
79
|
rescue RailwayIpc::InvalidProtobuf => e
|
76
|
-
RailwayIpc.logger.error(
|
80
|
+
RailwayIpc.logger.error('Invalid protobuf', log_message_options(message))
|
77
81
|
raise e
|
78
82
|
rescue ActiveRecord::RecordInvalid => e
|
79
|
-
RailwayIpc.logger.error(
|
83
|
+
RailwayIpc.logger.error('Failed to store outgoing message', log_message_options(message))
|
80
84
|
raise RailwayIpc::FailedToStoreOutgoingMessage.new(e)
|
81
85
|
rescue StandardError => e
|
82
86
|
stored_message&.destroy
|
83
87
|
raise e
|
84
88
|
end
|
85
89
|
# rubocop:enable Metrics/AbcSize
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def log_message_options(message)
|
94
|
+
{
|
95
|
+
feature: 'railway_ipc_publisher',
|
96
|
+
exchange: exchange_name,
|
97
|
+
protobuf: {
|
98
|
+
type: message.class,
|
99
|
+
data: message
|
100
|
+
}
|
101
|
+
}
|
102
|
+
end
|
86
103
|
end
|
87
104
|
end
|
@@ -11,7 +11,11 @@ module RailwayIpc
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def respond(request)
|
14
|
-
RailwayIpc.logger.info(
|
14
|
+
RailwayIpc.logger.info(
|
15
|
+
'Responding to request',
|
16
|
+
protobuf: { type: request.class, data: request },
|
17
|
+
feature: 'railway_ipc_request'
|
18
|
+
)
|
15
19
|
response = self.class.block.call(request)
|
16
20
|
raise ResponseTypeError.new(response.class) unless response.is_a?(Google::Protobuf::MessageExts)
|
17
21
|
|
@@ -39,18 +39,26 @@ module RailwayIpc
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# rubocop:disable Metrics/AbcSize
|
42
|
+
# rubocop:disable Metrics/MethodLength
|
42
43
|
def process_payload(response)
|
43
44
|
decoded_payload = decode_payload(response)
|
44
45
|
case decoded_payload.type
|
45
46
|
when *registered_handlers
|
46
47
|
@message = get_message_class(decoded_payload).decode(decoded_payload.message)
|
47
|
-
RailwayIpc.logger.info(
|
48
|
+
RailwayIpc.logger.info(
|
49
|
+
'Handling response',
|
50
|
+
feature: 'railway_ipc_consumer',
|
51
|
+
exchange: self.class.exchange_name,
|
52
|
+
queue: self.class.queue_name,
|
53
|
+
protobuf: { type: message.class, data: message }
|
54
|
+
)
|
48
55
|
RailwayIpc::Response.new(message, success: true)
|
49
56
|
else
|
50
57
|
@message = LearnIpc::ErrorMessage.decode(decoded_payload.message)
|
51
58
|
raise RailwayIpc::UnhandledMessageError.new("#{self.class} does not know how to handle #{decoded_payload.type}")
|
52
59
|
end
|
53
60
|
end
|
61
|
+
# rubocop:enable Metrics/MethodLength
|
54
62
|
# rubocop:enable Metrics/AbcSize
|
55
63
|
|
56
64
|
def setup_rabbit_connection
|
@@ -78,10 +86,12 @@ module RailwayIpc
|
|
78
86
|
private
|
79
87
|
|
80
88
|
def log_exception(exception, payload)
|
81
|
-
RailwayIpc.logger.
|
82
|
-
|
89
|
+
RailwayIpc.logger.error(
|
90
|
+
exception.message,
|
91
|
+
feature: 'railway_ipc_consumer',
|
92
|
+
exchange: self.class.exchange_name,
|
93
|
+
queue: self.class.queue_name,
|
83
94
|
error: exception.class,
|
84
|
-
error_message: exception.message,
|
85
95
|
payload: decode_for_error(exception, payload)
|
86
96
|
)
|
87
97
|
end
|
@@ -99,7 +109,12 @@ module RailwayIpc
|
|
99
109
|
end
|
100
110
|
|
101
111
|
def publish_message
|
102
|
-
RailwayIpc.logger.info(
|
112
|
+
RailwayIpc.logger.info(
|
113
|
+
'Sending request',
|
114
|
+
feature: 'railway_ipc_publisher',
|
115
|
+
exchange: self.class.exchange_name,
|
116
|
+
protobuf: { type: request_message.class, data: request_message }
|
117
|
+
)
|
103
118
|
rabbit_connection.publish(RailwayIpc::Rabbitmq::Payload.encode(request_message), routing_key: '')
|
104
119
|
end
|
105
120
|
|
@@ -45,10 +45,12 @@ module RailwayIpc
|
|
45
45
|
raise RailwayIpc::UnhandledMessageError.new("#{self.class} does not know how to handle #{decoded_payload.type}")
|
46
46
|
end
|
47
47
|
rescue StandardError => e
|
48
|
-
RailwayIpc.logger.
|
49
|
-
|
48
|
+
RailwayIpc.logger.error(
|
49
|
+
e.message,
|
50
|
+
feature: 'railway_ipc_consumer',
|
51
|
+
exchange: self.class.exchange_name,
|
52
|
+
queue: self.class.queue_name,
|
50
53
|
error: e.class,
|
51
|
-
error_message: e.message,
|
52
54
|
payload: payload
|
53
55
|
)
|
54
56
|
raise e
|
@@ -56,10 +58,19 @@ module RailwayIpc
|
|
56
58
|
# rubocop:enable Metrics/AbcSize
|
57
59
|
# rubocop:enable Metrics/MethodLength
|
58
60
|
|
61
|
+
# rubocop:disable Metrics/AbcSize
|
62
|
+
# rubocop:disable Metrics/MethodLength
|
59
63
|
def handle_request(payload)
|
60
64
|
response = work(payload)
|
61
65
|
rescue StandardError => e
|
62
|
-
RailwayIpc.logger.error(
|
66
|
+
RailwayIpc.logger.error(
|
67
|
+
'Error responding to message.',
|
68
|
+
exception: e,
|
69
|
+
feature: 'railway_ipc_consumer',
|
70
|
+
exchange: self.class.exchange_name,
|
71
|
+
queue: self.class.queue_name,
|
72
|
+
protobuf: { type: message.class, data: message }
|
73
|
+
)
|
63
74
|
response = self.class.rpc_error_adapter_class.error_message(e, message)
|
64
75
|
ensure
|
65
76
|
if response
|
@@ -68,6 +79,8 @@ module RailwayIpc
|
|
68
79
|
)
|
69
80
|
end
|
70
81
|
end
|
82
|
+
# rubocop:enable Metrics/AbcSize
|
83
|
+
# rubocop:enable Metrics/MethodLength
|
71
84
|
|
72
85
|
private
|
73
86
|
|
data/lib/railway_ipc/version.rb
CHANGED
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:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -263,7 +263,7 @@ licenses:
|
|
263
263
|
- MIT
|
264
264
|
metadata:
|
265
265
|
allowed_push_host: https://rubygems.org/
|
266
|
-
post_install_message:
|
266
|
+
post_install_message:
|
267
267
|
rdoc_options: []
|
268
268
|
require_paths:
|
269
269
|
- lib
|
@@ -278,9 +278,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
278
278
|
- !ruby/object:Gem::Version
|
279
279
|
version: '0'
|
280
280
|
requirements: []
|
281
|
-
rubyforge_project:
|
281
|
+
rubyforge_project:
|
282
282
|
rubygems_version: 2.7.6
|
283
|
-
signing_key:
|
283
|
+
signing_key:
|
284
284
|
specification_version: 4
|
285
285
|
summary: IPC components for Rails
|
286
286
|
test_files: []
|