railway-ipc 2.2.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +49 -3
- data/lib/railway_ipc.rb +5 -0
- data/lib/railway_ipc/connection_manager.rb +52 -0
- data/lib/railway_ipc/consumer/consumer.rb +14 -3
- data/lib/railway_ipc/incoming_message.rb +16 -12
- data/lib/railway_ipc/message_decoders.rb +34 -0
- data/lib/railway_ipc/message_encoders.rb +23 -0
- data/lib/railway_ipc/models/published_message.rb +7 -8
- data/lib/railway_ipc/outgoing_message.rb +38 -0
- data/lib/railway_ipc/publisher.rb +14 -66
- data/lib/railway_ipc/version.rb +1 -1
- data/railway_ipc.gemspec +1 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d520b8d56b0ef067e1a02228e1982541de4abce283d83ccdf7d168ee3cbb52f
|
4
|
+
data.tar.gz: b4b3eb85928de3ee6dd2a86f3e93e89567b37996af3e2476baa074de3cf5dc47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1190af3d7a5e4bb953007b9c2f31668ba0e6048b9958af0927c9be59d01ce4f3f8139c205354e2b931bc08c831c8f9a6e40e94bc40410b9329dc709bc212c5a4
|
7
|
+
data.tar.gz: 24f7eba242e5879ec229b80e2d4b24af920bcfa4bfef2a5b0b12b1c8c9e408011b2bd7f0954fcfd27de64d4c7429b185dc9945073a78e1192868ea414a2cfc02
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.5
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
5
|
|
7
6
|
## [Unreleased]
|
8
7
|
### Added
|
@@ -10,6 +9,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
10
9
|
### Removed
|
11
10
|
### Fixed
|
12
11
|
|
12
|
+
## [5.0.0] - 2021-02-17
|
13
|
+
### Added
|
14
|
+
* Message encoders. Messages can now be encoded using either binary protobufs (the default) or JSON protobufs.
|
15
|
+
* `RailwayIpc::OutgoingMessage` abstraction that encapsulates everything about a message to be published.
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
* `Publisher#publish` now takes an optional `format` parameter that specifies how the message should be encoded. It is added to the message header when the message is published. The default format is `binary_protobuf`.
|
19
|
+
* (Breaking change) `Publisher#publish` now returns an `OutgoingMessage` instead of a `Bunny::Exchange`.
|
20
|
+
* Refactor `PublishedMessage#store_message` to take an `OutgoingMessage`.
|
21
|
+
|
22
|
+
### Removed
|
23
|
+
* (Breaking change) Remove deprecated `SingletonPublisher`
|
24
|
+
|
25
|
+
## [4.0.1] - 2021-01-12
|
26
|
+
### Fixed
|
27
|
+
* Fixed `undefined method fetch for Bunny::MessageProperties` error. `Bunny::MessageProperties` isn't really a Hash, it wraps one (and doesn't provide a `#fetch` method).
|
28
|
+
|
29
|
+
## [4.0.0] - 2021-01-11
|
30
|
+
### Added
|
31
|
+
* JSON decoder for consumers that can handle JSON encoded Protobufs. Note that the publishers do not (yet) have the option of encoding the messages as JSON.
|
32
|
+
|
33
|
+
### Changed
|
34
|
+
* (Breaking Change) Rename `Consumer#work` to `Consumer#work_with_params`. This was necessary so that we can support specifying different message encodings via metadata in the future. If the message encoding cannot be determined from the message metadata fall back to a default decoder (binary protobufs).
|
35
|
+
|
36
|
+
### Fixed
|
37
|
+
* `./bin/console` script was broken because Pry wasn't a dependency; added Pry as a development dependency only.
|
38
|
+
|
39
|
+
## [3.0.0] - 2020-12-07
|
40
|
+
### Changed
|
41
|
+
* Consumers _will no longer crash_ when an exception is raised. Instead, consumers will move the message that caused the exception to a single dead-letter exchange called 'ipc:errors'. Railway will configure the dead-letter exchange automatically.
|
42
|
+
|
43
|
+
## [2.2.2] - 2020-11-20
|
44
|
+
### Fixed
|
45
|
+
* Fixed Publisher class channel leak. Channels were being created on each instantiation of a Publisher instead of being re-used.
|
46
|
+
|
47
|
+
## [2.2.1] - 2020-10-20
|
48
|
+
### Added
|
49
|
+
* Logging to indicate when options passed via `listen_to`/`from_queue` are overriding the defaults.
|
50
|
+
|
13
51
|
## [2.2.0] - 2020-10-20
|
14
52
|
### Added
|
15
53
|
* The ability to configure workers to handle different workloads via `rake railway_ipc::consumers:spawn`
|
@@ -74,7 +112,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
74
112
|
### Added
|
75
113
|
- Correlation ID and message UUID are auto generated for messages for IDs are not passed in [#23](https://github.com/learn-co/railway_ipc_gem/pull/23)
|
76
114
|
|
77
|
-
[Unreleased]: https://github.com/learn-co/railway_ipc_gem/compare/
|
115
|
+
[Unreleased]: https://github.com/learn-co/railway_ipc_gem/compare/v5.0.0...HEAD
|
116
|
+
[5.0.0]: https://github.com/learn-co/railway_ipc_gem/compare/v4.0.1...v5.0.0
|
117
|
+
[4.0.1]: https://github.com/learn-co/railway_ipc_gem/compare/v4.0.0...v4.0.1
|
118
|
+
[4.0.0]: https://github.com/learn-co/railway_ipc_gem/compare/v3.0.0...v4.0.0
|
119
|
+
[3.0.0]: https://github.com/learn-co/railway_ipc_gem/compare/v2.2.2...v3.0.0
|
120
|
+
[2.2.2]: https://github.com/learn-co/railway_ipc_gem/compare/v2.2.1...v2.2.2
|
121
|
+
[2.2.1]: https://github.com/learn-co/railway_ipc_gem/compare/v2.2.0...v2.2.1
|
122
|
+
[2.2.0]: https://github.com/learn-co/railway_ipc_gem/compare/v2.1.0...v2.2.0
|
123
|
+
[2.1.0]: https://github.com/learn-co/railway_ipc_gem/compare/v2.0.3...v2.1.0
|
78
124
|
[2.0.3]: https://github.com/learn-co/railway_ipc_gem/compare/v2.0.2...v2.0.3
|
79
125
|
[2.0.2]: https://github.com/learn-co/railway_ipc_gem/compare/v2.0.1...v2.0.2
|
80
126
|
[2.0.1]: https://github.com/learn-co/railway_ipc_gem/compare/v2.0.0...v2.0.1
|
data/lib/railway_ipc.rb
CHANGED
@@ -5,6 +5,7 @@ require 'sneakers'
|
|
5
5
|
require 'sneakers/spawner'
|
6
6
|
require 'bunny'
|
7
7
|
require 'active_record'
|
8
|
+
require 'singleton'
|
8
9
|
require 'railway_ipc/logger'
|
9
10
|
require 'railway_ipc/unhandled_message_error'
|
10
11
|
require 'railway_ipc/response'
|
@@ -13,7 +14,11 @@ require 'railway_ipc/unknown_message.pb'
|
|
13
14
|
require 'railway_ipc/rabbitmq/adapter'
|
14
15
|
require 'railway_ipc/handler'
|
15
16
|
require 'railway_ipc/handler_store'
|
17
|
+
require 'railway_ipc/message_encoders'
|
18
|
+
require 'railway_ipc/message_decoders'
|
16
19
|
require 'railway_ipc/incoming_message'
|
20
|
+
require 'railway_ipc/outgoing_message'
|
21
|
+
require 'railway_ipc/connection_manager'
|
17
22
|
require 'railway_ipc/publisher'
|
18
23
|
require 'railway_ipc/responder'
|
19
24
|
require 'railway_ipc/rpc/rpc'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module RailwayIpc
|
6
|
+
# RabbitMQ connection manager. Ensures there is a single RabbitMQ
|
7
|
+
# connection and channel per thread, which prevents channel leaks.
|
8
|
+
#
|
9
|
+
class ConnectionManager
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
establish_connection
|
14
|
+
end
|
15
|
+
|
16
|
+
def establish_connection
|
17
|
+
@connection = Bunny.new(
|
18
|
+
host: settings[:host],
|
19
|
+
user: settings[:user],
|
20
|
+
pass: settings[:pass],
|
21
|
+
port: settings[:port],
|
22
|
+
vhost: settings[:vhost] || '/',
|
23
|
+
logger: RailwayIpc.logger
|
24
|
+
)
|
25
|
+
@connection.start
|
26
|
+
@channel = @connection.create_channel
|
27
|
+
|
28
|
+
@connection
|
29
|
+
end
|
30
|
+
|
31
|
+
def channel
|
32
|
+
return @channel if connected?
|
33
|
+
|
34
|
+
establish_connection
|
35
|
+
@channel
|
36
|
+
end
|
37
|
+
|
38
|
+
def connected?
|
39
|
+
@connection&.connected? && @channel&.open?
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def amqp_url
|
45
|
+
@amqp_url ||= ENV.fetch('RAILWAY_RABBITMQ_CONNECTION_URL', 'amqp://guest:guest@localhost:5672')
|
46
|
+
end
|
47
|
+
|
48
|
+
def settings
|
49
|
+
@settings ||= AMQ::Settings.parse_amqp_url(amqp_url)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -14,6 +14,7 @@ module RailwayIpc
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
17
18
|
def self.listen_to(queue:, exchange:, options: {})
|
18
19
|
unless options.empty?
|
19
20
|
RailwayIpc.logger.info(
|
@@ -27,9 +28,13 @@ module RailwayIpc
|
|
27
28
|
exchange: exchange,
|
28
29
|
durable: true,
|
29
30
|
exchange_type: :fanout,
|
31
|
+
arguments: {
|
32
|
+
'x-dead-letter-exchange' => 'ipc:errors'
|
33
|
+
},
|
30
34
|
connection: RailwayIpc.bunny_connection
|
31
35
|
}.merge(options)
|
32
36
|
end
|
37
|
+
# rubocop:enable Metrics/MethodLength
|
33
38
|
|
34
39
|
def self.handle(message_type, with:)
|
35
40
|
handlers.register(message: message_type, handler: with)
|
@@ -51,8 +56,14 @@ module RailwayIpc
|
|
51
56
|
queue.opts[:exchange]
|
52
57
|
end
|
53
58
|
|
54
|
-
|
55
|
-
|
59
|
+
# REFACTOR: Long term we should think about not leaking Sneakers
|
60
|
+
# methods as part of Railway's public API since clients can (and do)
|
61
|
+
# override them. -BN
|
62
|
+
def work_with_params(payload, _delivery_info, metadata)
|
63
|
+
headers = metadata.headers || {}
|
64
|
+
message_format = headers.fetch('message_format', 'binary_protobuf')
|
65
|
+
|
66
|
+
message = RailwayIpc::IncomingMessage.new(payload, message_format: message_format)
|
56
67
|
RailwayIpc::ProcessIncomingMessage.call(self, message)
|
57
68
|
ack!
|
58
69
|
rescue StandardError => e
|
@@ -64,7 +75,7 @@ module RailwayIpc
|
|
64
75
|
error: e.class,
|
65
76
|
payload: payload
|
66
77
|
)
|
67
|
-
|
78
|
+
reject!
|
68
79
|
end
|
69
80
|
|
70
81
|
def get_handler(type)
|
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
module RailwayIpc
|
4
4
|
class IncomingMessage
|
5
|
-
attr_reader :type, :payload, :parsed_payload, :errors
|
5
|
+
attr_reader :type, :message_format, :payload, :parsed_payload, :errors
|
6
6
|
|
7
|
-
def initialize(payload)
|
7
|
+
def initialize(payload, message_format: nil)
|
8
|
+
@message_format = message_format
|
8
9
|
@parsed_payload = JSON.parse(payload)
|
9
10
|
@type = parsed_payload['type']
|
10
11
|
@payload = payload
|
@@ -32,20 +33,23 @@ module RailwayIpc
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def decoded
|
35
|
-
@decoded ||=
|
36
|
-
|
37
|
-
protobuf_msg = Base64.decode64(parsed_payload['encoded_message'])
|
38
|
-
decoder = Kernel.const_get(type)
|
39
|
-
decoder.decode(protobuf_msg)
|
40
|
-
rescue Google::Protobuf::ParseError => e
|
41
|
-
raise RailwayIpc::IncomingMessage::ParserError.new(e)
|
42
|
-
rescue NameError
|
43
|
-
RailwayIpc::Messages::Unknown.decode(protobuf_msg)
|
44
|
-
end
|
36
|
+
@decoded ||= \
|
37
|
+
get_decoder(message_format).call(type, parsed_payload['encoded_message'])
|
45
38
|
end
|
46
39
|
|
47
40
|
def stringify_errors
|
48
41
|
errors.values.join(', ')
|
49
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
DEFAULT_DECODER = RailwayIpc::MessageDecoders::ProtobufBinaryDecoder
|
47
|
+
|
48
|
+
def get_decoder(name)
|
49
|
+
{
|
50
|
+
'binary_protobuf' => RailwayIpc::MessageDecoders::ProtobufBinaryDecoder,
|
51
|
+
'json_protobuf' => RailwayIpc::MessageDecoders::ProtobufJsonDecoder
|
52
|
+
}.fetch(name, DEFAULT_DECODER)
|
53
|
+
end
|
50
54
|
end
|
51
55
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailwayIpc
|
4
|
+
module MessageDecoders
|
5
|
+
ProtobufBinaryDecoder = lambda do |type, encoded_message|
|
6
|
+
protobuf_msg = Base64.decode64(encoded_message)
|
7
|
+
protobuf_klass = Kernel.const_get(type)
|
8
|
+
protobuf_klass.decode(protobuf_msg)
|
9
|
+
rescue Google::Protobuf::ParseError => e
|
10
|
+
raise RailwayIpc::IncomingMessage::ParserError.new(e)
|
11
|
+
rescue NameError
|
12
|
+
RailwayIpc::Messages::Unknown.decode(protobuf_msg)
|
13
|
+
end
|
14
|
+
|
15
|
+
ProtobufJsonDecoder = lambda do |type, message_hash|
|
16
|
+
protobuf_klass = Kernel.const_get(type)
|
17
|
+
protobuf_klass.new(message_hash)
|
18
|
+
rescue ArgumentError => e
|
19
|
+
raise RailwayIpc::IncomingMessage::ParserError.new(e)
|
20
|
+
rescue NameError
|
21
|
+
# NOTE: I didn't realize this until I made this ProtobufJsonDecoder, but
|
22
|
+
# the ProtobufBinaryDecoder will ignore any unknown keys -- which is
|
23
|
+
# probably not what we want. I'm coding this the same way as the binary
|
24
|
+
# protobuf version for consistency, but we should re-think how we want to
|
25
|
+
# handle this situation. -BN
|
26
|
+
RailwayIpc::Messages::Unknown.new(
|
27
|
+
user_uuid: message_hash.fetch(:user_uuid, ''),
|
28
|
+
correlation_id: message_hash.fetch(:correlation_id, ''),
|
29
|
+
uuid: message_hash.fetch(:uuid, ''),
|
30
|
+
context: message_hash.fetch(:context, {})
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailwayIpc
|
4
|
+
module MessageEncoders
|
5
|
+
ProtobufBinaryEncoder = lambda do |message|
|
6
|
+
{
|
7
|
+
type: message.type,
|
8
|
+
encoded_message: Base64.encode64(message.proto.class.encode(message.proto))
|
9
|
+
}.to_json
|
10
|
+
rescue NoMethodError
|
11
|
+
raise RailwayIpc::InvalidProtobuf.new("Message #{message} is not a valid protobuf")
|
12
|
+
end
|
13
|
+
|
14
|
+
ProtobufJsonEncoder = lambda do |message|
|
15
|
+
{
|
16
|
+
type: message.type,
|
17
|
+
encoded_message: message.proto.to_h
|
18
|
+
}.to_json
|
19
|
+
rescue NoMethodError
|
20
|
+
raise RailwayIpc::InvalidProtobuf.new("Message #{message} is not a valid protobuf")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -7,16 +7,15 @@ module RailwayIpc
|
|
7
7
|
|
8
8
|
validates :uuid, :status, presence: true
|
9
9
|
|
10
|
-
def self.store_message(
|
11
|
-
encoded_message = RailwayIpc::Rabbitmq::Payload.encode(message)
|
10
|
+
def self.store_message(outgoing_message)
|
12
11
|
create!(
|
13
|
-
uuid:
|
14
|
-
message_type:
|
15
|
-
user_uuid:
|
16
|
-
correlation_id:
|
17
|
-
encoded_message:
|
12
|
+
uuid: outgoing_message.uuid,
|
13
|
+
message_type: outgoing_message.type,
|
14
|
+
user_uuid: outgoing_message.user_uuid,
|
15
|
+
correlation_id: outgoing_message.correlation_id,
|
16
|
+
encoded_message: outgoing_message.encoded,
|
18
17
|
status: 'sent',
|
19
|
-
exchange:
|
18
|
+
exchange: outgoing_message.exchange
|
20
19
|
)
|
21
20
|
end
|
22
21
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailwayIpc
|
4
|
+
class OutgoingMessage
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
attr_reader :proto, :exchange, :format
|
8
|
+
|
9
|
+
def_delegators :@proto, :uuid, :user_uuid, :correlation_id
|
10
|
+
|
11
|
+
def initialize(proto, exchange, format=nil)
|
12
|
+
proto.uuid = SecureRandom.uuid if proto.uuid.blank?
|
13
|
+
proto.correlation_id = SecureRandom.uuid if proto.correlation_id.blank?
|
14
|
+
@proto = proto
|
15
|
+
@exchange = exchange
|
16
|
+
@format = format
|
17
|
+
end
|
18
|
+
|
19
|
+
def type
|
20
|
+
proto.class.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def encoded
|
24
|
+
@encoded ||= encoder.call(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
DEFAULT_ENCODER = RailwayIpc::MessageEncoders::ProtobufBinaryEncoder
|
30
|
+
|
31
|
+
def encoder
|
32
|
+
{
|
33
|
+
'binary_protobuf' => RailwayIpc::MessageEncoders::ProtobufBinaryEncoder,
|
34
|
+
'json_protobuf' => RailwayIpc::MessageEncoders::ProtobufJsonEncoder
|
35
|
+
}.fetch(format, DEFAULT_ENCODER)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,81 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'singleton'
|
4
|
-
|
5
|
-
module RailwayIpc
|
6
|
-
class SingletonPublisher < Sneakers::Publisher
|
7
|
-
include ::Singleton
|
8
|
-
|
9
|
-
def self.exchange(exchange)
|
10
|
-
@exchange_name = exchange
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.exchange_name
|
14
|
-
raise 'Subclass must set the exchange' unless @exchange_name
|
15
|
-
|
16
|
-
@exchange_name
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
super(exchange: self.class.exchange_name, exchange_type: :fanout)
|
21
|
-
end
|
22
|
-
|
23
|
-
def publish(message, published_message_store=RailwayIpc::PublishedMessage)
|
24
|
-
RailwayIpc.logger.warn('DEPRECATED: Use new PublisherInstance class', log_message_options)
|
25
|
-
ensure_message_uuid(message)
|
26
|
-
ensure_correlation_id(message)
|
27
|
-
RailwayIpc.logger.info('Publishing message', log_message_options(message))
|
28
|
-
result = super(RailwayIpc::Rabbitmq::Payload.encode(message))
|
29
|
-
published_message_store.store_message(self.class.exchange_name, message)
|
30
|
-
result
|
31
|
-
rescue RailwayIpc::InvalidProtobuf => e
|
32
|
-
RailwayIpc.logger.error('Invalid protobuf', log_message_options(message))
|
33
|
-
raise e
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def ensure_message_uuid(message)
|
39
|
-
message.uuid = SecureRandom.uuid if message.uuid.blank?
|
40
|
-
message
|
41
|
-
end
|
42
|
-
|
43
|
-
def ensure_correlation_id(message)
|
44
|
-
message.correlation_id = SecureRandom.uuid if message.correlation_id.blank?
|
45
|
-
message
|
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
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
3
|
module RailwayIpc
|
56
|
-
class Publisher
|
4
|
+
class Publisher
|
57
5
|
attr_reader :exchange_name, :message_store
|
58
6
|
|
59
7
|
def initialize(opts={})
|
60
8
|
@exchange_name = opts.fetch(:exchange_name)
|
61
9
|
@message_store = opts.fetch(:message_store, RailwayIpc::PublishedMessage)
|
62
|
-
connection = opts.fetch(:connection, nil)
|
63
|
-
options = {
|
64
|
-
exchange: exchange_name,
|
65
|
-
connection: connection,
|
66
|
-
exchange_type: :fanout
|
67
|
-
}.compact
|
68
|
-
super(options)
|
69
10
|
end
|
70
11
|
|
71
12
|
# rubocop:disable Metrics/AbcSize
|
72
|
-
def publish(message)
|
73
|
-
|
74
|
-
|
13
|
+
def publish(message, format='binary_protobuf')
|
14
|
+
outgoing_message = OutgoingMessage.new(message, exchange_name, format)
|
15
|
+
stored_message = message_store.store_message(outgoing_message)
|
75
16
|
RailwayIpc.logger.info('Publishing message', log_message_options(message))
|
76
|
-
|
77
|
-
|
78
|
-
super(RailwayIpc::Rabbitmq::Payload.encode(message))
|
17
|
+
exchange.publish(outgoing_message.encoded, headers: { message_format: format })
|
18
|
+
outgoing_message
|
79
19
|
rescue RailwayIpc::InvalidProtobuf => e
|
80
20
|
RailwayIpc.logger.error('Invalid protobuf', log_message_options(message))
|
81
21
|
raise e
|
@@ -88,8 +28,16 @@ module RailwayIpc
|
|
88
28
|
end
|
89
29
|
# rubocop:enable Metrics/AbcSize
|
90
30
|
|
31
|
+
def exchange
|
32
|
+
@exchange ||= channel.exchange(exchange_name, type: :fanout, durable: true, auto_delete: false, arguments: {})
|
33
|
+
end
|
34
|
+
|
91
35
|
private
|
92
36
|
|
37
|
+
def channel
|
38
|
+
RailwayIpc::ConnectionManager.instance.channel
|
39
|
+
end
|
40
|
+
|
93
41
|
def log_message_options(message)
|
94
42
|
{
|
95
43
|
feature: 'railway_ipc_publisher',
|
data/lib/railway_ipc/version.rb
CHANGED
data/railway_ipc.gemspec
CHANGED
@@ -48,6 +48,7 @@ Gem::Specification.new do |spec|
|
|
48
48
|
spec.add_development_dependency 'database_cleaner', '~> 1.7'
|
49
49
|
spec.add_development_dependency 'listen', '~> 3.0.5'
|
50
50
|
spec.add_development_dependency 'pg', '~> 0.18'
|
51
|
+
spec.add_development_dependency 'pry', '~> 0.13'
|
51
52
|
spec.add_development_dependency 'rails', '~> 5.0.7'
|
52
53
|
spec.add_development_dependency 'rspec-rails'
|
53
54
|
spec.add_development_dependency 'shoulda-matchers', '~> 4.2'
|
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: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -164,6 +164,20 @@ dependencies:
|
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0.18'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: pry
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0.13'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0.13'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: rails
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -213,6 +227,7 @@ extensions: []
|
|
213
227
|
extra_rdoc_files: []
|
214
228
|
files:
|
215
229
|
- ".gitignore"
|
230
|
+
- ".ruby-version"
|
216
231
|
- CHANGELOG.md
|
217
232
|
- CODE_OF_CONDUCT.md
|
218
233
|
- Gemfile
|
@@ -225,6 +240,7 @@ files:
|
|
225
240
|
- bin/setup
|
226
241
|
- lib/railway_ipc.rb
|
227
242
|
- lib/railway_ipc/Rakefile
|
243
|
+
- lib/railway_ipc/connection_manager.rb
|
228
244
|
- lib/railway_ipc/consumer/consumer.rb
|
229
245
|
- lib/railway_ipc/consumer/process_incoming_message.rb
|
230
246
|
- lib/railway_ipc/errors.rb
|
@@ -232,8 +248,11 @@ files:
|
|
232
248
|
- lib/railway_ipc/handler_store.rb
|
233
249
|
- lib/railway_ipc/incoming_message.rb
|
234
250
|
- lib/railway_ipc/logger.rb
|
251
|
+
- lib/railway_ipc/message_decoders.rb
|
252
|
+
- lib/railway_ipc/message_encoders.rb
|
235
253
|
- lib/railway_ipc/models/consumed_message.rb
|
236
254
|
- lib/railway_ipc/models/published_message.rb
|
255
|
+
- lib/railway_ipc/outgoing_message.rb
|
237
256
|
- lib/railway_ipc/publisher.rb
|
238
257
|
- lib/railway_ipc/rabbitmq/adapter.rb
|
239
258
|
- lib/railway_ipc/rabbitmq/payload.rb
|