waterdrop 1.0.1 → 1.2.0.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 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!