phobos 1.9.0.pre.beta2 → 2.0.2
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/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: []
|