phobos 1.8.1 → 1.8.2.pre.beta1
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/.travis.yml +1 -1
- data/CHANGELOG.md +4 -1
- data/README.md +73 -10
- data/config/phobos.yml.example +5 -1
- data/lib/phobos.rb +2 -0
- data/lib/phobos/actions/process_batch_inline.rb +59 -0
- data/lib/phobos/actions/process_message.rb +5 -57
- data/lib/phobos/batch_handler.rb +27 -0
- data/lib/phobos/batch_message.rb +20 -0
- data/lib/phobos/cli/start.rb +6 -2
- data/lib/phobos/listener.rb +24 -2
- data/lib/phobos/processor.rb +67 -0
- data/lib/phobos/version.rb +1 -1
- data/phobos.gemspec +5 -3
- metadata +13 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6610d5e383b53c4d2f926b4ab10ae33c260215fe2de0520132fa38e6b51089d8
|
|
4
|
+
data.tar.gz: '0791b9c0fc4d4b10f878607bddc1374c359bbe627386375ce48ea3ff6996329d'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc15fe9776e8aff478e3263a9d8d16b9d693baff6259ae62bdbf1e229b7f8c8bfb345fdf7b9603583ca5405642e1424461c2523ef4bdbcd9b85bd80140a03e6d
|
|
7
|
+
data.tar.gz: 782ca0a9838cf38a6ae37c92b33d3ce2f4692438a837aeeefabbea629dd6d5b6c595a6cdc7932e804882d29854784583d356574f8adfaa25613fe093e42cf10c
|
data/.travis.yml
CHANGED
|
@@ -11,7 +11,7 @@ services:
|
|
|
11
11
|
env:
|
|
12
12
|
global:
|
|
13
13
|
- DEFAULT_TIMEOUT=20
|
|
14
|
-
- CC_TEST_REPORTER_ID=
|
|
14
|
+
- CC_TEST_REPORTER_ID=a990fd40ff4421e8b28167232242a1d6c6638f9907fc0b80eb90f82f88fcfd81
|
|
15
15
|
|
|
16
16
|
before_install:
|
|
17
17
|
- env
|
data/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,10 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## [1.8.2-beta1] - 2019-03-13
|
|
8
|
+
|
|
9
|
+
- Added `BatchHandler` to consume messages in batches on the business
|
|
10
|
+
layer.
|
|
8
11
|
|
|
9
12
|
## [1.8.1] - 2018-11-23
|
|
10
13
|
### Added
|
data/README.md
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
|
-
[](https://depfu.com/github/klarna/phobos?project=Bundler)
|
|
7
|
-
[](https://discord.gg/rfMUBVD)
|
|
3
|
+
[](https://travis-ci.com/phobos/phobos)
|
|
4
|
+
[](https://codeclimate.com/github/phobos/phobos/maintainability)
|
|
5
|
+
[](https://codeclimate.com/github/phobos/phobos/test_coverage)
|
|
8
6
|
|
|
9
7
|
# Phobos
|
|
10
8
|
|
|
@@ -214,6 +212,49 @@ The hander life cycle can be illustrated as:
|
|
|
214
212
|
or optionally,
|
|
215
213
|
|
|
216
214
|
`.start` -> `#before_consume` -> `#around_consume` [ `#consume` ] -> `.stop`
|
|
215
|
+
|
|
216
|
+
#### Batch Consumption
|
|
217
|
+
|
|
218
|
+
In addition to the regular handler, Phobos provides a `BatchHandler`. The
|
|
219
|
+
basic ideas are identical, except that instead of being passed a single message
|
|
220
|
+
at a time, the `BatchHandler` is passed a batch of messages. All methods
|
|
221
|
+
follow the same pattern as the regular handler except that they each
|
|
222
|
+
end in `_batch` and are passed an array of `Phobos::BatchMessage`s instead
|
|
223
|
+
of a single payload.
|
|
224
|
+
|
|
225
|
+
To enable handling of batches on the consumer side, you must specify
|
|
226
|
+
a delivery method of `inline_batch` in [phobos.yml](config/phobos.yml.example),
|
|
227
|
+
and your handler must include `BatchHandler`. Using a delivery method of `batch`
|
|
228
|
+
assumes that you are still processing the messages one at a time and should
|
|
229
|
+
use `Handler`.
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
class MyBatchHandler
|
|
233
|
+
includes Phobos::BatchHandler
|
|
234
|
+
|
|
235
|
+
def before_consume_batch(payloads, metadata)
|
|
236
|
+
payloads.each do |p|
|
|
237
|
+
p.payload[:timestamp] = Time.zone.now
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def around_consume_batch(payloads, metadata)
|
|
242
|
+
yield
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def consume_batch(payloads, metadata)
|
|
246
|
+
payloads.each do |p|
|
|
247
|
+
logger.info("Got payload #{p.payload}, #{p.partition}, #{p.offset}, #{p.key}, #{p.payload[:timestamp]}")
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
end
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Note that retry logic will happen on the *batch* level in this case. If you are
|
|
255
|
+
processing messages individually and an error happens in the middle, Phobos's
|
|
256
|
+
retry logic will retry the entire batch. If this is not the behavior you want,
|
|
257
|
+
consider using `batch` instead of `inline_batch`.
|
|
217
258
|
|
|
218
259
|
### <a name="usage-producing-messages-to-kafka"></a> Producing messages to Kafka
|
|
219
260
|
|
|
@@ -436,7 +477,7 @@ end
|
|
|
436
477
|
* partition
|
|
437
478
|
* offset_lag
|
|
438
479
|
* highwater_mark_offset
|
|
439
|
-
* `listener.process_message` is sent after
|
|
480
|
+
* `listener.process_message` is sent after processing a message. It includes the following payload:
|
|
440
481
|
* listener_id
|
|
441
482
|
* group_id
|
|
442
483
|
* topic
|
|
@@ -445,7 +486,16 @@ end
|
|
|
445
486
|
* partition
|
|
446
487
|
* offset
|
|
447
488
|
* retry_count
|
|
448
|
-
* `listener.
|
|
489
|
+
* `listener.process_batch_inline` is sent after processing a batch with `batch_inline` mode. It includes the following payload:
|
|
490
|
+
* listener_id
|
|
491
|
+
* group_id
|
|
492
|
+
* topic
|
|
493
|
+
* handler
|
|
494
|
+
* batch_size
|
|
495
|
+
* partition
|
|
496
|
+
* offset_lag
|
|
497
|
+
* retry_count
|
|
498
|
+
* `listener.retry_handler_error` is sent after waiting for `handler#consume` retry. It includes the following payload:
|
|
449
499
|
* listener_id
|
|
450
500
|
* group_id
|
|
451
501
|
* topic
|
|
@@ -458,22 +508,35 @@ end
|
|
|
458
508
|
* exception_class
|
|
459
509
|
* exception_message
|
|
460
510
|
* backtrace
|
|
511
|
+
* `listener.retry_handler_error_batch` is sent after waiting for `handler#consume_batch` retry. It includes the following payload:
|
|
512
|
+
* listener_id
|
|
513
|
+
* group_id
|
|
514
|
+
* topic
|
|
515
|
+
* handler
|
|
516
|
+
* batch_size
|
|
517
|
+
* partition
|
|
518
|
+
* offset_lag
|
|
519
|
+
* retry_count
|
|
520
|
+
* waiting_time
|
|
521
|
+
* exception_class
|
|
522
|
+
* exception_message
|
|
523
|
+
* backtrace
|
|
461
524
|
* `listener.retry_aborted` is sent after waiting for a retry but the listener was stopped before the retry happened. It includes the following payload:
|
|
462
525
|
* listener_id
|
|
463
526
|
* group_id
|
|
464
527
|
* topic
|
|
465
528
|
* handler
|
|
466
|
-
* `listener.stopping` is sent when the listener receives signal to stop
|
|
529
|
+
* `listener.stopping` is sent when the listener receives signal to stop.
|
|
467
530
|
* listener_id
|
|
468
531
|
* group_id
|
|
469
532
|
* topic
|
|
470
533
|
* handler
|
|
471
|
-
* `listener.stop_handler` is sent after stopping the handler
|
|
534
|
+
* `listener.stop_handler` is sent after stopping the handler.
|
|
472
535
|
* listener_id
|
|
473
536
|
* group_id
|
|
474
537
|
* topic
|
|
475
538
|
* handler
|
|
476
|
-
* `listener.stop` is send after stopping the listener
|
|
539
|
+
* `listener.stop` is send after stopping the listener.
|
|
477
540
|
* listener_id
|
|
478
541
|
* group_id
|
|
479
542
|
* topic
|
data/config/phobos.yml.example
CHANGED
|
@@ -107,7 +107,11 @@ listeners:
|
|
|
107
107
|
# - `batch` will yield batches from Ruby Kafka using `each_batch`, and commit/heartbeat at every consumed batch.
|
|
108
108
|
# Due to implementation in Ruby Kafka, it should be noted that when configuring large batch sizes in combination with taking long time to consume messages,
|
|
109
109
|
# your consumers might get kicked from the Kafka cluster for not sending a heartbeat within the expected interval.
|
|
110
|
-
# Take this into consideration when determining your configuration.
|
|
110
|
+
# Take this into consideration when determining your configuration. You can send heartbeats manually while
|
|
111
|
+
# processing your messages if necessary.
|
|
112
|
+
# - `inline_batch` also uses `each_batch`, but will pass the entire batch to your handler instead
|
|
113
|
+
# of one message at a time. To use this method, you should include Phobos::BatchHandler
|
|
114
|
+
# instead of Phobos::Handler so that you can make use of the `consume_batch` etc. methods.
|
|
111
115
|
# Note: Ultimately commit/heartbeart will depend on the offset commit options and the heartbeat interval.
|
|
112
116
|
delivery: batch
|
|
113
117
|
# Use this if custom backoff is required for a listener
|
data/lib/phobos.rb
CHANGED
|
@@ -22,8 +22,10 @@ require 'phobos/errors'
|
|
|
22
22
|
require 'phobos/listener'
|
|
23
23
|
require 'phobos/actions/process_batch'
|
|
24
24
|
require 'phobos/actions/process_message'
|
|
25
|
+
require 'phobos/actions/process_batch_inline'
|
|
25
26
|
require 'phobos/producer'
|
|
26
27
|
require 'phobos/handler'
|
|
28
|
+
require 'phobos/batch_handler'
|
|
27
29
|
require 'phobos/echo_handler'
|
|
28
30
|
require 'phobos/executor'
|
|
29
31
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'phobos/batch_message'
|
|
4
|
+
require 'phobos/processor'
|
|
5
|
+
|
|
6
|
+
module Phobos
|
|
7
|
+
module Actions
|
|
8
|
+
class ProcessBatchInline
|
|
9
|
+
include Phobos::Processor
|
|
10
|
+
|
|
11
|
+
attr_reader :metadata
|
|
12
|
+
|
|
13
|
+
def initialize(listener:, batch:, metadata:)
|
|
14
|
+
@listener = listener
|
|
15
|
+
@batch = batch
|
|
16
|
+
@listener = listener
|
|
17
|
+
@batch = batch
|
|
18
|
+
@metadata = metadata.merge(
|
|
19
|
+
batch_size: batch.messages.count,
|
|
20
|
+
partition: batch.partition,
|
|
21
|
+
offset_lag: batch.offset_lag,
|
|
22
|
+
retry_count: 0
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def execute
|
|
27
|
+
payloads = @batch.messages.map do |message|
|
|
28
|
+
Phobos::BatchMessage.new(
|
|
29
|
+
key: message.key,
|
|
30
|
+
partition: message.partition,
|
|
31
|
+
offset: message.offset,
|
|
32
|
+
payload: force_encoding(message.value)
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
begin
|
|
37
|
+
process_batch(payloads)
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
handle_error(e, 'listener.retry_handler_error_batch',
|
|
40
|
+
"error processing inline batch, waiting #{backoff_interval}s")
|
|
41
|
+
retry
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def process_batch(payloads)
|
|
48
|
+
instrument('listener.process_batch_inline', @metadata) do |_metadata|
|
|
49
|
+
handler = @listener.handler_class.new
|
|
50
|
+
|
|
51
|
+
preprocessed_payloads = handler.before_consume_batch(payloads, @metadata)
|
|
52
|
+
consume_block = proc { handler.consume_batch(preprocessed_payloads, @metadata) }
|
|
53
|
+
|
|
54
|
+
handler.around_consume_batch(preprocessed_payloads, @metadata, &consume_block)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'phobos/processor'
|
|
4
|
+
|
|
3
5
|
module Phobos
|
|
4
6
|
module Actions
|
|
5
7
|
class ProcessMessage
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
include Phobos::Instrumentation
|
|
8
|
+
include Phobos::Processor
|
|
9
9
|
|
|
10
10
|
attr_reader :metadata
|
|
11
11
|
|
|
@@ -26,29 +26,14 @@ module Phobos
|
|
|
26
26
|
begin
|
|
27
27
|
process_message(payload)
|
|
28
28
|
rescue StandardError => e
|
|
29
|
-
handle_error(e
|
|
29
|
+
handle_error(e, 'listener.retry_handler_error',
|
|
30
|
+
"error processing message, waiting #{backoff_interval}s")
|
|
30
31
|
retry
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
def snooze(interval)
|
|
35
|
-
remaining_interval = interval
|
|
36
|
-
|
|
37
|
-
@listener.send_heartbeat_if_necessary
|
|
38
|
-
|
|
39
|
-
while remaining_interval.positive?
|
|
40
|
-
sleep [remaining_interval, MAX_SLEEP_INTERVAL].min
|
|
41
|
-
remaining_interval -= MAX_SLEEP_INTERVAL
|
|
42
|
-
@listener.send_heartbeat_if_necessary
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
35
|
private
|
|
47
36
|
|
|
48
|
-
def force_encoding(value)
|
|
49
|
-
@listener.encoding ? value&.force_encoding(@listener.encoding) : value
|
|
50
|
-
end
|
|
51
|
-
|
|
52
37
|
def process_message(payload)
|
|
53
38
|
instrument('listener.process_message', @metadata) do
|
|
54
39
|
handler = @listener.handler_class.new
|
|
@@ -75,43 +60,6 @@ module Phobos
|
|
|
75
60
|
'please update your consumer. This will not be backwards compatible in the future.')
|
|
76
61
|
handler.before_consume(payload)
|
|
77
62
|
end
|
|
78
|
-
|
|
79
|
-
def handle_error(error)
|
|
80
|
-
error_hash = {
|
|
81
|
-
waiting_time: backoff_interval,
|
|
82
|
-
exception_class: error.class.name,
|
|
83
|
-
exception_message: error.message,
|
|
84
|
-
backtrace: error.backtrace
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
instrument('listener.retry_handler_error', error_hash.merge(@metadata)) do
|
|
88
|
-
Phobos.logger.error do
|
|
89
|
-
{ message: "error processing message, waiting #{backoff_interval}s" }
|
|
90
|
-
.merge(error_hash)
|
|
91
|
-
.merge(@metadata)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
snooze(backoff_interval)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
increment_retry_count
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def retry_count
|
|
101
|
-
@metadata[:retry_count]
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def increment_retry_count
|
|
105
|
-
@metadata[:retry_count] = retry_count + 1
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def backoff
|
|
109
|
-
@backoff ||= @listener.create_exponential_backoff
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def backoff_interval
|
|
113
|
-
backoff.interval_at(retry_count).round(2)
|
|
114
|
-
end
|
|
115
63
|
end
|
|
116
64
|
end
|
|
117
65
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phobos
|
|
4
|
+
module BatchHandler
|
|
5
|
+
def self.included(base)
|
|
6
|
+
base.extend(ClassMethods)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def before_consume_batch(payloads, _metadata)
|
|
10
|
+
payloads
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def consume_batch(_payloads, _metadata)
|
|
14
|
+
raise NotImplementedError
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def around_consume_batch(_payloads, _metadata)
|
|
18
|
+
yield
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module ClassMethods
|
|
22
|
+
def start(kafka_client); end
|
|
23
|
+
|
|
24
|
+
def stop; end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phobos
|
|
4
|
+
class BatchMessage
|
|
5
|
+
attr_accessor :key, :partition, :offset, :payload
|
|
6
|
+
|
|
7
|
+
def initialize(key:, partition:, offset:, payload:)
|
|
8
|
+
@key = key
|
|
9
|
+
@partition = partition
|
|
10
|
+
@offset = offset
|
|
11
|
+
@payload = payload
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def ==(other)
|
|
15
|
+
[:key, :partition, :offset, :payload].all? do |s|
|
|
16
|
+
public_send(s) == other.public_send(s)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/phobos/cli/start.rb
CHANGED
|
@@ -35,11 +35,15 @@ module Phobos
|
|
|
35
35
|
File.exist?(config_file) || error_exit("Config file not found (#{config_file})")
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
def validate_listeners!
|
|
38
|
+
def validate_listeners! # rubocop:disable Metrics/MethodLength
|
|
39
39
|
Phobos.config.listeners.each do |listener|
|
|
40
40
|
handler = listener.handler
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
begin
|
|
43
|
+
handler.constantize
|
|
44
|
+
rescue NameError
|
|
45
|
+
error_exit("Handler '#{handler}' not defined")
|
|
46
|
+
end
|
|
43
47
|
|
|
44
48
|
delivery = listener.delivery
|
|
45
49
|
if delivery.nil?
|
data/lib/phobos/listener.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Phobos
|
|
|
7
7
|
include Phobos::Log
|
|
8
8
|
|
|
9
9
|
DEFAULT_MAX_BYTES_PER_PARTITION = 1_048_576 # 1 MB
|
|
10
|
-
DELIVERY_OPTS = %w[batch message].freeze
|
|
10
|
+
DELIVERY_OPTS = %w[batch message inline_batch].freeze
|
|
11
11
|
|
|
12
12
|
attr_reader :group_id, :topic, :id
|
|
13
13
|
attr_reader :handler_class, :encoding
|
|
@@ -123,7 +123,15 @@ module Phobos
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def start_consumer_loop
|
|
126
|
-
|
|
126
|
+
# validate batch handling
|
|
127
|
+
case @delivery
|
|
128
|
+
when 'batch'
|
|
129
|
+
consume_each_batch
|
|
130
|
+
when 'inline_batch'
|
|
131
|
+
consume_each_batch_inline
|
|
132
|
+
else
|
|
133
|
+
consume_each_message
|
|
134
|
+
end
|
|
127
135
|
end
|
|
128
136
|
|
|
129
137
|
def consume_each_batch
|
|
@@ -140,6 +148,20 @@ module Phobos
|
|
|
140
148
|
end
|
|
141
149
|
end
|
|
142
150
|
|
|
151
|
+
def consume_each_batch_inline
|
|
152
|
+
@consumer.each_batch(@message_processing_opts) do |batch|
|
|
153
|
+
batch_processor = Phobos::Actions::ProcessBatchInline.new(
|
|
154
|
+
listener: self,
|
|
155
|
+
batch: batch,
|
|
156
|
+
metadata: listener_metadata
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
batch_processor.execute
|
|
160
|
+
log_debug('Committed offset', batch_processor.metadata)
|
|
161
|
+
return nil if should_stop?
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
143
165
|
def consume_each_message
|
|
144
166
|
@consumer.each_message(@message_processing_opts) do |message|
|
|
145
167
|
message_processor = Phobos::Actions::ProcessMessage.new(
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
|
|
5
|
+
module Phobos
|
|
6
|
+
module Processor
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include Phobos::Instrumentation
|
|
9
|
+
|
|
10
|
+
MAX_SLEEP_INTERVAL = 3
|
|
11
|
+
|
|
12
|
+
def snooze(interval)
|
|
13
|
+
remaining_interval = interval
|
|
14
|
+
|
|
15
|
+
@listener.send_heartbeat_if_necessary
|
|
16
|
+
|
|
17
|
+
while remaining_interval.positive?
|
|
18
|
+
sleep [remaining_interval, MAX_SLEEP_INTERVAL].min
|
|
19
|
+
remaining_interval -= MAX_SLEEP_INTERVAL
|
|
20
|
+
@listener.send_heartbeat_if_necessary
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def force_encoding(value)
|
|
27
|
+
@listener.encoding ? value&.force_encoding(@listener.encoding) : value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def handle_error(error, instrumentation_key, error_message)
|
|
31
|
+
error_hash = {
|
|
32
|
+
waiting_time: backoff_interval,
|
|
33
|
+
exception_class: error.class.name,
|
|
34
|
+
exception_message: error.message,
|
|
35
|
+
backtrace: error.backtrace
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
instrument(instrumentation_key, error_hash.merge(@metadata)) do
|
|
39
|
+
Phobos.logger.error do
|
|
40
|
+
{ message: error_message }
|
|
41
|
+
.merge(error_hash)
|
|
42
|
+
.merge(@metadata)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
snooze(backoff_interval)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
increment_retry_count
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def retry_count
|
|
52
|
+
@metadata[:retry_count]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def increment_retry_count
|
|
56
|
+
@metadata[:retry_count] = retry_count + 1
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def backoff
|
|
60
|
+
@backoff ||= @listener.create_exponential_backoff
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def backoff_interval
|
|
64
|
+
backoff.interval_at(retry_count).round(2)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
data/lib/phobos/version.rb
CHANGED
data/phobos.gemspec
CHANGED
|
@@ -14,7 +14,8 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
'Thiago R. Colucci',
|
|
15
15
|
'Martin Svalin',
|
|
16
16
|
'Francisco Juan',
|
|
17
|
-
'Tommy Gustafsson'
|
|
17
|
+
'Tommy Gustafsson',
|
|
18
|
+
'Daniel Orner'
|
|
18
19
|
]
|
|
19
20
|
spec.email = [
|
|
20
21
|
'ornelas.tulio@gmail.com',
|
|
@@ -23,7 +24,8 @@ Gem::Specification.new do |spec|
|
|
|
23
24
|
'ticolucci@gmail.com',
|
|
24
25
|
'martin@lite.nu',
|
|
25
26
|
'francisco.juan@gmail.com',
|
|
26
|
-
'tommydgustafsson@gmail.com'
|
|
27
|
+
'tommydgustafsson@gmail.com',
|
|
28
|
+
'dmorner@gmail.com'
|
|
27
29
|
]
|
|
28
30
|
|
|
29
31
|
spec.summary = 'Simplifying Kafka for ruby apps'
|
|
@@ -53,7 +55,7 @@ Gem::Specification.new do |spec|
|
|
|
53
55
|
spec.add_development_dependency 'pry-byebug'
|
|
54
56
|
spec.add_development_dependency 'rake', '~> 12.3'
|
|
55
57
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
56
|
-
spec.add_development_dependency 'rubocop', '0.
|
|
58
|
+
spec.add_development_dependency 'rubocop', '0.62.0'
|
|
57
59
|
spec.add_development_dependency 'rubocop_rules'
|
|
58
60
|
spec.add_development_dependency 'simplecov'
|
|
59
61
|
spec.add_development_dependency 'timecop'
|
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: 1.8.
|
|
4
|
+
version: 1.8.2.pre.beta1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Túlio Ornelas
|
|
@@ -11,10 +11,11 @@ authors:
|
|
|
11
11
|
- Martin Svalin
|
|
12
12
|
- Francisco Juan
|
|
13
13
|
- Tommy Gustafsson
|
|
14
|
+
- Daniel Orner
|
|
14
15
|
autorequire:
|
|
15
16
|
bindir: bin
|
|
16
17
|
cert_chain: []
|
|
17
|
-
date:
|
|
18
|
+
date: 2019-03-13 00:00:00.000000000 Z
|
|
18
19
|
dependencies:
|
|
19
20
|
- !ruby/object:Gem::Dependency
|
|
20
21
|
name: bundler
|
|
@@ -78,14 +79,14 @@ dependencies:
|
|
|
78
79
|
requirements:
|
|
79
80
|
- - '='
|
|
80
81
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: 0.
|
|
82
|
+
version: 0.62.0
|
|
82
83
|
type: :development
|
|
83
84
|
prerelease: false
|
|
84
85
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
86
|
requirements:
|
|
86
87
|
- - '='
|
|
87
88
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: 0.
|
|
89
|
+
version: 0.62.0
|
|
89
90
|
- !ruby/object:Gem::Dependency
|
|
90
91
|
name: rubocop_rules
|
|
91
92
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -237,6 +238,7 @@ email:
|
|
|
237
238
|
- martin@lite.nu
|
|
238
239
|
- francisco.juan@gmail.com
|
|
239
240
|
- tommydgustafsson@gmail.com
|
|
241
|
+
- dmorner@gmail.com
|
|
240
242
|
executables:
|
|
241
243
|
- phobos
|
|
242
244
|
extensions: []
|
|
@@ -268,7 +270,10 @@ files:
|
|
|
268
270
|
- examples/publishing_messages_without_consumer.rb
|
|
269
271
|
- lib/phobos.rb
|
|
270
272
|
- lib/phobos/actions/process_batch.rb
|
|
273
|
+
- lib/phobos/actions/process_batch_inline.rb
|
|
271
274
|
- lib/phobos/actions/process_message.rb
|
|
275
|
+
- lib/phobos/batch_handler.rb
|
|
276
|
+
- lib/phobos/batch_message.rb
|
|
272
277
|
- lib/phobos/cli.rb
|
|
273
278
|
- lib/phobos/cli/runner.rb
|
|
274
279
|
- lib/phobos/cli/start.rb
|
|
@@ -281,6 +286,7 @@ files:
|
|
|
281
286
|
- lib/phobos/instrumentation.rb
|
|
282
287
|
- lib/phobos/listener.rb
|
|
283
288
|
- lib/phobos/log.rb
|
|
289
|
+
- lib/phobos/processor.rb
|
|
284
290
|
- lib/phobos/producer.rb
|
|
285
291
|
- lib/phobos/test.rb
|
|
286
292
|
- lib/phobos/test/helper.rb
|
|
@@ -304,12 +310,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
304
310
|
version: '2.3'
|
|
305
311
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
306
312
|
requirements:
|
|
307
|
-
- - "
|
|
313
|
+
- - ">"
|
|
308
314
|
- !ruby/object:Gem::Version
|
|
309
|
-
version:
|
|
315
|
+
version: 1.3.1
|
|
310
316
|
requirements: []
|
|
311
|
-
|
|
312
|
-
rubygems_version: 2.7.6
|
|
317
|
+
rubygems_version: 3.0.2
|
|
313
318
|
signing_key:
|
|
314
319
|
specification_version: 4
|
|
315
320
|
summary: Simplifying Kafka for ruby apps
|