freddy 2.0.0 → 2.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/.github/workflows/ci.yml +1 -1
- data/.ruby-version +1 -1
- data/README.md +34 -8
- data/freddy.gemspec +2 -1
- data/lib/freddy/adapters/bunny_adapter.rb +1 -1
- data/lib/freddy/encoding.rb +27 -0
- data/lib/freddy/payload.rb +2 -1
- data/lib/freddy/producers/send_and_forget_producer.rb +4 -1
- data/lib/freddy/version.rb +1 -1
- data/lib/freddy.rb +6 -3
- data/spec/freddy/freddy_spec.rb +23 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49a24c63763b6d607d1b5ee60ca4f65211a212999ca5852637c6a567ed6b13d2
|
4
|
+
data.tar.gz: da8e0b5d8818df0b054a66412c61b9b57f5648295b1a81f0e7f79b017cae66ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6323a6cb6f468a10c3395c318d3edb9f9de1de984b6f995786fceb17ca8b7a5b37adcc87649ade6caa7868da7671b09bf01d92365d9c46b9c0fa4b6a0a1e4db5
|
7
|
+
data.tar.gz: c41436342bcb7523f236c4ecec8ba77c0d990fef21aaaff7e3ea9f56071e2797b84faa3266fb176e01d452c1d706e82825c673ac83ac1f4bb4d8ed94f59e5d3a
|
data/.github/workflows/ci.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6
|
data/README.md
CHANGED
@@ -22,39 +22,60 @@ These message queues have been tested and are working with Freddy. Other queues
|
|
22
22
|
### Simple delivery
|
23
23
|
|
24
24
|
#### Send and forget
|
25
|
+
|
25
26
|
Sends a `message` to the given `destination`. If there is no consumer then the
|
26
27
|
message stays in the queue until somebody consumes it.
|
28
|
+
|
27
29
|
```ruby
|
28
|
-
|
30
|
+
freddy.deliver(destination, message)
|
29
31
|
```
|
30
32
|
|
31
33
|
#### Expiring messages
|
34
|
+
|
32
35
|
Sends a `message` to the given `destination`. If nobody consumes the message in
|
33
36
|
`timeout` seconds then the message is discarded. This is useful for showing
|
34
37
|
notifications that must happen in a certain timeframe but where we don't really
|
35
38
|
care if it reached the destination or not.
|
39
|
+
|
36
40
|
```ruby
|
37
41
|
freddy.deliver(destination, message, timeout: 5)
|
38
42
|
```
|
39
43
|
|
44
|
+
#### Compressed messages
|
45
|
+
|
46
|
+
Sends a `message` to the given `destination`. If `compress` is passed as an option parameter, it will compress the
|
47
|
+
payload according to the algorithm provided. Currently the `zlib` algorithm is implemented to compress the payload.
|
48
|
+
The message heading specify the `content-encoding` indicating the compression algorithm used.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
freddy.deliver(destination, message, compress: 'zlib')
|
52
|
+
```
|
53
|
+
|
40
54
|
### Request delivery
|
55
|
+
|
41
56
|
#### Expiring messages
|
57
|
+
|
42
58
|
Sends a `message` to the given `destination`. Has a default timeout of 3 and
|
43
59
|
discards the message from the queue if a response hasn't been returned in that
|
44
60
|
time.
|
61
|
+
|
45
62
|
```ruby
|
46
63
|
response = freddy.deliver_with_response(destination, message)
|
47
64
|
```
|
48
65
|
|
49
66
|
#### Persistant messages
|
67
|
+
|
50
68
|
Sends a `message` to the given `destination`. Keeps the message in the queue if
|
51
69
|
a timeout occurs.
|
70
|
+
|
52
71
|
```ruby
|
53
72
|
response = freddy.deliver_with_response(destination, message, timeout: 4, delete_on_timeout: false)
|
54
73
|
```
|
55
74
|
|
56
75
|
#### Errors
|
76
|
+
|
57
77
|
`deliver_with_response` raises an error if an error is returned. This can be handled by rescuing from `Freddy::InvalidRequestError` and `Freddy::TimeoutError` as:
|
78
|
+
|
58
79
|
```ruby
|
59
80
|
begin
|
60
81
|
response = freddy.deliver_with_response 'Q', {}
|
@@ -66,6 +87,7 @@ rescue Freddy::TimeoutError => e
|
|
66
87
|
```
|
67
88
|
|
68
89
|
## Responding to messages
|
90
|
+
|
69
91
|
```ruby
|
70
92
|
freddy.respond_to destination do |message, msg_handler|
|
71
93
|
# ...
|
@@ -73,8 +95,9 @@ end
|
|
73
95
|
```
|
74
96
|
|
75
97
|
The callback is called with 2 arguments
|
76
|
-
|
77
|
-
|
98
|
+
|
99
|
+
* the parsed message (note that in the message all keys are symbolized)
|
100
|
+
* the `MessageHandler` (described further down)
|
78
101
|
|
79
102
|
## The MessageHandler
|
80
103
|
|
@@ -82,17 +105,20 @@ When responding to messages the MessageHandler is given as the second argument.
|
|
82
105
|
|
83
106
|
The following operations are supported:
|
84
107
|
|
85
|
-
|
108
|
+
* responding with a successful response
|
109
|
+
|
86
110
|
```ruby
|
87
111
|
msg_handler.success(response = nil)
|
88
112
|
```
|
89
113
|
|
90
|
-
|
114
|
+
* responding with an error response
|
115
|
+
|
91
116
|
```ruby
|
92
117
|
msg_handler.error(error: "Couldn't process message")
|
93
118
|
```
|
94
119
|
|
95
120
|
## Tapping into messages
|
121
|
+
|
96
122
|
When it's necessary to receive messages but not consume them, consider tapping.
|
97
123
|
|
98
124
|
```ruby
|
@@ -132,13 +158,15 @@ end
|
|
132
158
|
## The ResponderHandler
|
133
159
|
|
134
160
|
When responding to a message or tapping the ResponderHandler is returned.
|
161
|
+
|
135
162
|
```ruby
|
136
163
|
responder_handler = freddy.respond_to ....
|
137
164
|
```
|
138
165
|
|
139
166
|
The following operations are supported:
|
140
167
|
|
141
|
-
|
168
|
+
* stop responding
|
169
|
+
|
142
170
|
```ruby
|
143
171
|
responder_handler.shutdown
|
144
172
|
```
|
@@ -155,11 +183,9 @@ This is not compatible with `opentelemetry-instrumentation-bunny` library.
|
|
155
183
|
|
156
184
|
*freddy* uses a thread pool to run concurrent responders. The thread pool is unique for each *tap_into* and *respond_to* responder. Thread pool size can be configured by passing the configuration option *max_concurrency*. Its default value is 4. e.g. If your application has 2 *respond_to* responders and 1 *tap_into* responder with *max_concurrency* set to 3 then your application may process up to 9 messages in parallel.
|
157
185
|
|
158
|
-
|
159
186
|
Note that while it is possible to use *deliver_with_response* inside a *respond_to* block,
|
160
187
|
it is not possible to use another *respond_to* block inside a different *respond_to* block.
|
161
188
|
|
162
|
-
|
163
189
|
Note also that other configuration options for freddy users
|
164
190
|
such as pool sizes for DB connections need to match or exceed *max_concurrency*
|
165
191
|
to avoid running out of resources.
|
data/freddy.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.summary = 'API for inter-application messaging supporting acknowledgements and request-response'
|
12
12
|
spec.license = 'MIT'
|
13
13
|
spec.homepage = 'https://github.com/salemove/freddy'
|
14
|
-
spec.required_ruby_version = '>= 2.
|
14
|
+
spec.required_ruby_version = '>= 2.6'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency 'opentelemetry-api', '~> 1.0.0.rc3'
|
27
27
|
spec.add_dependency 'opentelemetry-semantic_conventions', '~> 1.0'
|
28
28
|
spec.add_dependency 'thread', '~> 0.1'
|
29
|
+
spec.add_dependency 'zlib', '~> 1.1'
|
29
30
|
end
|
@@ -67,7 +67,7 @@ class Freddy
|
|
67
67
|
|
68
68
|
def subscribe(manual_ack: false)
|
69
69
|
@queue.subscribe(manual_ack: manual_ack) do |info, properties, payload|
|
70
|
-
parsed_payload = Payload.parse(payload)
|
70
|
+
parsed_payload = Payload.parse(payload, properties[:content_encoding])
|
71
71
|
delivery = Delivery.new(
|
72
72
|
parsed_payload, properties, info.routing_key, info.delivery_tag, info.exchange
|
73
73
|
)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'zlib'
|
4
|
+
|
5
|
+
class Freddy
|
6
|
+
class Encoding
|
7
|
+
ZLIB_CONTENT_ENCODING = 'zlib'
|
8
|
+
|
9
|
+
def self.compress(data, encoding)
|
10
|
+
case encoding
|
11
|
+
when ZLIB_CONTENT_ENCODING
|
12
|
+
::Zlib::Deflate.deflate(data)
|
13
|
+
else
|
14
|
+
data
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.uncompress(data, encoding)
|
19
|
+
case encoding
|
20
|
+
when ZLIB_CONTENT_ENCODING
|
21
|
+
::Zlib::Inflate.inflate(data)
|
22
|
+
else
|
23
|
+
data
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/freddy/payload.rb
CHANGED
@@ -20,7 +20,10 @@ class Freddy
|
|
20
20
|
)
|
21
21
|
Tracing.inject_tracing_information_to_properties!(properties)
|
22
22
|
|
23
|
-
json_payload =
|
23
|
+
json_payload = Freddy::Encoding.compress(
|
24
|
+
Payload.dump(payload),
|
25
|
+
properties[:content_encoding]
|
26
|
+
)
|
24
27
|
|
25
28
|
# Connection adapters handle thread safety for #publish themselves. No
|
26
29
|
# need to lock these.
|
data/lib/freddy/version.rb
CHANGED
data/lib/freddy.rb
CHANGED
@@ -65,7 +65,7 @@ class Freddy
|
|
65
65
|
# Received message as a ruby hash with symbolized keys
|
66
66
|
# @yieldparam [#success, #error] handler
|
67
67
|
# Handler for responding to messages. Use handler#success for successful
|
68
|
-
#
|
68
|
+
# response and handler#error for error response.
|
69
69
|
#
|
70
70
|
# @return [#shutdown]
|
71
71
|
#
|
@@ -99,7 +99,7 @@ class Freddy
|
|
99
99
|
# consuming them. It is useful for general messages that two or more clients
|
100
100
|
# are interested.
|
101
101
|
#
|
102
|
-
# @param [String]
|
102
|
+
# @param [String] pattern_or_patterns
|
103
103
|
# the destination pattern. Use `#` wildcard for matching 0 or more words.
|
104
104
|
# Use `*` to match exactly one word.
|
105
105
|
# @param [Hash] options
|
@@ -152,15 +152,18 @@ class Freddy
|
|
152
152
|
# @option options [Integer] :timeout (0)
|
153
153
|
# discards the message after given seconds if nobody consumes it. Message
|
154
154
|
# won't be discarded if timeout it set to 0 (default).
|
155
|
-
#
|
155
|
+
# @option options [String] :compress (nil)
|
156
|
+
# - 'zlib' - compresses the payload with zlib
|
156
157
|
# @return [void]
|
157
158
|
#
|
158
159
|
# @example
|
159
160
|
# freddy.deliver 'Metrics', user_id: 5, metric: 'signed_in'
|
160
161
|
def deliver(destination, payload, options = {})
|
161
162
|
timeout = options.fetch(:timeout, 0)
|
163
|
+
compression_algorithm = options.fetch(:compress, nil)
|
162
164
|
opts = {}
|
163
165
|
opts[:expiration] = (timeout * 1000).to_i if timeout.positive?
|
166
|
+
opts[:content_encoding] = compression_algorithm if compression_algorithm
|
164
167
|
|
165
168
|
@send_and_forget_producer.produce(destination, payload, opts)
|
166
169
|
end
|
data/spec/freddy/freddy_spec.rb
CHANGED
@@ -49,6 +49,29 @@ describe Freddy do
|
|
49
49
|
expect(processed_after_timeout).to be(true)
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
context 'with compress' do
|
54
|
+
it 'compresses the payload' do
|
55
|
+
expect(Freddy::Encoding).to receive(:compress).with(anything, 'zlib').and_call_original
|
56
|
+
|
57
|
+
freddy.tap_into(destination) { |msg| @tapped_message = msg }
|
58
|
+
freddy.deliver(destination, payload, compress: 'zlib')
|
59
|
+
default_sleep
|
60
|
+
|
61
|
+
wait_for { @tapped_message }
|
62
|
+
expect(@tapped_message).to eq(payload)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'without compress' do
|
67
|
+
it 'does not compress the payload' do
|
68
|
+
freddy.tap_into(destination) { |msg| @tapped_message = msg }
|
69
|
+
deliver
|
70
|
+
|
71
|
+
wait_for { @tapped_message }
|
72
|
+
expect(@tapped_message).to eq(payload)
|
73
|
+
end
|
74
|
+
end
|
52
75
|
end
|
53
76
|
|
54
77
|
context 'when making a synchronized request' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: freddy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Glia TechMovers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: zlib
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.1'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.1'
|
111
125
|
description: Messaging API
|
112
126
|
email:
|
113
127
|
- techmovers@salemove.com
|
@@ -134,6 +148,7 @@ files:
|
|
134
148
|
- lib/freddy/consumers/response_consumer.rb
|
135
149
|
- lib/freddy/consumers/tap_into_consumer.rb
|
136
150
|
- lib/freddy/delivery.rb
|
151
|
+
- lib/freddy/encoding.rb
|
137
152
|
- lib/freddy/error_response.rb
|
138
153
|
- lib/freddy/invalid_request_error.rb
|
139
154
|
- lib/freddy/message_handler.rb
|
@@ -174,7 +189,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
174
189
|
requirements:
|
175
190
|
- - ">="
|
176
191
|
- !ruby/object:Gem::Version
|
177
|
-
version: '2.
|
192
|
+
version: '2.6'
|
178
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
194
|
requirements:
|
180
195
|
- - ">="
|