mimi-messaging 0.1.9 → 1.1.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/.gitignore +1 -0
- data/.rubocop.yml +66 -0
- data/README.md +68 -3
- data/TODO.md +8 -0
- data/docs/Messaging_Layer_Properties.md +141 -0
- data/docs/Why_HTTP_is_a_bad_choice.md +20 -0
- data/docs/diagrams/Pattern -- Command.drawio +1 -0
- data/docs/diagrams/Pattern -- Event direct.drawio +1 -0
- data/docs/diagrams/Pattern -- Event with Queue.drawio +1 -0
- data/docs/diagrams/Pattern -- Event.drawio +1 -0
- data/docs/diagrams/Pattern -- Query.drawio +1 -0
- data/docs/img/pattern--command.png +0 -0
- data/docs/img/pattern--event-direct.png +0 -0
- data/docs/img/pattern--event-using-queue.png +0 -0
- data/docs/img/pattern--event.png +0 -0
- data/docs/img/pattern--query.png +0 -0
- data/examples/basic_event_listener.rb +35 -0
- data/examples/basic_request_processor.rb +38 -0
- data/examples/using_messaging_low.rb +59 -0
- data/examples/using_pure_adapter.rb +62 -0
- data/lib/mimi/messaging.rb +429 -92
- data/lib/mimi/messaging/adapters.rb +22 -0
- data/lib/mimi/messaging/adapters/base.rb +233 -0
- data/lib/mimi/messaging/adapters/memory.rb +119 -0
- data/lib/mimi/messaging/adapters/test.rb +50 -0
- data/lib/mimi/messaging/errors.rb +24 -12
- data/lib/mimi/messaging/json_serializer.rb +45 -0
- data/lib/mimi/messaging/message.rb +25 -65
- data/lib/mimi/messaging/version.rb +3 -1
- data/mimi-messaging.gemspec +25 -23
- metadata +34 -77
- data/lib/mimi/messaging/connection.rb +0 -181
- data/lib/mimi/messaging/listener.rb +0 -72
- data/lib/mimi/messaging/mock.rb +0 -13
- data/lib/mimi/messaging/mock/connection.rb +0 -153
- data/lib/mimi/messaging/mock/request.rb +0 -18
- data/lib/mimi/messaging/mock/request_processor.rb +0 -92
- data/lib/mimi/messaging/model.rb +0 -27
- data/lib/mimi/messaging/model_provider.rb +0 -100
- data/lib/mimi/messaging/msgpack/msgpack_ext.rb +0 -14
- data/lib/mimi/messaging/msgpack/type_packer.rb +0 -104
- data/lib/mimi/messaging/notification.rb +0 -35
- data/lib/mimi/messaging/provider.rb +0 -48
- data/lib/mimi/messaging/request.rb +0 -56
- data/lib/mimi/messaging/request_processor.rb +0 -216
- data/lib/mimi/messaging/request_processor/context.rb +0 -39
- data/lib/mimi/messaging/request_processor/dsl.rb +0 -121
- data/lib/tasks/console_ext.rake +0 -6
- data/lib/tasks/console_helpers.rb +0 -116
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module Mimi
|
6
|
+
module Messaging
|
7
|
+
#
|
8
|
+
# JSON serializer.
|
9
|
+
#
|
10
|
+
# De/Serializes a message (Hash) from/into a JSON object
|
11
|
+
#
|
12
|
+
module JsonSerializer
|
13
|
+
#
|
14
|
+
# Serialize given message into JSON object
|
15
|
+
#
|
16
|
+
# @param message [Hash]
|
17
|
+
# @return [String]
|
18
|
+
#
|
19
|
+
def self.serialize(message)
|
20
|
+
unless message.is_a?(Hash)
|
21
|
+
raise ArgumentError, "Invalid message passed to #{self}#serialize, Hash is expected"
|
22
|
+
end
|
23
|
+
|
24
|
+
message.to_json
|
25
|
+
rescue StandardError => e
|
26
|
+
raise "#{self} failed to serialize a message: #{e}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Deserializes a JSON into a message
|
30
|
+
#
|
31
|
+
# @param message [String]
|
32
|
+
# @return [Hash]
|
33
|
+
#
|
34
|
+
def self.deserialize(message)
|
35
|
+
unless message.is_a?(String)
|
36
|
+
raise ArgumentError, "Invalid message passed to #{self}#deserialize, String is expected"
|
37
|
+
end
|
38
|
+
|
39
|
+
JSON.parse(message)
|
40
|
+
rescue StandardError => e
|
41
|
+
raise "#{self} failed to deserialize a message: #{e}"
|
42
|
+
end
|
43
|
+
end # module JsonSerializer
|
44
|
+
end # module Messaging
|
45
|
+
end # module Mimi
|
@@ -1,74 +1,34 @@
|
|
1
|
-
|
2
|
-
require 'msgpack'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Mimi
|
5
4
|
module Messaging
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
headers = {
|
21
|
-
method_name: name.to_s,
|
22
|
-
Mimi::Messaging::CONTEXT_ID_KEY => Mimi::Messaging.logger.context_id
|
23
|
-
}
|
24
|
-
_d, _m, response = Mimi::Messaging.get(
|
25
|
-
queue_name, encode(data), opts.deep_merge(headers: headers)
|
26
|
-
)
|
27
|
-
raise Timeout::Error unless response
|
28
|
-
message = new(decode(response))
|
29
|
-
raise RequestError.new(message.error, Message.new(message.params)) if message.error?
|
30
|
-
message
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.post(name, data = {}, opts = {})
|
34
|
-
headers = {
|
35
|
-
method_name: name.to_s,
|
36
|
-
Mimi::Messaging::CONTEXT_ID_KEY => Mimi::Messaging.logger.context_id
|
37
|
-
}
|
38
|
-
Mimi::Messaging.post(
|
39
|
-
queue_name, encode(data), opts.deep_merge(headers: headers)
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.add_method(name, &block)
|
44
|
-
self.class.instance_eval do
|
45
|
-
define_method(name, &block)
|
5
|
+
#
|
6
|
+
# A Message is a Hash and additional headers structure.
|
7
|
+
#
|
8
|
+
class Message < Hash
|
9
|
+
attr_reader :headers
|
10
|
+
|
11
|
+
# Creates a Message out of Hash or another Message.
|
12
|
+
#
|
13
|
+
# @param message_or_hash [Hash,Message]
|
14
|
+
# @param headers [Hash,nil] additional headers to attach to the message
|
15
|
+
#
|
16
|
+
def initialize(message_or_hash, headers = nil)
|
17
|
+
unless message_or_hash.is_a?(Hash) # or a Message
|
18
|
+
raise ArgumentError, "Message or Hash is expected as argument"
|
46
19
|
end
|
47
|
-
end
|
48
20
|
|
49
|
-
|
50
|
-
|
51
|
-
add_method(method_name) do |*params|
|
52
|
-
get(method_name, *params)
|
53
|
-
end
|
54
|
-
add_method("#{method_name}!") do |*params|
|
55
|
-
post(method_name, *params)
|
56
|
-
nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
21
|
+
# copy attributes
|
22
|
+
message_or_hash.each { |k, v| self[k] = v.dup }
|
60
23
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
def to_s
|
70
|
-
to_hash.to_s
|
24
|
+
# copy headers
|
25
|
+
headers ||= {}
|
26
|
+
if message_or_hash.is_a?(Mimi::Messaging::Message)
|
27
|
+
@headers = message_or_hash.headers.merge(headers)
|
28
|
+
else
|
29
|
+
@headers = headers
|
30
|
+
end
|
71
31
|
end
|
72
32
|
end # class Message
|
73
33
|
end # module Messaging
|
74
|
-
end # module Mimi
|
34
|
+
end # module Mimi
|
data/mimi-messaging.gemspec
CHANGED
@@ -1,39 +1,41 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require "mimi/messaging/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = "mimi-messaging"
|
8
9
|
spec.version = Mimi::Messaging::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ["Alex Kukushkin"]
|
11
|
+
spec.email = ["alex@kukushk.in"]
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = "Interservice communication via message bus for microservices"
|
14
|
+
spec.description = "Interservice communication via message bus for microservices"
|
15
|
+
spec.homepage = "https://github.com/kukushkin/mimi-messaging"
|
16
|
+
spec.license = "MIT"
|
16
17
|
|
17
18
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
19
|
# delete this section to allow pushing this gem to any host.
|
19
20
|
if spec.respond_to?(:metadata)
|
20
|
-
spec.metadata[
|
21
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
21
22
|
else
|
22
|
-
raise
|
23
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
# Specify which files should be added to the gem when it is released.
|
27
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
28
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
29
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
30
|
+
end
|
31
|
+
spec.bindir = "exe"
|
27
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
-
spec.require_paths = [
|
33
|
+
spec.require_paths = ["lib"]
|
29
34
|
|
30
|
-
spec.add_dependency
|
31
|
-
spec.add_dependency 'mimi-core', '~> 0.1'
|
32
|
-
spec.add_dependency 'mimi-logger', '~> 0.2', '>= 0.2.3'
|
33
|
-
spec.add_dependency 'msgpack', '~> 1.2'
|
35
|
+
spec.add_dependency "mimi-core", "~> 1.1"
|
34
36
|
|
35
|
-
spec.add_development_dependency
|
36
|
-
spec.add_development_dependency
|
37
|
-
spec.add_development_dependency
|
38
|
-
spec.add_development_dependency
|
37
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
38
|
+
spec.add_development_dependency "pry", "~> 0.12"
|
39
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
40
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
39
41
|
end
|
metadata
CHANGED
@@ -1,105 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mimi-messaging
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Kukushkin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bunny
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '2.9'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2.9'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: mimi-core
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0.1'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: mimi-logger
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0.2'
|
48
|
-
- - ">="
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: 0.2.3
|
51
|
-
type: :runtime
|
52
|
-
prerelease: false
|
53
|
-
version_requirements: !ruby/object:Gem::Requirement
|
54
|
-
requirements:
|
55
|
-
- - "~>"
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: '0.2'
|
58
|
-
- - ">="
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: 0.2.3
|
61
|
-
- !ruby/object:Gem::Dependency
|
62
|
-
name: msgpack
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - "~>"
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: '1.2'
|
19
|
+
version: '1.1'
|
68
20
|
type: :runtime
|
69
21
|
prerelease: false
|
70
22
|
version_requirements: !ruby/object:Gem::Requirement
|
71
23
|
requirements:
|
72
24
|
- - "~>"
|
73
25
|
- !ruby/object:Gem::Version
|
74
|
-
version: '1.
|
26
|
+
version: '1.1'
|
75
27
|
- !ruby/object:Gem::Dependency
|
76
28
|
name: bundler
|
77
29
|
requirement: !ruby/object:Gem::Requirement
|
78
30
|
requirements:
|
79
31
|
- - "~>"
|
80
32
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
33
|
+
version: '2.0'
|
82
34
|
type: :development
|
83
35
|
prerelease: false
|
84
36
|
version_requirements: !ruby/object:Gem::Requirement
|
85
37
|
requirements:
|
86
38
|
- - "~>"
|
87
39
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
40
|
+
version: '2.0'
|
89
41
|
- !ruby/object:Gem::Dependency
|
90
42
|
name: pry
|
91
43
|
requirement: !ruby/object:Gem::Requirement
|
92
44
|
requirements:
|
93
45
|
- - "~>"
|
94
46
|
- !ruby/object:Gem::Version
|
95
|
-
version: '0.
|
47
|
+
version: '0.12'
|
96
48
|
type: :development
|
97
49
|
prerelease: false
|
98
50
|
version_requirements: !ruby/object:Gem::Requirement
|
99
51
|
requirements:
|
100
52
|
- - "~>"
|
101
53
|
- !ruby/object:Gem::Version
|
102
|
-
version: '0.
|
54
|
+
version: '0.12'
|
103
55
|
- !ruby/object:Gem::Dependency
|
104
56
|
name: rake
|
105
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,7 +80,7 @@ dependencies:
|
|
128
80
|
- - "~>"
|
129
81
|
- !ruby/object:Gem::Version
|
130
82
|
version: '3.0'
|
131
|
-
description:
|
83
|
+
description: Interservice communication via message bus for microservices
|
132
84
|
email:
|
133
85
|
- alex@kukushk.in
|
134
86
|
executables: []
|
@@ -137,36 +89,41 @@ extra_rdoc_files: []
|
|
137
89
|
files:
|
138
90
|
- ".gitignore"
|
139
91
|
- ".rspec"
|
92
|
+
- ".rubocop.yml"
|
140
93
|
- ".travis.yml"
|
141
94
|
- CODE_OF_CONDUCT.md
|
142
95
|
- Gemfile
|
143
96
|
- LICENSE.txt
|
144
97
|
- README.md
|
145
98
|
- Rakefile
|
99
|
+
- TODO.md
|
146
100
|
- bin/console
|
147
101
|
- bin/setup
|
102
|
+
- docs/Messaging_Layer_Properties.md
|
103
|
+
- docs/Why_HTTP_is_a_bad_choice.md
|
104
|
+
- docs/diagrams/Pattern -- Command.drawio
|
105
|
+
- docs/diagrams/Pattern -- Event direct.drawio
|
106
|
+
- docs/diagrams/Pattern -- Event with Queue.drawio
|
107
|
+
- docs/diagrams/Pattern -- Event.drawio
|
108
|
+
- docs/diagrams/Pattern -- Query.drawio
|
109
|
+
- docs/img/pattern--command.png
|
110
|
+
- docs/img/pattern--event-direct.png
|
111
|
+
- docs/img/pattern--event-using-queue.png
|
112
|
+
- docs/img/pattern--event.png
|
113
|
+
- docs/img/pattern--query.png
|
114
|
+
- examples/basic_event_listener.rb
|
115
|
+
- examples/basic_request_processor.rb
|
116
|
+
- examples/using_messaging_low.rb
|
117
|
+
- examples/using_pure_adapter.rb
|
148
118
|
- lib/mimi/messaging.rb
|
149
|
-
- lib/mimi/messaging/
|
119
|
+
- lib/mimi/messaging/adapters.rb
|
120
|
+
- lib/mimi/messaging/adapters/base.rb
|
121
|
+
- lib/mimi/messaging/adapters/memory.rb
|
122
|
+
- lib/mimi/messaging/adapters/test.rb
|
150
123
|
- lib/mimi/messaging/errors.rb
|
151
|
-
- lib/mimi/messaging/
|
124
|
+
- lib/mimi/messaging/json_serializer.rb
|
152
125
|
- lib/mimi/messaging/message.rb
|
153
|
-
- lib/mimi/messaging/mock.rb
|
154
|
-
- lib/mimi/messaging/mock/connection.rb
|
155
|
-
- lib/mimi/messaging/mock/request.rb
|
156
|
-
- lib/mimi/messaging/mock/request_processor.rb
|
157
|
-
- lib/mimi/messaging/model.rb
|
158
|
-
- lib/mimi/messaging/model_provider.rb
|
159
|
-
- lib/mimi/messaging/msgpack/msgpack_ext.rb
|
160
|
-
- lib/mimi/messaging/msgpack/type_packer.rb
|
161
|
-
- lib/mimi/messaging/notification.rb
|
162
|
-
- lib/mimi/messaging/provider.rb
|
163
|
-
- lib/mimi/messaging/request.rb
|
164
|
-
- lib/mimi/messaging/request_processor.rb
|
165
|
-
- lib/mimi/messaging/request_processor/context.rb
|
166
|
-
- lib/mimi/messaging/request_processor/dsl.rb
|
167
126
|
- lib/mimi/messaging/version.rb
|
168
|
-
- lib/tasks/console_ext.rake
|
169
|
-
- lib/tasks/console_helpers.rb
|
170
127
|
- mimi-messaging.gemspec
|
171
128
|
homepage: https://github.com/kukushkin/mimi-messaging
|
172
129
|
licenses:
|
@@ -189,8 +146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
146
|
version: '0'
|
190
147
|
requirements: []
|
191
148
|
rubyforge_project:
|
192
|
-
rubygems_version: 2.6.14.
|
149
|
+
rubygems_version: 2.6.14.4
|
193
150
|
signing_key:
|
194
151
|
specification_version: 4
|
195
|
-
summary:
|
152
|
+
summary: Interservice communication via message bus for microservices
|
196
153
|
test_files: []
|
@@ -1,181 +0,0 @@
|
|
1
|
-
require 'bunny'
|
2
|
-
|
3
|
-
module Mimi
|
4
|
-
module Messaging
|
5
|
-
class Connection
|
6
|
-
attr_reader :queue_prefix
|
7
|
-
|
8
|
-
# Creates a Connection with given connection params
|
9
|
-
#
|
10
|
-
# @param params [Hash] Connection params as accepted by Bunny
|
11
|
-
# @param params[:queue_prefix] [String] (optional) Use this connection for all communication
|
12
|
-
# related to queues, having names starting with given
|
13
|
-
# prefix
|
14
|
-
#
|
15
|
-
def initialize(params = {})
|
16
|
-
@queue_prefix = params[:queue_prefix]
|
17
|
-
@channel_pool = {}
|
18
|
-
bunny_params = {
|
19
|
-
host: params[:mq_host],
|
20
|
-
port: params[:mq_port],
|
21
|
-
username: params[:mq_username],
|
22
|
-
password: params[:mq_password],
|
23
|
-
vhost: params[:mq_vhost]
|
24
|
-
}
|
25
|
-
@connection = Bunny.new(bunny_params)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Starts the connection, opening actual connection to RabbitMQ
|
29
|
-
#
|
30
|
-
def start
|
31
|
-
@connection.start
|
32
|
-
end
|
33
|
-
|
34
|
-
# Stops the connection
|
35
|
-
#
|
36
|
-
def stop
|
37
|
-
@connection.close
|
38
|
-
@channel_pool = {}
|
39
|
-
end
|
40
|
-
|
41
|
-
def started?
|
42
|
-
@connection.status == :open
|
43
|
-
end
|
44
|
-
|
45
|
-
def channel
|
46
|
-
raise ConnectionError unless started?
|
47
|
-
@channel_pool[Thread.current.object_id] ||= create_channel
|
48
|
-
end
|
49
|
-
|
50
|
-
def create_channel(opts = {})
|
51
|
-
Channel.new(@connection, opts)
|
52
|
-
end
|
53
|
-
|
54
|
-
def reply_queue
|
55
|
-
raise ConnectionError unless started?
|
56
|
-
channel.reply_queue
|
57
|
-
end
|
58
|
-
|
59
|
-
def post(queue_name, raw_message, params = {})
|
60
|
-
channel.post(queue_name, raw_message, params)
|
61
|
-
end
|
62
|
-
|
63
|
-
def get(queue_name, raw_message, params = {})
|
64
|
-
channel.get(queue_name, raw_message, params)
|
65
|
-
end
|
66
|
-
|
67
|
-
def broadcast(queue_name, raw_message, params = {})
|
68
|
-
channel.broadcast(queue_name, raw_message, params)
|
69
|
-
end
|
70
|
-
|
71
|
-
class Channel
|
72
|
-
attr_reader :options, :connection
|
73
|
-
|
74
|
-
DEFAULT_OPTIONS = {
|
75
|
-
concurrency: 1
|
76
|
-
}
|
77
|
-
DEFAULT_GET_TIMEOUT = 60 # seconds
|
78
|
-
|
79
|
-
def initialize(connection, opts = {})
|
80
|
-
@connection = connection
|
81
|
-
@options = DEFAULT_OPTIONS.merge(opts)
|
82
|
-
@channel = @connection.create_channel(nil, options[:concurrency])
|
83
|
-
@mutex = Mutex.new
|
84
|
-
end
|
85
|
-
|
86
|
-
def create_queue(name, opts = {})
|
87
|
-
@channel.queue(name, opts)
|
88
|
-
end
|
89
|
-
|
90
|
-
def reply_queue
|
91
|
-
@reply_queue ||= create_queue('', exclusive: true)
|
92
|
-
end
|
93
|
-
|
94
|
-
def ack(tag)
|
95
|
-
@channel.ack(tag)
|
96
|
-
end
|
97
|
-
|
98
|
-
def fanout(name)
|
99
|
-
@channel.fanout(name)
|
100
|
-
end
|
101
|
-
|
102
|
-
def active?
|
103
|
-
@channel && @channel.active
|
104
|
-
end
|
105
|
-
|
106
|
-
# Sends a raw RabbitMQ message to a given direct exchange
|
107
|
-
#
|
108
|
-
# @param queue_name [String] Queue name to send the message to
|
109
|
-
# @param raw_message [String]
|
110
|
-
# @param params [Hash] Message params (metadata)
|
111
|
-
#
|
112
|
-
def post(queue_name, raw_message, params = {})
|
113
|
-
x = @channel.default_exchange
|
114
|
-
params = { routing_key: queue_name }.merge(params.dup)
|
115
|
-
publish(x, raw_message, params)
|
116
|
-
end
|
117
|
-
|
118
|
-
# Sends a raw RabbitMQ message to a given direct exchange and listens for response
|
119
|
-
#
|
120
|
-
# @param queue_name [String] Queue name to send the message to
|
121
|
-
# @param raw_message [String]
|
122
|
-
# @param params [Hash] Message params (metadata)
|
123
|
-
#
|
124
|
-
# @param params[:timeout] [Integer] (optional) Timeout in seconds
|
125
|
-
#
|
126
|
-
# @return [nil,Array]
|
127
|
-
#
|
128
|
-
def get(queue_name, raw_message, params = {})
|
129
|
-
correlation_id = Time.now.utc.to_f.to_s
|
130
|
-
params = params.dup.merge(
|
131
|
-
reply_to: reply_queue.name,
|
132
|
-
correlation_id: correlation_id
|
133
|
-
)
|
134
|
-
post(queue_name, raw_message, params)
|
135
|
-
response = nil
|
136
|
-
begin
|
137
|
-
Timeout.timeout(params[:timeout] || DEFAULT_GET_TIMEOUT) do
|
138
|
-
loop do
|
139
|
-
d, m, p = reply_queue.pop
|
140
|
-
next if d && m.correlation_id != correlation_id
|
141
|
-
response = [d, m, p] if d
|
142
|
-
break if response
|
143
|
-
sleep 0.001 # s
|
144
|
-
end
|
145
|
-
end
|
146
|
-
rescue Timeout::Error
|
147
|
-
# respond with nil
|
148
|
-
end
|
149
|
-
response
|
150
|
-
end
|
151
|
-
|
152
|
-
# Sends a raw RabbitMQ message to a given fanout exchange
|
153
|
-
#
|
154
|
-
# @param fanout_name [String] Fanout exchange name to send the message to
|
155
|
-
# @param raw_message [String]
|
156
|
-
# @param params [Hash] Message params (metadata)
|
157
|
-
#
|
158
|
-
def broadcast(fanout_name, raw_message, params = {})
|
159
|
-
x = @channel.fanout(fanout_name)
|
160
|
-
publish(x, raw_message, params)
|
161
|
-
end
|
162
|
-
|
163
|
-
private
|
164
|
-
|
165
|
-
def publish(exchange, raw_message, params = {})
|
166
|
-
# HACK: Connection-level mutex reduces throughoutput, hopefully improves stability (ku)
|
167
|
-
@mutex.synchronize do
|
168
|
-
# TODO: may be make publishing an atomic operation using a separate thread? (ku)
|
169
|
-
exchange.publish(raw_message, params)
|
170
|
-
end
|
171
|
-
rescue StandardError => e
|
172
|
-
# Raising fatal error:
|
173
|
-
unless Thread.main == Thread.current
|
174
|
-
Thread.main.raise ConnectionError, "failed to publish message in a child thread: #{e}"
|
175
|
-
end
|
176
|
-
raise ConnectionError, "failed to publish message: #{e}"
|
177
|
-
end
|
178
|
-
end # class Channel
|
179
|
-
end # class Connection
|
180
|
-
end # module Messaging
|
181
|
-
end # module Mimi
|