phobos 1.9.0.pre.beta2 → 2.0.2
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/CHANGELOG.md +22 -0
- data/README.md +61 -10
- data/lib/phobos.rb +1 -1
- data/lib/phobos/actions/process_batch_inline.rb +3 -22
- data/lib/phobos/actions/process_message.rb +2 -37
- data/lib/phobos/deep_struct.rb +1 -1
- data/lib/phobos/executor.rb +1 -1
- data/lib/phobos/listener.rb +5 -5
- data/lib/phobos/producer.rb +14 -48
- data/lib/phobos/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77558904b4cc06321149de51f2b13edeb97704a93128749214ba8454ff997db3
|
4
|
+
data.tar.gz: c88ded6d626d55f56eef5645147f102867097bbc5d32c8c4d3604a24b53f8d57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2c541adb24d1a42be9c99958508ebc143c078c3294df9245094c954de8c5d240be89fdf8a1afcf05ed3ad556290b2a7928b5722b4e1b56a25b2095f9e3d2b69
|
7
|
+
data.tar.gz: 49af36a25cc903e7bcc87e6a7a453dfd32127111ce99896b77bf31f50c1967cc8550b9e3740d47d42febaae44ffa92c7dd5e3959c96a0b637bcc5bb20ddf0c66
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
``
|
7
7
|
## UNRELEASED
|
8
8
|
|
9
|
+
## [2.0.2] - 2021-01-28
|
10
|
+
- Additional fixes for Ruby 3.0
|
11
|
+
|
12
|
+
## [2.0.1] - 2021-01-14
|
13
|
+
- Fix bug with Ruby 3.0 around OpenStruct
|
14
|
+
|
15
|
+
## [2.0.0-beta1] - 2020-05-04
|
16
|
+
|
17
|
+
- Remove deprecated patterns:
|
18
|
+
-- `before_consume` method
|
19
|
+
-- `around_consume` as a class method or without yielding values
|
20
|
+
-- `publish` and `async_publish` with positional arguments
|
21
|
+
|
22
|
+
## [1.9.0] - 2020-03-05
|
23
|
+
- Bumped version to 1.9.0.
|
24
|
+
|
25
|
+
## [1.9.0-beta3] - 2020-02-05
|
26
|
+
|
27
|
+
- Fix bug where deprecation errors would be shown when receiving nil payloads
|
28
|
+
even if `around_consume` was updated to yield them.
|
29
|
+
|
30
|
+
|
9
31
|
## [1.9.0-beta2] - 2020-01-09
|
10
32
|
|
11
33
|
- Allow `around_consume` to yield payload and metadata, and deprecate
|
data/README.md
CHANGED
@@ -21,7 +21,6 @@ With Phobos by your side, all this becomes smooth sailing.
|
|
21
21
|
## Table of Contents
|
22
22
|
|
23
23
|
1. [Installation](#installation)
|
24
|
-
1. [Upgrade Notes](#upgrade-notes)
|
25
24
|
1. [Usage](#usage)
|
26
25
|
1. [Standalone apps](#usage-standalone-apps)
|
27
26
|
1. [Consuming messages from Kafka](#usage-consuming-messages-from-kafka)
|
@@ -32,6 +31,7 @@ With Phobos by your side, all this becomes smooth sailing.
|
|
32
31
|
1. [Plugins](#plugins)
|
33
32
|
1. [Development](#development)
|
34
33
|
1. [Test](#test)
|
34
|
+
1. [Upgrade Notes](#upgrade-notes)
|
35
35
|
|
36
36
|
## <a name="installation"></a> Installation
|
37
37
|
|
@@ -53,10 +53,6 @@ Or install it yourself as:
|
|
53
53
|
$ gem install phobos
|
54
54
|
```
|
55
55
|
|
56
|
-
### <a name="upgrade-notes"></a> Upgrade Notes
|
57
|
-
|
58
|
-
Version 1.8.2 introduced a new `persistent_connections` setting for regular producers. This reduces the number of connections used to produce messages and you should consider setting it to true. This does require a manual shutdown call - please see [Producers with persistent connections](#persistent-connection).
|
59
|
-
|
60
56
|
## <a name="usage"></a> Usage
|
61
57
|
|
62
58
|
Phobos can be used in two ways: as a standalone application or to support Kafka features in your existing project - including Rails apps. It provides a CLI tool to run it.
|
@@ -197,8 +193,6 @@ class MyHandler
|
|
197
193
|
end
|
198
194
|
```
|
199
195
|
|
200
|
-
Note: Previous versions used a `before_consume` method to pre-process the payload. This is still supported, but deprecated. Going forward, `around_consume` should yield the payload and metadata back to the calling code, allowing it to act as a pre-processor, e.g. by decoding Avro messages into Ruby hashes.
|
201
|
-
|
202
196
|
Take a look at the examples folder for some ideas.
|
203
197
|
|
204
198
|
The hander life cycle can be illustrated as:
|
@@ -287,8 +281,6 @@ my = MyProducer.new
|
|
287
281
|
my.producer.publish(topic: 'topic', payload: 'message-payload', key: 'partition and message key', headers: { header_1: 'value 1' })
|
288
282
|
```
|
289
283
|
|
290
|
-
Older versions of Phobos provided a `publish` method that accepted positional arguments. That version is still supported but it's soon to be deprecated in favour of the keyword arguments version.
|
291
|
-
|
292
284
|
It is also possible to publish several messages at once:
|
293
285
|
|
294
286
|
```ruby
|
@@ -604,8 +596,16 @@ Phobos exports a spec helper that can help you test your consumer. The Phobos li
|
|
604
596
|
* `process_message(handler:, payload:, metadata: {}, encoding: nil)` - Invokes your handler with payload and metadata, using a dummy listener (encoding and metadata are optional).
|
605
597
|
|
606
598
|
```ruby
|
607
|
-
|
599
|
+
### spec_helper.rb
|
600
|
+
require 'phobos/test/helper'
|
601
|
+
RSpec.configure do |config|
|
602
|
+
config.include Phobos::Test::Helper
|
603
|
+
config.before(:each) do
|
604
|
+
Phobos.configure(path_to_my_config_file)
|
605
|
+
end
|
606
|
+
end
|
608
607
|
|
608
|
+
### Spec file
|
609
609
|
describe MyConsumer do
|
610
610
|
let(:payload) { 'foo' }
|
611
611
|
let(:metadata) { Hash(foo: 'bar') }
|
@@ -619,6 +619,57 @@ describe MyConsumer do
|
|
619
619
|
end
|
620
620
|
```
|
621
621
|
|
622
|
+
## <a name="upgrade-notes"></a> Upgrade Notes
|
623
|
+
|
624
|
+
Version 2.0 removes deprecated ways of defining producers and consumers:
|
625
|
+
* The `before_consume` method has been removed. You can have this behavior in the first part of an `around_consume` method.
|
626
|
+
* `around_consume` is now only available as an instance method, and it must yield the values to pass to the `consume` method.
|
627
|
+
* `publish` and `async_publish` now only accept keyword arguments, not positional arguments.
|
628
|
+
|
629
|
+
Example pre-2.0:
|
630
|
+
```ruby
|
631
|
+
class MyHandler
|
632
|
+
include Phobos::Handler
|
633
|
+
|
634
|
+
def before_consume(payload, metadata)
|
635
|
+
payload[:id] = 1
|
636
|
+
end
|
637
|
+
|
638
|
+
def self.around_consume(payload, metadata)
|
639
|
+
metadata[:key] = 5
|
640
|
+
yield
|
641
|
+
end
|
642
|
+
end
|
643
|
+
```
|
644
|
+
|
645
|
+
In 2.0:
|
646
|
+
```ruby
|
647
|
+
class MyHandler
|
648
|
+
include Phobos::Handler
|
649
|
+
|
650
|
+
def around_consume(payload, metadata)
|
651
|
+
new_payload = payload.dup
|
652
|
+
new_metadata = metadata.dup
|
653
|
+
new_payload[:id] = 1
|
654
|
+
new_metadata[:key] = 5
|
655
|
+
yield new_payload, new_metadata
|
656
|
+
end
|
657
|
+
end
|
658
|
+
```
|
659
|
+
|
660
|
+
Producer, 1.9:
|
661
|
+
```ruby
|
662
|
+
producer.publish('my-topic', { payload_value: 1}, 5, 3, {header_val: 5})
|
663
|
+
```
|
664
|
+
|
665
|
+
Producer 2.0:
|
666
|
+
```ruby
|
667
|
+
producer.publish(topic: 'my-topic', payload: { payload_value: 1}, key: 5,
|
668
|
+
partition_key: 3, headers: { header_val: 5})
|
669
|
+
```
|
670
|
+
|
671
|
+
Version 1.8.2 introduced a new `persistent_connections` setting for regular producers. This reduces the number of connections used to produce messages and you should consider setting it to true. This does require a manual shutdown call - please see [Producers with persistent connections](#persistent-connection).
|
672
|
+
|
622
673
|
## Contributing
|
623
674
|
|
624
675
|
Bug reports and pull requests are welcome on GitHub at https://github.com/klarna/phobos.
|
data/lib/phobos.rb
CHANGED
@@ -47,32 +47,13 @@ module Phobos
|
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
50
|
-
def preprocess(batch, handler)
|
51
|
-
if handler.respond_to?(:before_consume_batch)
|
52
|
-
Phobos.deprecate('before_consume_batch is deprecated and will be removed in 2.0. \
|
53
|
-
Use around_consume_batch and yield payloads and metadata objects.')
|
54
|
-
handler.before_consume_batch(batch, @metadata)
|
55
|
-
else
|
56
|
-
batch
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
50
|
def process_batch(batch)
|
61
51
|
instrument('listener.process_batch_inline', @metadata) do |_metadata|
|
62
52
|
handler = @listener.handler_class.new
|
63
53
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
handler.consume_batch(around_batch, around_metadata)
|
68
|
-
else
|
69
|
-
Phobos.deprecate('Calling around_consume_batch without yielding payloads \
|
70
|
-
and metadata is deprecated and will be removed in 2.0.')
|
71
|
-
handler.consume_batch(preprocessed_batch, @metadata)
|
72
|
-
end
|
73
|
-
}
|
74
|
-
|
75
|
-
handler.around_consume_batch(preprocessed_batch, @metadata, &consume_block)
|
54
|
+
handler.around_consume_batch(batch, @metadata) do |around_batch, around_metadata|
|
55
|
+
handler.consume_batch(around_batch, around_metadata)
|
56
|
+
end
|
76
57
|
end
|
77
58
|
end
|
78
59
|
end
|
@@ -35,47 +35,12 @@ module Phobos
|
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
def preprocess(payload, handler)
|
39
|
-
if handler.respond_to?(:before_consume)
|
40
|
-
Phobos.deprecate('before_consume is deprecated and will be removed in 2.0. \
|
41
|
-
Use around_consume and yield payload and metadata objects.')
|
42
|
-
begin
|
43
|
-
handler.before_consume(payload, @metadata)
|
44
|
-
rescue ArgumentError
|
45
|
-
handler.before_consume(payload)
|
46
|
-
end
|
47
|
-
else
|
48
|
-
payload
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def consume_block(payload, handler)
|
53
|
-
proc { |around_payload, around_metadata|
|
54
|
-
if around_payload
|
55
|
-
handler.consume(around_payload, around_metadata)
|
56
|
-
else
|
57
|
-
Phobos.deprecate('Calling around_consume without yielding payload and metadata \
|
58
|
-
is deprecated and will be removed in 2.0.')
|
59
|
-
handler.consume(payload, @metadata)
|
60
|
-
end
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
64
38
|
def process_message(payload)
|
65
39
|
instrument('listener.process_message', @metadata) do
|
66
40
|
handler = @listener.handler_class.new
|
67
41
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
if @listener.handler_class.respond_to?(:around_consume)
|
72
|
-
# around_consume class method implementation
|
73
|
-
Phobos.deprecate('around_consume has been moved to instance method, please update '\
|
74
|
-
'your consumer. This will not be backwards compatible in the future.')
|
75
|
-
@listener.handler_class.around_consume(preprocessed_payload, @metadata, &block)
|
76
|
-
else
|
77
|
-
# around_consume instance method implementation
|
78
|
-
handler.around_consume(preprocessed_payload, @metadata, &block)
|
42
|
+
handler.around_consume(payload, @metadata) do |around_payload, around_metadata|
|
43
|
+
handler.consume(around_payload, around_metadata)
|
79
44
|
end
|
80
45
|
end
|
81
46
|
end
|
data/lib/phobos/deep_struct.rb
CHANGED
data/lib/phobos/executor.rb
CHANGED
@@ -13,7 +13,7 @@ module Phobos
|
|
13
13
|
max_concurrency = listener_configs[:max_concurrency] || 1
|
14
14
|
Array.new(max_concurrency).map do
|
15
15
|
configs = listener_configs.select { |k| Constants::LISTENER_OPTS.include?(k) }
|
16
|
-
Phobos::Listener.new(configs.merge(handler: handler_class))
|
16
|
+
Phobos::Listener.new(**configs.merge(handler: handler_class))
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
data/lib/phobos/listener.rb
CHANGED
@@ -93,7 +93,7 @@ module Phobos
|
|
93
93
|
def start_listener
|
94
94
|
instrument('listener.start', listener_metadata) do
|
95
95
|
@consumer = create_kafka_consumer
|
96
|
-
@consumer.subscribe(topic,
|
96
|
+
@consumer.subscribe(topic, **@subscribe_opts)
|
97
97
|
|
98
98
|
# This is done here because the producer client is bound to the current thread and
|
99
99
|
# since "start" blocks a thread might be used to call it
|
@@ -135,7 +135,7 @@ module Phobos
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def consume_each_batch
|
138
|
-
@consumer.each_batch(
|
138
|
+
@consumer.each_batch(**@message_processing_opts) do |batch|
|
139
139
|
batch_processor = Phobos::Actions::ProcessBatch.new(
|
140
140
|
listener: self,
|
141
141
|
batch: batch,
|
@@ -149,7 +149,7 @@ module Phobos
|
|
149
149
|
end
|
150
150
|
|
151
151
|
def consume_each_batch_inline
|
152
|
-
@consumer.each_batch(
|
152
|
+
@consumer.each_batch(**@message_processing_opts) do |batch|
|
153
153
|
batch_processor = Phobos::Actions::ProcessBatchInline.new(
|
154
154
|
listener: self,
|
155
155
|
batch: batch,
|
@@ -163,7 +163,7 @@ module Phobos
|
|
163
163
|
end
|
164
164
|
|
165
165
|
def consume_each_message
|
166
|
-
@consumer.each_message(
|
166
|
+
@consumer.each_message(**@message_processing_opts) do |message|
|
167
167
|
message_processor = Phobos::Actions::ProcessMessage.new(
|
168
168
|
listener: self,
|
169
169
|
message: message,
|
@@ -181,7 +181,7 @@ module Phobos
|
|
181
181
|
Constants::KAFKA_CONSUMER_OPTS.include?(k)
|
182
182
|
end
|
183
183
|
configs.merge!(@kafka_consumer_opts)
|
184
|
-
@kafka_client.consumer({ group_id: group_id }.merge(configs))
|
184
|
+
@kafka_client.consumer(**{ group_id: group_id }.merge(configs))
|
185
185
|
end
|
186
186
|
|
187
187
|
def compact(hash)
|
data/lib/phobos/producer.rb
CHANGED
@@ -11,28 +11,24 @@ module Phobos
|
|
11
11
|
end
|
12
12
|
|
13
13
|
class PublicAPI
|
14
|
-
MissingRequiredArgumentsError = Class.new(StandardError) do
|
15
|
-
def initialize
|
16
|
-
super('You need to provide a topic name and a payload')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
14
|
def initialize(host_obj)
|
21
15
|
@host_obj = host_obj
|
22
16
|
end
|
23
17
|
|
24
|
-
def publish(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
18
|
+
def publish(topic:, payload:, key: nil, partition_key: nil, headers: nil)
|
19
|
+
class_producer.publish(topic: topic,
|
20
|
+
payload: payload,
|
21
|
+
key: key,
|
22
|
+
partition_key: partition_key,
|
23
|
+
headers: headers)
|
29
24
|
end
|
30
25
|
|
31
|
-
def async_publish(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
26
|
+
def async_publish(topic:, payload:, key: nil, partition_key: nil, headers: nil)
|
27
|
+
class_producer.async_publish(topic: topic,
|
28
|
+
payload: payload,
|
29
|
+
key: key,
|
30
|
+
partition_key: partition_key,
|
31
|
+
headers: headers)
|
36
32
|
end
|
37
33
|
|
38
34
|
# @param messages [Array(Hash(:topic, :payload, :key, :headers))]
|
@@ -54,36 +50,6 @@ module Phobos
|
|
54
50
|
def class_producer
|
55
51
|
@host_obj.class.producer
|
56
52
|
end
|
57
|
-
|
58
|
-
# rubocop:disable Metrics/ParameterLists
|
59
|
-
def normalize_arguments(p_topic = nil, p_payload = nil, p_key = nil,
|
60
|
-
p_partition_key = nil, p_headers = {},
|
61
|
-
**kwargs)
|
62
|
-
{}.tap do |args|
|
63
|
-
{
|
64
|
-
topic: p_topic,
|
65
|
-
payload: p_payload,
|
66
|
-
key: p_key,
|
67
|
-
partition_key: p_partition_key,
|
68
|
-
headers: p_headers
|
69
|
-
}.each { |k, v| args[k] = kwargs[k] || v }
|
70
|
-
|
71
|
-
raise MissingRequiredArgumentsError if [:topic, :payload].any? { |k| args[k].nil? }
|
72
|
-
|
73
|
-
kwargs.each do |k, v|
|
74
|
-
next if args.key?(k)
|
75
|
-
|
76
|
-
args[:headers][k] = v
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
# rubocop:enable Metrics/ParameterLists
|
81
|
-
|
82
|
-
def deprecate_positional_args_message(method_name)
|
83
|
-
"The `#{method_name}` method should now receive keyword arguments " \
|
84
|
-
'rather than positional ones. Please update your publishers. This will ' \
|
85
|
-
'not be backwards compatible in the future.'
|
86
|
-
end
|
87
53
|
end
|
88
54
|
|
89
55
|
module ClassMethods
|
@@ -112,7 +78,7 @@ module Phobos
|
|
112
78
|
|
113
79
|
def create_sync_producer
|
114
80
|
client = kafka_client || configure_kafka_client(Phobos.create_kafka_client)
|
115
|
-
sync_producer = client.producer(regular_configs)
|
81
|
+
sync_producer = client.producer(**regular_configs)
|
116
82
|
if Phobos.config.producer_hash[:persistent_connections]
|
117
83
|
producer_store[:sync_producer] = sync_producer
|
118
84
|
end
|
@@ -143,7 +109,7 @@ module Phobos
|
|
143
109
|
|
144
110
|
def create_async_producer
|
145
111
|
client = kafka_client || configure_kafka_client(Phobos.create_kafka_client)
|
146
|
-
async_producer = client.async_producer(async_configs)
|
112
|
+
async_producer = client.async_producer(**async_configs)
|
147
113
|
producer_store[:async_producer] = async_producer
|
148
114
|
end
|
149
115
|
|
data/lib/phobos/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phobos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Túlio Ornelas
|
@@ -12,10 +12,10 @@ authors:
|
|
12
12
|
- Francisco Juan
|
13
13
|
- Tommy Gustafsson
|
14
14
|
- Daniel Orner
|
15
|
-
autorequire:
|
15
|
+
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date:
|
18
|
+
date: 2021-01-28 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bundler
|
@@ -299,7 +299,7 @@ licenses:
|
|
299
299
|
- Apache License Version 2.0
|
300
300
|
metadata:
|
301
301
|
allowed_push_host: https://rubygems.org
|
302
|
-
post_install_message:
|
302
|
+
post_install_message:
|
303
303
|
rdoc_options: []
|
304
304
|
require_paths:
|
305
305
|
- lib
|
@@ -310,12 +310,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
310
310
|
version: '2.3'
|
311
311
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
312
312
|
requirements:
|
313
|
-
- - "
|
313
|
+
- - ">="
|
314
314
|
- !ruby/object:Gem::Version
|
315
|
-
version:
|
315
|
+
version: '0'
|
316
316
|
requirements: []
|
317
|
-
rubygems_version: 3.
|
318
|
-
signing_key:
|
317
|
+
rubygems_version: 3.2.3
|
318
|
+
signing_key:
|
319
319
|
specification_version: 4
|
320
320
|
summary: Simplifying Kafka for ruby apps
|
321
321
|
test_files: []
|