waterdrop 1.0.1 → 1.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4c194065166002b613a559ba2818edc33edea127
4
- data.tar.gz: ca654d85779ccefd488269360a977db8e3406f54
2
+ SHA256:
3
+ metadata.gz: 25c083d88a1163c685e9939307feba4294fd3a526f4523692958cdc5d0d04363
4
+ data.tar.gz: 300d3e1cce18970d0c9beb105ab6e3b6b7d5eedfc388e3fad7f1cd0db1c204e3
5
5
  SHA512:
6
- metadata.gz: dee9f25037979516a0f5d62591e4cce4706a2f54b10862e63bc0ea757664f6dc7b442efb501f70e9eafe0b1ec9d6389be0f9b74968369faeefa69ad1adf864d4
7
- data.tar.gz: da09ca5c22c4553e0c6f82fb16a7761bf97453c8f6ac8a3713ac350f09ffe69f47150912a48f4c2574b9bdacc6197d9ad445dff2ee4c030a082035e5c8ef33b1
6
+ metadata.gz: aa9f0cdfb2285b1f50a71f9a1e84310903e1abc936cd41838f8568a2ddf818b4c83324ccaf7a7c299980a7a8b7d6f0c8fb7fdad65b075e26440bc740be1f20cb
7
+ data.tar.gz: fff2c225e42eeb1ab849fb5ea34c900e6bf4b9783541a6087c094647ec8235c6ce6305087119455d2900cfd53c55e7179b27be5b0f29d49ef80f70720f6674ff
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.4.2
1
+ 2.5.0
data/.travis.yml CHANGED
@@ -9,6 +9,7 @@ rvm:
9
9
  - 2.4.0
10
10
  - 2.4.1
11
11
  - 2.4.2
12
+ - 2.5.0
12
13
  - jruby-head
13
14
  script: bundle exec rspec spec/
14
15
  env:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # WaterDrop changelog
2
2
 
3
+ ## 1.2.0.beta1
4
+ - #45 - Allow specifying a create time for messages
5
+ - #47 - Support SCRAM once released
6
+ - #49 - Add lz4 support once merged and released
7
+ - #50 - Potential message loss in async mode
8
+ - Ruby 2.5.0 support
9
+ - Gem bump to match Karafka framework versioning
10
+ - #48 - ssl_ca_certs_from_system
11
+ - #52 - Use instrumentation compatible with Karafka 1.2
12
+
3
13
  ## 1.0.1
4
14
  - Added high level retry on connection problems
5
15
 
data/Gemfile.lock CHANGED
@@ -1,20 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- waterdrop (1.0.1)
5
- delivery_boy (>= 0.2.2)
4
+ waterdrop (1.2.0.beta1)
5
+ delivery_boy (>= 0.2.3)
6
6
  dry-configurable (~> 0.7)
7
+ dry-monitor (~> 0.1)
7
8
  dry-validation (~> 0.11)
8
9
  null-logger
9
- ruby-kafka (>= 0.5)
10
+ ruby-kafka (>= 0.5.3)
10
11
 
11
12
  GEM
12
13
  remote: https://rubygems.org/
13
14
  specs:
14
15
  concurrent-ruby (1.0.5)
15
- delivery_boy (0.2.2)
16
+ delivery_boy (0.2.4)
16
17
  king_konf (~> 0.1.8)
17
- ruby-kafka (~> 0.4)
18
+ ruby-kafka (~> 0.5.1)
18
19
  diff-lcs (1.3)
19
20
  docile (1.1.5)
20
21
  dry-configurable (0.7.0)
@@ -22,13 +23,22 @@ GEM
22
23
  dry-container (0.6.0)
23
24
  concurrent-ruby (~> 1.0)
24
25
  dry-configurable (~> 0.1, >= 0.1.3)
25
- dry-core (0.4.1)
26
+ dry-core (0.4.4)
26
27
  concurrent-ruby (~> 1.0)
27
28
  dry-equalizer (0.2.0)
29
+ dry-events (0.1.0)
30
+ concurrent-ruby (~> 1.0)
31
+ dry-core (~> 0.4)
32
+ dry-equalizer (~> 0.2)
28
33
  dry-logic (0.4.2)
29
34
  dry-container (~> 0.2, >= 0.2.6)
30
35
  dry-core (~> 0.2)
31
36
  dry-equalizer (~> 0.2)
37
+ dry-monitor (0.1.2)
38
+ dry-configurable (~> 0.5)
39
+ dry-equalizer (~> 0.2)
40
+ dry-events (~> 0.1)
41
+ rouge (~> 2.0, >= 2.2.1)
32
42
  dry-types (0.12.2)
33
43
  concurrent-ruby (~> 1.0)
34
44
  dry-configurable (~> 0.1)
@@ -46,13 +56,14 @@ GEM
46
56
  dry-types (~> 0.12.0)
47
57
  inflecto (0.0.2)
48
58
  json (2.1.0)
49
- king_konf (0.1.8)
59
+ king_konf (0.1.10)
50
60
  null-logger (0.1.4)
61
+ rouge (2.2.1)
51
62
  rspec (3.7.0)
52
63
  rspec-core (~> 3.7.0)
53
64
  rspec-expectations (~> 3.7.0)
54
65
  rspec-mocks (~> 3.7.0)
55
- rspec-core (3.7.0)
66
+ rspec-core (3.7.1)
56
67
  rspec-support (~> 3.7.0)
57
68
  rspec-expectations (3.7.0)
58
69
  diff-lcs (>= 1.2.0, < 2.0)
@@ -60,8 +71,8 @@ GEM
60
71
  rspec-mocks (3.7.0)
61
72
  diff-lcs (>= 1.2.0, < 2.0)
62
73
  rspec-support (~> 3.7.0)
63
- rspec-support (3.7.0)
64
- ruby-kafka (0.5.0)
74
+ rspec-support (3.7.1)
75
+ ruby-kafka (0.5.3)
65
76
  simplecov (0.15.1)
66
77
  docile (~> 1.1.0)
67
78
  json (>= 1.8, < 3)
@@ -77,4 +88,4 @@ DEPENDENCIES
77
88
  waterdrop!
78
89
 
79
90
  BUNDLED WITH
80
- 1.15.4
91
+ 1.16.1
data/README.md CHANGED
@@ -11,6 +11,7 @@ It is:
11
11
 
12
12
  - Thread safe
13
13
  - Supports sync and async producers
14
+ - Working with 0.10.1+ Kafka
14
15
 
15
16
  ## Installation
16
17
 
@@ -60,19 +61,20 @@ end
60
61
 
61
62
  **Note:** All the options are subject to validations. In order to check what is and what is not acceptable, please go to the [config.rb validation schema](https://github.com/karafka/waterdrop/blob/master/lib/water_drop/schemas/config.rb) file.
62
63
 
63
- | Option | Description |
64
- |---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
65
- | delivery_interval | The number of seconds between background message deliveries. Disable timer-based background deliveries by setting this to 0. |
66
- | delivery_threshold | The number of buffered messages that will trigger a background message delivery. Disable buffer size based background deliveries by setting this to 0.|
67
- | required_acks | The number of Kafka replicas that must acknowledge messages before they're considered as successfully written. |
68
- | ack_timeout | A timeout executed by a broker when the client is sending messages to it. |
69
- | max_retries | The number of retries when attempting to deliver messages. |
70
- | retry_backoff | The number of seconds to wait after a failed attempt to send messages to a Kafka broker before retrying. |
71
- | max_buffer_bytesize | The maximum number of bytes allowed in the buffer before new messages are rejected. |
72
- | max_buffer_size | The maximum number of messages allowed in the buffer before new messages are rejected. |
73
- | max_queue_size | The maximum number of messages allowed in the queue before new messages are rejected. |
74
- | sasl_plain_username | The username used to authenticate. |
75
- | sasl_plain_password | The password used to authenticate. |
64
+ | Option | Description |
65
+ |--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
66
+ | raise_on_buffer_overflow | Should we raise an exception, when messages can't be sent in an async way due to the message buffer overflow or should we just drop them |
67
+ | delivery_interval | The number of seconds between background message deliveries. Disable timer-based background deliveries by setting this to 0. |
68
+ | delivery_threshold | The number of buffered messages that will trigger a background message delivery. Disable buffer size based background deliveries by setting this to 0.|
69
+ | required_acks | The number of Kafka replicas that must acknowledge messages before they're considered as successfully written. |
70
+ | ack_timeout | A timeout executed by a broker when the client is sending messages to it. |
71
+ | max_retries | The number of retries when attempting to deliver messages. |
72
+ | retry_backoff | The number of seconds to wait after a failed attempt to send messages to a Kafka broker before retrying. |
73
+ | max_buffer_bytesize | The maximum number of bytes allowed in the buffer before new messages are rejected. |
74
+ | max_buffer_size | The maximum number of messages allowed in the buffer before new messages are rejected. |
75
+ | max_queue_size | The maximum number of messages allowed in the queue before new messages are rejected. |
76
+ | sasl_plain_username | The username used to authenticate. |
77
+ | sasl_plain_password | The password used to authenticate. |
76
78
 
77
79
  This configuration can be also placed in *config/initializers* and can vary based on the environment:
78
80
 
@@ -95,12 +97,13 @@ WaterDrop::AsyncProducer.call('message', topic: 'my-topic')
95
97
 
96
98
  Both ```SyncProducer``` and ```AsyncProducer``` accept following options:
97
99
 
98
- | Option | Required | Value type | Description |
99
- |-------------------- |----------|----------------|---------------------------------------------------------------------|
100
- | ```topic``` | true | String | The Kafka topic that should be written to |
101
- | ```key``` | false | String | The key that should be set on the Kafka message |
102
- | ```partition``` | false | Integer | A specific partition number that should be written to |
103
- | ```partition_key``` | false | String | A string that can be used to deterministically select the partition |
100
+ | Option | Required | Value type | Description |
101
+ |-------------------- |----------|------------|---------------------------------------------------------------------|
102
+ | ```topic``` | true | String | The Kafka topic that should be written to |
103
+ | ```key``` | false | String | The key that should be set on the Kafka message |
104
+ | ```partition``` | false | Integer | A specific partition number that should be written to |
105
+ | ```partition_key``` | false | String | A string that can be used to deterministically select the partition |
106
+ | ```create_time``` | false | Time | The timestamp that should be set on the message |
104
107
 
105
108
  Keep in mind, that message you want to send should be either binary or stringified (to_s, to_json, etc).
106
109
 
@@ -110,23 +113,14 @@ Keep in mind, that message you want to send should be either binary or stringifi
110
113
  * [WaterDrop Travis CI](https://travis-ci.org/karafka/waterdrop)
111
114
  * [WaterDrop Coditsu](https://app.coditsu.io/karafka/repositories/waterdrop)
112
115
 
113
- ## Note on Patches/Pull Requests
116
+ ## Note on contributions
114
117
 
115
- Fork the project.
116
- Make your feature addition or bug fix.
117
- Add tests for it. This is important so we don't break it in a future versions unintentionally.
118
- Commit, do not mess with version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull). Send me a pull request. Bonus points for topic branches.
118
+ First, thank you for considering contributing to WaterDrop! It's people like you that make the open source community such a great community!
119
119
 
120
- [![coditsu](https://coditsu.io/assets/quality_bar.svg)](https://app.coditsu.io/karafka/repositories/waterdrop)
120
+ Each pull request must pass all the rspec specs and meet our quality requirements.
121
121
 
122
- Each pull request must pass our quality requirements. To check if everything is as it should be, we use [Coditsu](https://coditsu.io) that combines multiple linters and code analyzers for both code and documentation.
122
+ To check if everything is as it should be, we use [Coditsu](https://coditsu.io) that combines multiple linters and code analyzers for both code and documentation. Once you're done with your changes, submit a pull request.
123
123
 
124
- Unfortunately, it does not yet support independent forks, however you should be fine by looking at what we require.
124
+ Coditsu will automatically check your work against our quality standards. You can find your commit check results on the [builds page](https://app.coditsu.io/karafka/repositories/waterdrop/builds/commit_builds) of WaterDrop repository.
125
125
 
126
- Please run:
127
-
128
- ```bash
129
- bundle exec rspec
130
- ```
131
-
132
- to check if everything is in order. After that you can submit a pull request.
126
+ [![coditsu](https://coditsu.io/assets/quality_bar.svg)](https://app.coditsu.io/karafka/repositories/waterdrop/builds/commit_builds)
data/lib/water_drop.rb CHANGED
@@ -5,7 +5,9 @@
5
5
  json
6
6
  delivery_boy
7
7
  null_logger
8
+ singleton
8
9
  dry-configurable
10
+ dry/monitor/notifications
9
11
  dry-validation
10
12
  ].each { |lib| require lib }
11
13
 
@@ -44,6 +46,11 @@ module WaterDrop
44
46
  Config.config
45
47
  end
46
48
 
49
+ # @return [::WaterDrop::Monitor] monitor that we want to use
50
+ def monitor
51
+ config.monitor
52
+ end
53
+
47
54
  # @return [String] root path of this gem
48
55
  def gem_root
49
56
  Pathname.new(File.expand_path('../..', __FILE__))
@@ -53,6 +60,8 @@ end
53
60
 
54
61
  %w[
55
62
  version
63
+ instrumentation/monitor
64
+ instrumentation/listener
56
65
  schemas/message_options
57
66
  schemas/config
58
67
  config
@@ -10,20 +10,17 @@ module WaterDrop
10
10
  # @raise [WaterDrop::Errors::InvalidMessageOptions] raised when message options are
11
11
  # somehow invalid and we cannot perform delivery because of that
12
12
  def self.call(message, options)
13
- attempts ||= 0
14
- attempts += 1
13
+ attempts_count ||= 0
14
+ attempts_count += 1
15
15
 
16
16
  validate!(options)
17
17
  return unless WaterDrop.config.deliver
18
- DeliveryBoy.deliver_async(message, options)
19
- rescue Kafka::Error => e
20
- if attempts > WaterDrop.config.kafka.max_retries
21
- WaterDrop.logger.error e
22
- raise e
23
- else
24
- WaterDrop.logger.warn "Retrying delivery after: #{e}"
25
- retry
26
- end
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 => error
23
+ graceful_attempt?(attempts_count, message, options, error) ? retry : raise(error)
27
24
  end
28
25
  end
29
26
  end
@@ -16,6 +16,35 @@ module WaterDrop
16
16
  return true if validation_result.success?
17
17
  raise Errors::InvalidMessageOptions, validation_result.errors
18
18
  end
19
+
20
+ # Upon failed delivery, we may try to resend a message depending on the attempt number
21
+ # or reraise an error if we're unable to do that after given number of retries
22
+ # This method checks that and also instruments errors and retries for the delivery
23
+ # @param attempts_count [Integer] number of attempt (starting from 1) for the delivery
24
+ # @param message [String] message that we want to send to Kafka
25
+ # @param options [Hash] options (including topic) for producer
26
+ # @param error [Kafka::Error] error that occured
27
+ # @return [Boolean] true if this is a graceful attempt and we can retry or false it this
28
+ # was the final one and we should deal with the fact, that we cannot deliver a given
29
+ # message
30
+ def graceful_attempt?(attempts_count, message, options, error)
31
+ scope = "#{to_s.split('::').last.sub('Producer', '_producer').downcase}.call"
32
+ payload = {
33
+ caller: self,
34
+ message: message,
35
+ options: options,
36
+ error: error,
37
+ attempts_count: attempts_count
38
+ }
39
+
40
+ if attempts_count > WaterDrop.config.kafka.max_retries
41
+ WaterDrop.monitor.instrument("#{scope}.error", payload)
42
+ false
43
+ else
44
+ WaterDrop.monitor.instrument("#{scope}.retry", payload)
45
+ true
46
+ end
47
+ end
19
48
  end
20
49
  end
21
50
  end
@@ -12,9 +12,17 @@ module WaterDrop
12
12
  setting :client_id, 'waterdrop'
13
13
  # option [Instance, nil] logger that we want to use or nil to fallback to ruby-kafka logger
14
14
  setting :logger, NullLogger.new
15
+ # option [Instance] monitor that we want to use. See instrumentation part of the README for
16
+ # more details
17
+ setting :monitor, WaterDrop::Instrumentation::Monitor.instance
15
18
  # option [Boolean] should we send messages. Setting this to false can be really useful when
16
19
  # testing and or developing because when set to false, won't actually ping Kafka
17
20
  setting :deliver, true
21
+ # option [Boolean] if you're producing messages faster than the framework or the network can
22
+ # send them off, ruby-kafka might reject them. If that happens, WaterDrop will either raise
23
+ # or ignore - this setting manages that behavior. This only applies to async producer as
24
+ # sync producer will always raise upon problems
25
+ setting :raise_on_buffer_overflow, true
18
26
 
19
27
  # Settings directly related to the Kafka driver
20
28
  setting :kafka do
@@ -73,24 +81,33 @@ module WaterDrop
73
81
  setting :compression_codec, nil
74
82
 
75
83
  # SSL authentication related settings
76
- # option ca_cert [String] SSL CA certificate
84
+ # option ca_cert [String, nil] SSL CA certificate
77
85
  setting :ssl_ca_cert, nil
78
- # option ssl_ca_cert_file_path [String] SSL CA certificate file path
86
+ # option ssl_ca_cert_file_path [String, nil] SSL CA certificate file path
79
87
  setting :ssl_ca_cert_file_path, nil
80
- # option ssl_client_cert [String] SSL client certificate
88
+ # option ssl_ca_certs_from_system [Boolean] Use the CA certs from your system's default
89
+ # certificate store
90
+ setting :ssl_ca_certs_from_system, false
91
+ # option ssl_client_cert [String, nil] SSL client certificate
81
92
  setting :ssl_client_cert, nil
82
- # option ssl_client_cert_key [String] SSL client certificate password
93
+ # option ssl_client_cert_key [String, nil] SSL client certificate password
83
94
  setting :ssl_client_cert_key, nil
84
- # option sasl_gssapi_principal [String] sasl principal
95
+ # option sasl_gssapi_principal [String, nil] sasl principal
85
96
  setting :sasl_gssapi_principal, nil
86
- # option sasl_gssapi_keytab [String] sasl keytab
97
+ # option sasl_gssapi_keytab [String, nil] sasl keytab
87
98
  setting :sasl_gssapi_keytab, nil
88
99
  # option sasl_plain_authzid [String] The authorization identity to use
89
100
  setting :sasl_plain_authzid, ''
90
- # option sasl_plain_username [String] The username used to authenticate
101
+ # option sasl_plain_username [String, nil] The username used to authenticate
91
102
  setting :sasl_plain_username, nil
92
- # option sasl_plain_password [String] The password used to authenticate
103
+ # option sasl_plain_password [String, nil] The password used to authenticate
93
104
  setting :sasl_plain_password, nil
105
+ # option sasl_scram_username [String, nil] The username used to authenticate
106
+ setting :sasl_scram_username, nil
107
+ # option sasl_scram_password [String, nil] The password used to authenticate
108
+ setting :sasl_scram_password, nil
109
+ # option sasl_scram_mechanism [String, nil] Scram mechanism, either 'sha256' or 'sha512'
110
+ setting :sasl_scram_mechanism, nil
94
111
  end
95
112
 
96
113
  # option producer [Hash] - optional - producer configuration options
@@ -11,5 +11,8 @@ module WaterDrop
11
11
 
12
12
  # Raised when we try to send message with invalid optionss
13
13
  InvalidMessageOptions = Class.new(BaseError)
14
+
15
+ # Raised when want to hook up to an event that is not registered and supported
16
+ UnregisteredMonitorEvent = Class.new(BaseError)
14
17
  end
15
18
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WaterDrop
4
+ module Instrumentation
5
+ # Default listener that hooks up to our instrumentation and uses its events for logging
6
+ # It can be removed/replaced or anything without any harm to the Waterdrop flow
7
+ # @note It is a module as we can use it then as a part of the Karafka framework listener
8
+ # as well as we can use it standalone
9
+ module Listener
10
+ # Log levels that we use in this particular listener
11
+ USED_LOG_LEVELS = %i[
12
+ info
13
+ error
14
+ ].freeze
15
+
16
+ %i[
17
+ sync_producer
18
+ async_producer
19
+ ].each do |producer_type|
20
+ error_name = :"on_#{producer_type}_call_error"
21
+ retry_name = :"on_#{producer_type}_call_retry"
22
+
23
+ define_method error_name do |event|
24
+ options = event[:options]
25
+ error = event[:error]
26
+ error "Delivery failure to: #{options} because of #{error}"
27
+ end
28
+
29
+ define_method retry_name do |event|
30
+ attempts_count = event[:attempts_count]
31
+ options = event[:options]
32
+ error = event[:error]
33
+
34
+ info "Attempt #{attempts_count} of delivery to: #{options} because of #{error}"
35
+ end
36
+
37
+ module_function error_name
38
+ module_function retry_name
39
+ public error_name
40
+ public retry_name
41
+ end
42
+
43
+ USED_LOG_LEVELS.each do |log_level|
44
+ define_method log_level do |*args|
45
+ WaterDrop.logger.send(log_level, *args)
46
+ end
47
+
48
+ module_function log_level
49
+ private_class_method log_level
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WaterDrop
4
+ # Namespace for all the things related with WaterDrop instrumentation process
5
+ module Instrumentation
6
+ # Monitor is used to hookup external monitoring services to monitor how WaterDrop works
7
+ # Since it is a pub-sub based on dry-monitor, you can use as many subscribers/loggers at the
8
+ # same time, which means that you might have for example file logging and newrelic at the same
9
+ # time
10
+ # @note This class acts as a singleton because we are only permitted to have single monitor
11
+ # per running process (just as logger)
12
+ class Monitor < Dry::Monitor::Notifications
13
+ include Singleton
14
+
15
+ # List of events that we support in the system and to which a monitor client can hook up
16
+ # @note The non-error once support timestamp benchmarking
17
+ BASE_EVENTS = %w[
18
+ async_producer.call.error
19
+ async_producer.call.retry
20
+ sync_producer.call.error
21
+ sync_producer.call.retry
22
+ ].freeze
23
+
24
+ private_constant :BASE_EVENTS
25
+
26
+ # @return [WaterDrop::Instrumentation::Monitor] monitor instance for system instrumentation
27
+ def initialize
28
+ super(:waterdrop)
29
+ BASE_EVENTS.each(&method(:register_event))
30
+ end
31
+
32
+ # Allows us to subscribe to events with a code that will be yielded upon events
33
+ # @param event_name_or_listener [String, Object] name of the event we want to subscribe to
34
+ # or a listener if we decide to go with object listener
35
+ def subscribe(event_name_or_listener)
36
+ return super unless event_name_or_listener.is_a?(String)
37
+ return super if available_events.include?(event_name_or_listener)
38
+ raise Errors::UnregisteredMonitorEvent, event_name_or_listener
39
+ end
40
+
41
+ # @return [Array<String>] names of available events to which we can subscribe
42
+ def available_events
43
+ __bus__.events.keys
44
+ end
45
+ end
46
+ end
47
+ end
@@ -11,18 +11,8 @@ module WaterDrop
11
11
  kafka+ssl
12
12
  ].freeze
13
13
 
14
- # All encryption related options keys
15
- ENCRYPTION_OPTIONS_KEYS = %i[
16
- ssl_ca_cert
17
- ssl_ca_cert_file_path
18
- ssl_client_cert
19
- ssl_client_cert_key
20
- sasl_plain_authzid
21
- sasl_plain_username
22
- sasl_plain_password
23
- sasl_gssapi_principal
24
- sasl_gssapi_keytab
25
- ].freeze
14
+ # Available sasl scram mechanism of authentication (plus nil)
15
+ SASL_SCRAM_MECHANISMS ||= %w[sha256 sha512].freeze
26
16
 
27
17
  configure do
28
18
  config.messages_file = File.join(
@@ -43,13 +33,14 @@ module WaterDrop
43
33
  required(:client_id).filled(:str?, format?: Schemas::TOPIC_REGEXP)
44
34
  required(:logger).filled
45
35
  required(:deliver).filled(:bool?)
36
+ required(:raise_on_buffer_overflow).filled(:bool?)
46
37
 
47
38
  required(:kafka).schema do
48
39
  required(:seed_brokers).filled { each(:broker_schema?) }
49
40
  required(:connect_timeout).filled { (int? | float?) & gt?(0) }
50
41
  required(:socket_timeout).filled { (int? | float?) & gt?(0) }
51
42
  required(:compression_threshold).filled(:int?, gteq?: 1)
52
- optional(:compression_codec).maybe(included_in?: %i[snappy gzip])
43
+ optional(:compression_codec).maybe(included_in?: %i[snappy gzip lz4])
53
44
 
54
45
  required(:max_buffer_bytesize).filled(:int?, gt?: 0)
55
46
  required(:max_buffer_size).filled(:int?, gt?: 0)
@@ -63,9 +54,27 @@ module WaterDrop
63
54
  required(:retry_backoff).filled(:int?, gteq?: 0)
64
55
  required(:required_acks).filled(included_in?: [1, 0, -1, :all])
65
56
 
66
- ENCRYPTION_OPTIONS_KEYS.each do |encryption_attribute|
57
+ %i[
58
+ ssl_ca_cert
59
+ ssl_ca_cert_file_path
60
+ ssl_client_cert
61
+ ssl_client_cert_key
62
+ sasl_gssapi_principal
63
+ sasl_gssapi_keytab
64
+ sasl_plain_authzid
65
+ sasl_plain_username
66
+ sasl_plain_password
67
+ sasl_scram_username
68
+ sasl_scram_password
69
+ ].each do |encryption_attribute|
67
70
  optional(encryption_attribute).maybe(:str?)
68
71
  end
72
+
73
+ optional(:ssl_ca_certs_from_system).maybe(:bool?)
74
+
75
+ # It's not with other encryptions as it has some more rules
76
+ optional(:sasl_scram_mechanism)
77
+ .maybe(:str?, included_in?: WaterDrop::Schemas::SASL_SCRAM_MECHANISMS)
69
78
  end
70
79
  end
71
80
  end
@@ -13,6 +13,7 @@ module WaterDrop
13
13
  optional(:key).maybe(:str?, :filled?)
14
14
  optional(:partition).filled(:int?, gteq?: 0)
15
15
  optional(:partition_key).maybe(:str?, :filled?)
16
+ optional(:create_time).maybe(:time?)
16
17
  end
17
18
  end
18
19
  end
@@ -10,20 +10,15 @@ module WaterDrop
10
10
  # @raise [WaterDrop::Errors::InvalidMessageOptions] raised when message options are
11
11
  # somehow invalid and we cannot perform delivery because of that
12
12
  def self.call(message, options)
13
- attempts ||= 0
14
- attempts += 1
13
+ attempts_count ||= 0
14
+ attempts_count += 1
15
15
 
16
16
  validate!(options)
17
17
  return unless WaterDrop.config.deliver
18
+
18
19
  DeliveryBoy.deliver(message, options)
19
- rescue Kafka::Error => e
20
- if attempts > WaterDrop.config.kafka.max_retries
21
- WaterDrop.logger.error e
22
- raise e
23
- else
24
- WaterDrop.logger.warn "Retrying delivery after: #{e}"
25
- retry
26
- end
20
+ rescue Kafka::Error => error
21
+ graceful_attempt?(attempts_count, message, options, error) ? retry : raise(error)
27
22
  end
28
23
  end
29
24
  end
@@ -3,5 +3,5 @@
3
3
  # WaterDrop library
4
4
  module WaterDrop
5
5
  # Current WaterDrop version
6
- VERSION = '1.0.1'
6
+ VERSION = '1.2.0.beta1'
7
7
  end
data/waterdrop.gemspec CHANGED
@@ -12,15 +12,16 @@ Gem::Specification.new do |spec|
12
12
  spec.authors = ['Maciej Mensfeld']
13
13
  spec.email = %w[maciej@mensfeld.pl]
14
14
  spec.homepage = 'https://github.com/karafka/waterdrop'
15
- spec.summary = ' Kafka messaging made easy! '
15
+ spec.summary = 'Kafka messaging made easy!'
16
16
  spec.description = spec.summary
17
17
  spec.license = 'MIT'
18
18
 
19
- spec.add_dependency 'delivery_boy', '>= 0.2.2'
19
+ spec.add_dependency 'delivery_boy', '>= 0.2.3'
20
20
  spec.add_dependency 'dry-configurable', '~> 0.7'
21
+ spec.add_dependency 'dry-monitor', '~> 0.1'
21
22
  spec.add_dependency 'dry-validation', '~> 0.11'
22
23
  spec.add_dependency 'null-logger'
23
- spec.add_dependency 'ruby-kafka', '>= 0.5'
24
+ spec.add_dependency 'ruby-kafka', '>= 0.5.3'
24
25
 
25
26
  spec.required_ruby_version = '>= 2.2.0'
26
27
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waterdrop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Mensfeld
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-06 00:00:00.000000000 Z
11
+ date: 2018-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: delivery_boy
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.2
19
+ version: 0.2.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.2
26
+ version: 0.2.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: dry-configurable
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-monitor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: dry-validation
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +86,14 @@ dependencies:
72
86
  requirements:
73
87
  - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '0.5'
89
+ version: 0.5.3
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '0.5'
96
+ version: 0.5.3
83
97
  description: Kafka messaging made easy!
84
98
  email:
85
99
  - maciej@mensfeld.pl
@@ -103,6 +117,8 @@ files:
103
117
  - lib/water_drop/base_producer.rb
104
118
  - lib/water_drop/config.rb
105
119
  - lib/water_drop/errors.rb
120
+ - lib/water_drop/instrumentation/listener.rb
121
+ - lib/water_drop/instrumentation/monitor.rb
106
122
  - lib/water_drop/schemas/config.rb
107
123
  - lib/water_drop/schemas/message_options.rb
108
124
  - lib/water_drop/sync_producer.rb
@@ -124,12 +140,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
140
  version: 2.2.0
125
141
  required_rubygems_version: !ruby/object:Gem::Requirement
126
142
  requirements:
127
- - - ">="
143
+ - - ">"
128
144
  - !ruby/object:Gem::Version
129
- version: '0'
145
+ version: 1.3.1
130
146
  requirements: []
131
147
  rubyforge_project:
132
- rubygems_version: 2.6.13
148
+ rubygems_version: 2.7.3
133
149
  signing_key:
134
150
  specification_version: 4
135
151
  summary: Kafka messaging made easy!