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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ae99c2d347a67110923b71ffac1af46c706d177b39b82c3adaae4db3f686a1d
4
- data.tar.gz: 557210126d3c4cdff8f0946ee5b6882e3334126c3cb0ae900df823f6e762fdd9
3
+ metadata.gz: 49a24c63763b6d607d1b5ee60ca4f65211a212999ca5852637c6a567ed6b13d2
4
+ data.tar.gz: da8e0b5d8818df0b054a66412c61b9b57f5648295b1a81f0e7f79b017cae66ba
5
5
  SHA512:
6
- metadata.gz: a2ee88b1ec7e51523ae6b3851f07b398b9093d90b193712bce172a09764d2a683d0b5209ced2a4a524248d8ffab36074b8a0b65c662ef9844f319424ccb32e93
7
- data.tar.gz: ea65f5f23e18c768098c1eec7edc299a146f0fc830a0a57b5e9d1f725b5fe6f0b442b017ecd08b80f6242424a6a0958b57c8514cdf015bca07e4d316e88edc56
6
+ metadata.gz: 6323a6cb6f468a10c3395c318d3edb9f9de1de984b6f995786fceb17ca8b7a5b37adcc87649ade6caa7868da7671b09bf01d92365d9c46b9c0fa4b6a0a1e4db5
7
+ data.tar.gz: c41436342bcb7523f236c4ecec8ba77c0d990fef21aaaff7e3ea9f56071e2797b84faa3266fb176e01d452c1d706e82825c673ac83ac1f4bb4d8ed94f59e5d3a
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- ruby-version: ['2.7']
14
+ ruby-version: ['2.6']
15
15
  services:
16
16
  rabbitmq:
17
17
  image: rabbitmq
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7
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
- freddy.deliver(destination, message)
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
- * the parsed message (note that in the message all keys are symbolized)
77
- * the `MessageHandler` (described further down)
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
- * responding with a successful response
108
+ * responding with a successful response
109
+
86
110
  ```ruby
87
111
  msg_handler.success(response = nil)
88
112
  ```
89
113
 
90
- * responding with an error response
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
- * stop responding
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.7'
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
@@ -4,9 +4,10 @@ require 'oj'
4
4
 
5
5
  class Freddy
6
6
  class Payload
7
- def self.parse(payload)
7
+ def self.parse(payload, encoding)
8
8
  return {} if payload == 'null'
9
9
 
10
+ payload = Freddy::Encoding.uncompress(payload, encoding)
10
11
  json_handler.parse(payload)
11
12
  end
12
13
 
@@ -20,7 +20,10 @@ class Freddy
20
20
  )
21
21
  Tracing.inject_tracing_information_to_properties!(properties)
22
22
 
23
- json_payload = Payload.dump(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.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Freddy
4
- VERSION = '2.0.0'
4
+ VERSION = '2.1.0'
5
5
  end
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
- # respone and handler#error for error response.
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] pattern
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
@@ -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.0.0
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-08-17 00:00:00.000000000 Z
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.7'
192
+ version: '2.6'
178
193
  required_rubygems_version: !ruby/object:Gem::Requirement
179
194
  requirements:
180
195
  - - ">="