waterdrop 1.3.1 → 2.0.0.rc1
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.diffend.yml +3 -0
- data/.github/workflows/ci.yml +53 -0
- data/.gitignore +4 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +27 -4
- data/Gemfile +9 -0
- data/Gemfile.lock +54 -37
- data/LICENSE +165 -0
- data/README.md +192 -53
- data/certs/mensfeld.pem +21 -21
- data/config/errors.yml +3 -16
- data/docker-compose.yml +17 -0
- data/lib/water_drop.rb +5 -23
- data/lib/water_drop/config.rb +41 -136
- data/lib/water_drop/contracts.rb +0 -2
- data/lib/water_drop/contracts/config.rb +8 -121
- data/lib/water_drop/contracts/message.rb +41 -0
- data/lib/water_drop/errors.rb +30 -5
- data/lib/water_drop/instrumentation.rb +7 -0
- data/lib/water_drop/instrumentation/monitor.rb +16 -23
- data/lib/water_drop/instrumentation/stdout_listener.rb +113 -32
- data/lib/water_drop/producer.rb +142 -0
- data/lib/water_drop/producer/async.rb +51 -0
- data/lib/water_drop/producer/buffer.rb +113 -0
- data/lib/water_drop/producer/builder.rb +63 -0
- data/lib/water_drop/producer/dummy_client.rb +32 -0
- data/lib/water_drop/producer/statistics_decorator.rb +71 -0
- data/lib/water_drop/producer/status.rb +52 -0
- data/lib/water_drop/producer/sync.rb +65 -0
- data/lib/water_drop/version.rb +1 -1
- data/log/{.keep → .gitkeep} +0 -0
- data/waterdrop.gemspec +4 -4
- metadata +52 -45
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -35
- data/MIT-LICENCE +0 -18
- data/lib/water_drop/async_producer.rb +0 -26
- data/lib/water_drop/base_producer.rb +0 -57
- data/lib/water_drop/config_applier.rb +0 -52
- data/lib/water_drop/contracts/message_options.rb +0 -19
- data/lib/water_drop/sync_producer.rb +0 -24
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaterDrop
|
4
|
+
class Producer
|
5
|
+
# Producer lifecycle status object representation
|
6
|
+
class Status
|
7
|
+
# States in which the producer can be
|
8
|
+
LIFECYCLE = %i[
|
9
|
+
initial
|
10
|
+
configured
|
11
|
+
connected
|
12
|
+
closing
|
13
|
+
closed
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
private_constant :LIFECYCLE
|
17
|
+
|
18
|
+
# Creates a new instance of status with the initial state
|
19
|
+
# @return [Status]
|
20
|
+
def initialize
|
21
|
+
@current = LIFECYCLE.first
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Boolean] true if producer is in a active state. Active means, that we can start
|
25
|
+
# sending messages. Actives states are connected (connection established) or configured,
|
26
|
+
# which means, that producer is configured, but connection with Kafka is
|
27
|
+
# not yet established.
|
28
|
+
def active?
|
29
|
+
connected? || configured?
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [String] current status as a string
|
33
|
+
def to_s
|
34
|
+
@current.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
LIFECYCLE.each do |state|
|
38
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
39
|
+
# @return [Boolean] true if current status is as we want, otherwise false
|
40
|
+
def #{state}?
|
41
|
+
@current == :#{state}
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets a given state as current
|
45
|
+
def #{state}!
|
46
|
+
@current = :#{state}
|
47
|
+
end
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaterDrop
|
4
|
+
class Producer
|
5
|
+
# Component for synchronous producer operations
|
6
|
+
module Sync
|
7
|
+
# Produces a message to Kafka and waits for it to be delivered
|
8
|
+
#
|
9
|
+
# @param message [Hash] hash that complies with the {Contracts::Message} contract
|
10
|
+
#
|
11
|
+
# @return [Rdkafka::Producer::DeliveryReport] delivery report
|
12
|
+
#
|
13
|
+
# @raise [Rdkafka::RdkafkaError] When adding the message to rdkafka's queue failed
|
14
|
+
# @raise [Rdkafka::Producer::WaitTimeoutError] When the timeout has been reached and the
|
15
|
+
# handle is still pending
|
16
|
+
# @raise [Errors::MessageInvalidError] When provided message details are invalid and the
|
17
|
+
# message could not be sent to Kafka
|
18
|
+
def produce_sync(message)
|
19
|
+
ensure_active!
|
20
|
+
validate_message!(message)
|
21
|
+
|
22
|
+
@monitor.instrument(
|
23
|
+
'message.produced_sync',
|
24
|
+
producer: self,
|
25
|
+
message: message
|
26
|
+
) do
|
27
|
+
client
|
28
|
+
.produce(**message)
|
29
|
+
.wait(
|
30
|
+
max_wait_timeout: @config.max_wait_timeout,
|
31
|
+
wait_timeout: @config.wait_timeout
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Produces many messages to Kafka and waits for them to be delivered
|
37
|
+
#
|
38
|
+
# @param messages [Array<Hash>] array with messages that comply with the
|
39
|
+
# {Contracts::Message} contract
|
40
|
+
#
|
41
|
+
# @return [Array<Rdkafka::Producer::DeliveryReport>] delivery reports
|
42
|
+
#
|
43
|
+
# @raise [Rdkafka::RdkafkaError] When adding the messages to rdkafka's queue failed
|
44
|
+
# @raise [Rdkafka::Producer::WaitTimeoutError] When the timeout has been reached and the
|
45
|
+
# some handles are still pending
|
46
|
+
# @raise [Errors::MessageInvalidError] When any of the provided messages details are invalid
|
47
|
+
# and the message could not be sent to Kafka
|
48
|
+
def produce_many_sync(messages)
|
49
|
+
ensure_active!
|
50
|
+
messages.each { |message| validate_message!(message) }
|
51
|
+
|
52
|
+
@monitor.instrument('messages.produced_sync', producer: self, messages: messages) do
|
53
|
+
messages
|
54
|
+
.map { |message| client.produce(**message) }
|
55
|
+
.map! do |handler|
|
56
|
+
handler.wait(
|
57
|
+
max_wait_timeout: @config.max_wait_timeout,
|
58
|
+
wait_timeout: @config.wait_timeout
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/water_drop/version.rb
CHANGED
data/log/{.keep → .gitkeep}
RENAMED
File without changes
|
data/waterdrop.gemspec
CHANGED
@@ -14,13 +14,13 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = 'https://github.com/karafka/waterdrop'
|
15
15
|
spec.summary = 'Kafka messaging made easy!'
|
16
16
|
spec.description = spec.summary
|
17
|
-
spec.license = '
|
17
|
+
spec.license = 'LGPL-3.0'
|
18
18
|
|
19
|
-
spec.add_dependency '
|
19
|
+
spec.add_dependency 'concurrent-ruby', '>= 1.1'
|
20
20
|
spec.add_dependency 'dry-configurable', '~> 0.8'
|
21
21
|
spec.add_dependency 'dry-monitor', '~> 0.3'
|
22
|
-
spec.add_dependency 'dry-validation', '~> 1.
|
23
|
-
spec.add_dependency '
|
22
|
+
spec.add_dependency 'dry-validation', '~> 1.3'
|
23
|
+
spec.add_dependency 'rdkafka', '>= 0.6.0'
|
24
24
|
spec.add_dependency 'zeitwerk', '~> 2.1'
|
25
25
|
|
26
26
|
spec.required_ruby_version = '>= 2.5.0'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: waterdrop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciej Mensfeld
|
@@ -11,45 +11,45 @@ cert_chain:
|
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIEODCCAqCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhtYWNp
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
14
|
+
ZWovREM9bWVuc2ZlbGQvREM9cGwwHhcNMjAwODExMDkxNTM3WhcNMjEwODExMDkx
|
15
|
+
NTM3WjAjMSEwHwYDVQQDDBhtYWNpZWovREM9bWVuc2ZlbGQvREM9cGwwggGiMA0G
|
16
|
+
CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDCpXsCgmINb6lHBXXBdyrgsBPSxC4/
|
17
|
+
2H+weJ6L9CruTiv2+2/ZkQGtnLcDgrD14rdLIHK7t0o3EKYlDT5GhD/XUVhI15JE
|
18
|
+
N7IqnPUgexe1fbZArwQ51afxz2AmPQN2BkB2oeQHXxnSWUGMhvcEZpfbxCCJH26w
|
19
|
+
hS0Ccsma8yxA6hSlGVhFVDuCr7c2L1di6cK2CtIDpfDaWqnVNJEwBYHIxrCoWK5g
|
20
|
+
sIGekVt/admS9gRhIMaIBg+Mshth5/DEyWO2QjteTodItlxfTctrfmiAl8X8T5JP
|
21
|
+
VXeLp5SSOJ5JXE80nShMJp3RFnGw5fqjX/ffjtISYh78/By4xF3a25HdWH9+qO2Z
|
22
|
+
tx0wSGc9/4gqNM0APQnjN/4YXrGZ4IeSjtE+OrrX07l0TiyikzSLFOkZCAp8oBJi
|
23
|
+
Fhlosz8xQDJf7mhNxOaZziqASzp/hJTU/tuDKl5+ql2icnMv5iV/i6SlmvU29QNg
|
24
|
+
LCV71pUv0pWzN+OZbHZKWepGhEQ3cG9MwvkCAwEAAaN3MHUwCQYDVR0TBAIwADAL
|
25
|
+
BgNVHQ8EBAMCBLAwHQYDVR0OBBYEFImGed2AXS070ohfRidiCEhXEUN+MB0GA1Ud
|
26
26
|
EQQWMBSBEm1hY2llakBtZW5zZmVsZC5wbDAdBgNVHRIEFjAUgRJtYWNpZWpAbWVu
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
c2ZlbGQucGwwDQYJKoZIhvcNAQELBQADggGBAKiHpwoENVrMi94V1zD4o8/6G3AU
|
28
|
+
gWz4udkPYHTZLUy3dLznc/sNjdkJFWT3E6NKYq7c60EpJ0m0vAEg5+F5pmNOsvD3
|
29
|
+
2pXLj9kisEeYhR516HwXAvtngboUcb75skqvBCU++4Pu7BRAPjO1/ihLSBexbwSS
|
30
|
+
fF+J5OWNuyHHCQp+kGPLtXJe2yUYyvSWDj3I2//Vk0VhNOIlaCS1+5/P3ZJThOtm
|
31
|
+
zJUBI7h3HgovwRpcnmk2mXTmU4Zx/bCzX8EA6VY0khEvnmiq7S6eBF0H9qH8KyQ6
|
32
|
+
EkVLpvmUDFcf/uNaBQdazEMB5jYtwoA8gQlANETNGPi51KlkukhKgaIEDMkBDJOx
|
33
|
+
65N7DzmkcyY0/GwjIVIxmRhcrCt1YeCUElmfFx0iida1/YRm6sB2AXqScc1+ECRi
|
34
|
+
2DND//YJUikn1zwbz1kT70XmHd97B4Eytpln7K+M1u2g1pHVEPW4owD/ammXNpUy
|
35
|
+
nt70FcDD4yxJQ+0YNiHd0N8IcVBM1TMIVctMNQ==
|
36
36
|
-----END CERTIFICATE-----
|
37
|
-
date:
|
37
|
+
date: 2020-09-05 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
|
-
name:
|
40
|
+
name: concurrent-ruby
|
41
41
|
requirement: !ruby/object:Gem::Requirement
|
42
42
|
requirements:
|
43
|
-
- - "
|
43
|
+
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
45
|
+
version: '1.1'
|
46
46
|
type: :runtime
|
47
47
|
prerelease: false
|
48
48
|
version_requirements: !ruby/object:Gem::Requirement
|
49
49
|
requirements:
|
50
|
-
- - "
|
50
|
+
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '1.1'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: dry-configurable
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,28 +84,28 @@ dependencies:
|
|
84
84
|
requirements:
|
85
85
|
- - "~>"
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: '1.
|
87
|
+
version: '1.3'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
90
|
version_requirements: !ruby/object:Gem::Requirement
|
91
91
|
requirements:
|
92
92
|
- - "~>"
|
93
93
|
- !ruby/object:Gem::Version
|
94
|
-
version: '1.
|
94
|
+
version: '1.3'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
|
-
name:
|
96
|
+
name: rdkafka
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
99
|
- - ">="
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: 0.
|
101
|
+
version: 0.6.0
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - ">="
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version: 0.
|
108
|
+
version: 0.6.0
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: zeitwerk
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,38 +128,45 @@ extensions: []
|
|
128
128
|
extra_rdoc_files: []
|
129
129
|
files:
|
130
130
|
- ".coditsu/ci.yml"
|
131
|
+
- ".diffend.yml"
|
131
132
|
- ".github/FUNDING.yml"
|
133
|
+
- ".github/workflows/ci.yml"
|
132
134
|
- ".gitignore"
|
133
135
|
- ".rspec"
|
134
136
|
- ".ruby-gemset"
|
135
137
|
- ".ruby-version"
|
136
|
-
- ".travis.yml"
|
137
138
|
- CHANGELOG.md
|
138
139
|
- Gemfile
|
139
140
|
- Gemfile.lock
|
140
|
-
-
|
141
|
+
- LICENSE
|
141
142
|
- README.md
|
142
143
|
- certs/mensfeld.pem
|
143
144
|
- config/errors.yml
|
145
|
+
- docker-compose.yml
|
144
146
|
- lib/water_drop.rb
|
145
|
-
- lib/water_drop/async_producer.rb
|
146
|
-
- lib/water_drop/base_producer.rb
|
147
147
|
- lib/water_drop/config.rb
|
148
|
-
- lib/water_drop/config_applier.rb
|
149
148
|
- lib/water_drop/contracts.rb
|
150
149
|
- lib/water_drop/contracts/config.rb
|
151
|
-
- lib/water_drop/contracts/
|
150
|
+
- lib/water_drop/contracts/message.rb
|
152
151
|
- lib/water_drop/errors.rb
|
152
|
+
- lib/water_drop/instrumentation.rb
|
153
153
|
- lib/water_drop/instrumentation/monitor.rb
|
154
154
|
- lib/water_drop/instrumentation/stdout_listener.rb
|
155
|
-
- lib/water_drop/
|
155
|
+
- lib/water_drop/producer.rb
|
156
|
+
- lib/water_drop/producer/async.rb
|
157
|
+
- lib/water_drop/producer/buffer.rb
|
158
|
+
- lib/water_drop/producer/builder.rb
|
159
|
+
- lib/water_drop/producer/dummy_client.rb
|
160
|
+
- lib/water_drop/producer/statistics_decorator.rb
|
161
|
+
- lib/water_drop/producer/status.rb
|
162
|
+
- lib/water_drop/producer/sync.rb
|
156
163
|
- lib/water_drop/version.rb
|
157
164
|
- lib/waterdrop.rb
|
158
|
-
- log/.
|
165
|
+
- log/.gitkeep
|
159
166
|
- waterdrop.gemspec
|
160
167
|
homepage: https://github.com/karafka/waterdrop
|
161
168
|
licenses:
|
162
|
-
-
|
169
|
+
- LGPL-3.0
|
163
170
|
metadata: {}
|
164
171
|
post_install_message:
|
165
172
|
rdoc_options: []
|
@@ -172,11 +179,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
179
|
version: 2.5.0
|
173
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
181
|
requirements:
|
175
|
-
- - "
|
182
|
+
- - ">"
|
176
183
|
- !ruby/object:Gem::Version
|
177
|
-
version:
|
184
|
+
version: 1.3.1
|
178
185
|
requirements: []
|
179
|
-
rubygems_version: 3.
|
186
|
+
rubygems_version: 3.1.4
|
180
187
|
signing_key:
|
181
188
|
specification_version: 4
|
182
189
|
summary: Kafka messaging made easy!
|
metadata.gz.sig
CHANGED
Binary file
|
data/.travis.yml
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
services:
|
2
|
-
- docker
|
3
|
-
|
4
|
-
dist: trusty
|
5
|
-
cache: bundler
|
6
|
-
|
7
|
-
git:
|
8
|
-
depth: false
|
9
|
-
|
10
|
-
test: &test
|
11
|
-
stage: Test
|
12
|
-
language: ruby
|
13
|
-
before_install:
|
14
|
-
- gem install bundler
|
15
|
-
- gem update --system
|
16
|
-
script: bundle exec rspec
|
17
|
-
|
18
|
-
jobs:
|
19
|
-
include:
|
20
|
-
- <<: *test
|
21
|
-
rvm: 2.6.5
|
22
|
-
- <<: *test
|
23
|
-
rvm: 2.5.5
|
24
|
-
|
25
|
-
- stage: coditsu
|
26
|
-
language: ruby
|
27
|
-
rvm: 2.6.5
|
28
|
-
before_install:
|
29
|
-
- gem update --system
|
30
|
-
- gem install bundler
|
31
|
-
script: \curl -sSL https://api.coditsu.io/run/ci | bash
|
32
|
-
|
33
|
-
stages:
|
34
|
-
- coditsu
|
35
|
-
- test
|
data/MIT-LICENCE
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
2
|
-
a copy of this software and associated documentation files (the
|
3
|
-
"Software"), to deal in the Software without restriction, including
|
4
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
5
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
6
|
-
permit persons to whom the Software is furnished to do so, subject to
|
7
|
-
the following conditions:
|
8
|
-
|
9
|
-
The above copyright notice and this permission notice shall be
|
10
|
-
included in all copies or substantial portions of the Software.
|
11
|
-
|
12
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
13
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
14
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
16
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
17
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
18
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# WaterDrop library
|
4
|
-
module WaterDrop
|
5
|
-
# Async producer for messages
|
6
|
-
class AsyncProducer < BaseProducer
|
7
|
-
# Performs message delivery using deliver_async method
|
8
|
-
# @param message [String] message that we want to send to Kafka
|
9
|
-
# @param options [Hash] options (including topic) for producer
|
10
|
-
# @raise [WaterDrop::Errors::InvalidMessageOptions] raised when message options are
|
11
|
-
# somehow invalid and we cannot perform delivery because of that
|
12
|
-
def self.call(message, options)
|
13
|
-
attempts_count ||= 0
|
14
|
-
attempts_count += 1
|
15
|
-
|
16
|
-
validate!(options)
|
17
|
-
return unless WaterDrop.config.deliver
|
18
|
-
|
19
|
-
d_method = WaterDrop.config.raise_on_buffer_overflow ? :deliver_async! : :deliver_async
|
20
|
-
|
21
|
-
DeliveryBoy.send(d_method, message, options)
|
22
|
-
rescue Kafka::Error => e
|
23
|
-
graceful_attempt?(attempts_count, message, options, e) ? retry : raise(e)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WaterDrop
|
4
|
-
# Base messages producer that contains all the logic that is exactly the same for both
|
5
|
-
# sync and async producers
|
6
|
-
class BaseProducer
|
7
|
-
# Contract for checking the correctness of the provided data that someone wants to
|
8
|
-
# dispatch to Kafka
|
9
|
-
SCHEMA = Contracts::MessageOptions.new.freeze
|
10
|
-
|
11
|
-
private_constant :SCHEMA
|
12
|
-
|
13
|
-
class << self
|
14
|
-
private
|
15
|
-
|
16
|
-
# Runs the message options validations and raises an error if anything is invalid
|
17
|
-
# @param options [Hash] hash that we want to validate
|
18
|
-
# @raise [WaterDrop::Errors::InvalidMessageOptions] raised when message options are
|
19
|
-
# somehow invalid and we cannot perform delivery because of that
|
20
|
-
def validate!(options)
|
21
|
-
validation_result = SCHEMA.call(options)
|
22
|
-
return true if validation_result.success?
|
23
|
-
|
24
|
-
raise Errors::InvalidMessageOptions, validation_result.errors
|
25
|
-
end
|
26
|
-
|
27
|
-
# Upon failed delivery, we may try to resend a message depending on the attempt number
|
28
|
-
# or re-raise an error if we're unable to do that after given number of retries
|
29
|
-
# This method checks that and also instruments errors and retries for the delivery
|
30
|
-
# @param attempts_count [Integer] number of attempt (starting from 1) for the delivery
|
31
|
-
# @param message [String] message that we want to send to Kafka
|
32
|
-
# @param options [Hash] options (including topic) for producer
|
33
|
-
# @param error [Kafka::Error] error that occurred
|
34
|
-
# @return [Boolean] true if this is a graceful attempt and we can retry or false it this
|
35
|
-
# was the final one and we should deal with the fact, that we cannot deliver a given
|
36
|
-
# message
|
37
|
-
def graceful_attempt?(attempts_count, message, options, error)
|
38
|
-
scope = "#{to_s.split('::').last.sub('Producer', '_producer').downcase}.call"
|
39
|
-
payload = {
|
40
|
-
caller: self,
|
41
|
-
message: message,
|
42
|
-
options: options,
|
43
|
-
error: error,
|
44
|
-
attempts_count: attempts_count
|
45
|
-
}
|
46
|
-
|
47
|
-
if attempts_count > WaterDrop.config.kafka.max_retries
|
48
|
-
WaterDrop.monitor.instrument("#{scope}.error", payload)
|
49
|
-
false
|
50
|
-
else
|
51
|
-
WaterDrop.monitor.instrument("#{scope}.retry", payload)
|
52
|
-
true
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|