karafka 2.0.0.beta5 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +28 -0
  4. data/CONTRIBUTING.md +0 -5
  5. data/Gemfile.lock +12 -42
  6. data/LICENSE-COMM +1 -1
  7. data/README.md +44 -16
  8. data/bin/stress_many +1 -1
  9. data/bin/stress_one +1 -1
  10. data/config/errors.yml +52 -5
  11. data/docker-compose.yml +7 -0
  12. data/karafka.gemspec +2 -4
  13. data/lib/karafka/active_job/consumer.rb +2 -0
  14. data/lib/karafka/active_job/job_options_contract.rb +8 -2
  15. data/lib/karafka/base_consumer.rb +4 -6
  16. data/lib/karafka/cli/install.rb +15 -2
  17. data/lib/karafka/cli/server.rb +4 -2
  18. data/lib/karafka/connection/client.rb +20 -17
  19. data/lib/karafka/connection/listener.rb +12 -24
  20. data/lib/karafka/connection/pauses_manager.rb +0 -8
  21. data/lib/karafka/contracts/base.rb +2 -8
  22. data/lib/karafka/contracts/config.rb +71 -51
  23. data/lib/karafka/contracts/consumer_group.rb +25 -18
  24. data/lib/karafka/contracts/consumer_group_topic.rb +30 -16
  25. data/lib/karafka/contracts/server_cli_options.rb +18 -7
  26. data/lib/karafka/helpers/colorize.rb +20 -0
  27. data/lib/karafka/instrumentation/logger_listener.rb +8 -2
  28. data/lib/karafka/instrumentation/vendors/datadog/dashboard.json +1 -0
  29. data/lib/karafka/instrumentation/vendors/datadog/listener.rb +232 -0
  30. data/lib/karafka/pro/active_job/dispatcher.rb +5 -2
  31. data/lib/karafka/pro/active_job/job_options_contract.rb +11 -6
  32. data/lib/karafka/pro/base_consumer.rb +21 -12
  33. data/lib/karafka/pro/contracts/base.rb +21 -0
  34. data/lib/karafka/pro/contracts/consumer_group.rb +34 -0
  35. data/lib/karafka/pro/contracts/consumer_group_topic.rb +33 -0
  36. data/lib/karafka/pro/loader.rb +23 -3
  37. data/lib/karafka/pro/processing/coordinator.rb +51 -0
  38. data/lib/karafka/pro/processing/partitioner.rb +60 -0
  39. data/lib/karafka/pro/routing/builder_extensions.rb +30 -0
  40. data/lib/karafka/pro/routing/{extensions.rb → topic_extensions.rb} +7 -1
  41. data/lib/karafka/processing/coordinator.rb +6 -2
  42. data/lib/karafka/processing/coordinators_buffer.rb +3 -7
  43. data/lib/karafka/processing/executor.rb +1 -1
  44. data/lib/karafka/processing/jobs_queue.rb +11 -0
  45. data/lib/karafka/processing/partitioner.rb +22 -0
  46. data/lib/karafka/processing/worker.rb +4 -2
  47. data/lib/karafka/setup/config.rb +9 -3
  48. data/lib/karafka/templates/example_consumer.rb.erb +2 -2
  49. data/lib/karafka/version.rb +1 -1
  50. data/lib/karafka.rb +2 -2
  51. data.tar.gz.sig +0 -0
  52. metadata +15 -34
  53. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c8e680ffdf69f88899a715c84cc484e8f568f4a93da9284195f4bf55a283ee1
4
- data.tar.gz: 974356226a10ba2c77de770351a47180716533021a89040bcdc1aae57f452121
3
+ metadata.gz: b2a60c5c750ef681042f6e0a0d61032c2b9d9e8d48fa73ec480157c7bffb4cc7
4
+ data.tar.gz: c04074859408e77d236e86dcfdbe8502ba5322f6e7d8d1e236c9aa838b3e1a29
5
5
  SHA512:
6
- metadata.gz: 2427aaae1b1b07430df7c9f042d290bbae8380fb1f6ec7c26eecee92b8fe79e13ea9f3a99a36bf89b314ffba809c556618b22c0a87f0c0c83bb73cf8af72321b
7
- data.tar.gz: 55e18448b5645acd38c4194967ea7df657c142d82a105699f7b204f222f8dfb2dbd14cce82b1f424ec177afb78049b3e7588642013674a3c2923a8848b6b87e7
6
+ metadata.gz: 487dc8f5fb131dc8f25087ae026b40710c9859e7849b878ac42053737dd665a0147462fd6348e3e03eb87e0d6657c8f0038b02506f525ee221ee1f6d806bcf84
7
+ data.tar.gz: 23a68b2d97cd5441088521c949c2a0ec23befde2fa81c9b9178ea6786a582aea5e342697d08f9a3dd1dfe1401792bcbc3e936b91c87eb740ef66beccd69b39bf
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Karafka framework changelog
2
2
 
3
+ ## 2.0.0.rc3 (2022-07-26)
4
+ - Fix Pro partitioner hash function may not utilize all the threads (#907).
5
+ - Improve virtual partitions messages distribution.
6
+ - Add StatsD/DataDog optional monitoring listener + dashboard template.
7
+ - Validate that Pro consumer is always used for Pro subscription.
8
+ - Improve ActiveJob consumer shutdown behaviour.
9
+ - Change default `max_wait_time` to 1 second.
10
+ - Change default `max_messages` to 100 (#915).
11
+ - Move logger listener polling reporting level to debug when no messages (#916).
12
+ - Improve stability on aggressive rebalancing (multiple rebalances in a short period).
13
+ - Improve specs stability.
14
+ - Allow using `:key` and `:partition_key` for Enhanced Active Job partitioning.
15
+
16
+ ## 2.0.0.rc2 (2022-07-19)
17
+ - Fix `example_consumer.rb.erb` `#shutdown` and `#revoked` signatures to correct once.
18
+ - Improve the install user experience (print status and created files).
19
+ - Change default `max_wait_time` from 10s to 5s.
20
+ - Remove direct dependency on `dry-configurable` in favour of a home-brew.
21
+ - Remove direct dependency on `dry-validation` in favour of a home-brew.
22
+
23
+ ## 2.0.0-rc1 (2022-07-08)
24
+ - Extract consumption partitioner out of listener inline code.
25
+ - Introduce virtual partitioner concept for parallel processing of data from a single topic partition.
26
+ - Improve stability when there kafka internal errors occur while polling.
27
+ - Fix a case where we would resume a LRJ partition upon rebalance where we would reclaim the partition while job was still running.
28
+ - Do not revoke pauses for lost partitions. This will allow to un-pause reclaimed partitions when LRJ jobs are done.
29
+ - Fail integrations by default (unless configured otherwise) if any errors occur during Karafka server execution.
30
+
3
31
  ## 2.0.0-beta5 (2022-07-05)
4
32
  - Always resume processing of a revoked partition upon assignment.
5
33
  - Improve specs stability.
data/CONTRIBUTING.md CHANGED
@@ -34,8 +34,3 @@ By sending a pull request to the pro components, you are agreeing to transfer th
34
34
 
35
35
  If you have any questions, create an [issue](issue) (protip: do a quick search first to see if someone else didn't ask the same question before!).
36
36
  You can also reach us at hello@karafka.opencollective.com.
37
-
38
- ## Credits
39
-
40
- Thank you to all the people who have already contributed to karafka!
41
- <a href="graphs/contributors"><img src="https://opencollective.com/karafka/contributors.svg?width=890" /></a>
data/Gemfile.lock CHANGED
@@ -1,22 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- karafka (2.0.0.beta5)
5
- dry-configurable (~> 0.13)
4
+ karafka (2.0.0.rc3)
6
5
  dry-monitor (~> 0.5)
7
- dry-validation (~> 1.7)
8
6
  rdkafka (>= 0.10)
9
7
  thor (>= 0.20)
10
- waterdrop (>= 2.3.1, < 3.0.0)
8
+ waterdrop (>= 2.3.3, < 3.0.0)
11
9
  zeitwerk (~> 2.3)
12
10
 
13
11
  GEM
14
12
  remote: https://rubygems.org/
15
13
  specs:
16
- activejob (7.0.3)
17
- activesupport (= 7.0.3)
14
+ activejob (7.0.3.1)
15
+ activesupport (= 7.0.3.1)
18
16
  globalid (>= 0.3.6)
19
- activesupport (7.0.3)
17
+ activesupport (7.0.3.1)
20
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
21
19
  i18n (>= 1.6, < 2)
22
20
  minitest (>= 5.1)
@@ -28,51 +26,25 @@ GEM
28
26
  dry-configurable (0.15.0)
29
27
  concurrent-ruby (~> 1.0)
30
28
  dry-core (~> 0.6)
31
- dry-container (0.9.0)
32
- concurrent-ruby (~> 1.0)
33
- dry-configurable (~> 0.13, >= 0.13.0)
34
- dry-core (0.7.1)
29
+ dry-core (0.8.0)
35
30
  concurrent-ruby (~> 1.0)
36
31
  dry-events (0.3.0)
37
32
  concurrent-ruby (~> 1.0)
38
33
  dry-core (~> 0.5, >= 0.5)
39
- dry-inflector (0.2.1)
40
- dry-initializer (3.1.1)
41
- dry-logic (1.2.0)
42
- concurrent-ruby (~> 1.0)
43
- dry-core (~> 0.5, >= 0.5)
44
- dry-monitor (0.5.0)
34
+ dry-monitor (0.6.1)
45
35
  dry-configurable (~> 0.13, >= 0.13.0)
46
36
  dry-core (~> 0.5, >= 0.5)
47
37
  dry-events (~> 0.2)
48
- dry-schema (1.9.2)
49
- concurrent-ruby (~> 1.0)
50
- dry-configurable (~> 0.13, >= 0.13.0)
51
- dry-core (~> 0.5, >= 0.5)
52
- dry-initializer (~> 3.0)
53
- dry-logic (~> 1.0)
54
- dry-types (~> 1.5)
55
- dry-types (1.5.1)
56
- concurrent-ruby (~> 1.0)
57
- dry-container (~> 0.3)
58
- dry-core (~> 0.5, >= 0.5)
59
- dry-inflector (~> 0.1, >= 0.1.2)
60
- dry-logic (~> 1.0, >= 1.0.2)
61
- dry-validation (1.8.1)
62
- concurrent-ruby (~> 1.0)
63
- dry-container (~> 0.7, >= 0.7.1)
64
- dry-core (~> 0.5, >= 0.5)
65
- dry-initializer (~> 3.0)
66
- dry-schema (~> 1.8, >= 1.8.0)
38
+ zeitwerk (~> 2.5)
67
39
  factory_bot (6.2.1)
68
40
  activesupport (>= 5.0.0)
69
41
  ffi (1.15.5)
70
42
  globalid (1.0.0)
71
43
  activesupport (>= 5.0)
72
- i18n (1.10.0)
44
+ i18n (1.12.0)
73
45
  concurrent-ruby (~> 1.0)
74
46
  mini_portile2 (2.8.0)
75
- minitest (5.15.0)
47
+ minitest (5.16.2)
76
48
  rake (13.0.6)
77
49
  rdkafka (0.12.0)
78
50
  ffi (~> 1.15)
@@ -100,11 +72,9 @@ GEM
100
72
  thor (1.2.1)
101
73
  tzinfo (2.0.4)
102
74
  concurrent-ruby (~> 1.0)
103
- waterdrop (2.3.1)
75
+ waterdrop (2.3.3)
104
76
  concurrent-ruby (>= 1.1)
105
- dry-configurable (~> 0.13)
106
77
  dry-monitor (~> 0.5)
107
- dry-validation (~> 1.7)
108
78
  rdkafka (>= 0.10)
109
79
  zeitwerk (~> 2.3)
110
80
  zeitwerk (2.6.0)
@@ -121,4 +91,4 @@ DEPENDENCIES
121
91
  simplecov
122
92
 
123
93
  BUNDLED WITH
124
- 2.3.11
94
+ 2.3.15
data/LICENSE-COMM CHANGED
@@ -30,7 +30,7 @@ The Open Source version of the Software (“LGPL Version”) is licensed under t
30
30
 
31
31
  4. Ownership. Notwithstanding anything to the contrary contained herein, except for the limited license rights expressly provided herein, Maciej Mensfeld and its suppliers have and will retain all rights, title and interest (including, without limitation, all patent, copyright, trademark, trade secret and other intellectual property rights) in and to the Software and all copies, modifications and derivative works thereof (including any changes which incorporate any of your ideas, feedback or suggestions). You acknowledge that you are obtaining only a limited license right to the Software, and that irrespective of any use of the words “purchase”, “sale” or like terms hereunder no ownership rights are being conveyed to you under this Agreement or otherwise.
32
32
 
33
- 5. Fees and Payment. The Software license fees will be due and payable in full as set forth in the applicable invoice or at the time of purchase. If the Software does not function properly within two weeks of purchase, please contact us within those two weeks for a refund. You shall be responsible for all taxes, withholdings, duties and levies arising from the order (excluding taxes based on the net income of Maciej Mensfeld).
33
+ 5. Fees and Payment. The Software license fees will be due and payable in full as set forth in the applicable invoice or at the time of purchase. There are no refunds beyond the remedy refund.
34
34
 
35
35
  6. Support, Maintenance and Services. Subject to the terms and conditions of this Agreement, as set forth in your invoice, and as set forth on the Karafka Pro support page (https://github.com/karafka/karafka/wiki/Commercial-Support), support and maintenance services may be included with the purchase of your license subscription.
36
36
 
data/README.md CHANGED
@@ -4,11 +4,18 @@
4
4
  [![Gem Version](https://badge.fury.io/rb/karafka.svg)](http://badge.fury.io/rb/karafka)
5
5
  [![Join the chat at https://slack.karafka.io](https://raw.githubusercontent.com/karafka/misc/master/slack.svg)](https://slack.karafka.io)
6
6
 
7
- **Note**: All of the documentation here refers to Karafka `2.0`. If you are looking for the documentation to Karafka `1.4` please click here (TBA).
7
+ **Note**: All of the documentation here refers to Karafka `2.0.0.rc2` or higher. If you are looking for the documentation for Karafka `1.4`, please click [here](https://github.com/karafka/wiki/tree/1.4).
8
8
 
9
9
  ## About Karafka
10
10
 
11
- Karafka is a framework used to simplify Apache Kafka based Ruby and Ruby on Rails applications development.
11
+ Karafka is a Ruby and Rails multi-threaded efficient Kafka processing framework that:
12
+
13
+ - Supports parallel processing in [multiple threads](Concurrency-and-multithreading) (also for a single topic partition work)
14
+ - Has [ActiveJob backend](Active-Job) support (including ordered jobs)
15
+ - [Automatically integrates](Integrating-with-Ruby-on-Rails-and-other-frameworks#integrating-with-ruby-on-rails=) with Ruby on Rails
16
+ - Supports in-development [code reloading](Auto-reload-of-code-changes-in-development)
17
+ - Is powered by [librdkafka](https://github.com/edenhill/librdkafka) (the Apache Kafka C/C++ client library)
18
+ - Has an out-of the box [StatsD/DataDog monitoring](Monitoring-and-logging) with a dashboard template.
12
19
 
13
20
  ```ruby
14
21
  # Define what topics you want to consume with which consumers in karafka.rb
@@ -28,13 +35,11 @@ class EventsConsumer < ApplicationConsumer
28
35
  end
29
36
  ```
30
37
 
31
- Karafka allows you to capture everything that happens in your systems in large scale, providing you with a seamless and stable core for consuming, processing and producing data, without having to focus on things that are not your business domain.
32
-
33
- Karafka **uses** threads to handle many messages at the same time in the same process. It does not require Rails but will integrate tightly with any Ruby on Rails applications to make event processing dead simple.
38
+ Karafka **uses** threads to handle many messages simultaneously in the same process. It does not require Rails but will integrate tightly with any Ruby on Rails applications to make event processing dead simple.
34
39
 
35
40
  ## Getting started
36
41
 
37
- If you're completely new to the subject, you can start with our "Kafka on Rails" articles series, that will get you up and running with the terminology and basic ideas behind using Kafka:
42
+ If you're entirely new to the subject, you can start with our "Kafka on Rails" articles series, which will get you up and running with the terminology and basic ideas behind using Kafka:
38
43
 
39
44
  - [Kafka on Rails: Using Kafka with Ruby on Rails – Part 1 – Kafka basics and its advantages](https://mensfeld.pl/2017/11/kafka-on-rails-using-kafka-with-ruby-on-rails-part-1-kafka-basics-and-its-advantages/)
40
45
  - [Kafka on Rails: Using Kafka with Ruby on Rails – Part 2 – Getting started with Ruby and Kafka](https://mensfeld.pl/2018/01/kafka-on-rails-using-kafka-with-ruby-on-rails-part-2-getting-started-with-ruby-and-kafka/)
@@ -43,9 +48,38 @@ If you want to get started with Kafka and Karafka as fast as possible, then the
43
48
 
44
49
  We also maintain many [integration specs](https://github.com/karafka/karafka/tree/master/spec/integrations) illustrating various use-cases and features of the framework.
45
50
 
51
+ ### TL;DR (1 minute from setup to publishing and consuming messages)
52
+
53
+ **Prerequisites**: Kafka running. You can start it by following instructions from [here](https://github.com/karafka/karafka/wiki/Setting-up-Kafka).
54
+
55
+ 1. Add and install Karafka:
56
+
57
+ ```bash
58
+ bundle add karafka -v 2.0.0.rc2
59
+
60
+ bundle exec karafka install
61
+ ```
62
+
63
+ 2. Dispatch a message to the example topic using the Rails or Ruby console:
64
+
65
+ ```ruby
66
+ Karafka.producer.produce_sync(topic: 'example', payload: { 'ping' => 'pong' }.to_json)
67
+ ```
68
+
69
+ 3. Run Karafka server and see the consumption magic happen:
70
+
71
+ ```bash
72
+ bundle exec karafka server
73
+
74
+ [7616dc24-505a-417f-b87b-6bf8fc2d98c5] Polled 1 message in 1000ms
75
+ [dcf3a8d8-0bd9-433a-8f63-b70a0cdb0732] Consume job for ExampleConsumer on example started
76
+ {"ping"=>"pong"}
77
+ [dcf3a8d8-0bd9-433a-8f63-b70a0cdb0732] Consume job for ExampleConsumer on example finished in 0ms
78
+ ```
79
+
46
80
  ## Want to Upgrade? LGPL is not for you? Want to help?
47
81
 
48
- I also sell Karafka Pro subscription. It includes commercial-friendly license, priority support, architecture consultations and high throughput data processing-related features (under development).
82
+ I also sell Karafka Pro subscriptions. It includes a commercial-friendly license, priority support, architecture consultations, and high throughput data processing-related features (virtual partitions, long-running jobs, and more).
49
83
 
50
84
  **20%** of the income will be distributed back to other OSS projects that Karafka uses under the hood.
51
85
 
@@ -53,14 +87,8 @@ Help me provide high-quality open-source software. Please see the Karafka [homep
53
87
 
54
88
  ## Support
55
89
 
56
- Karafka has [Wiki pages](https://github.com/karafka/karafka/wiki) for almost everything and a pretty decent [FAQ](https://github.com/karafka/karafka/wiki/FAQ). It covers the whole installation, setup and deployment along with other useful details on how to run Karafka.
57
-
58
- If you have any questions about using Karafka, feel free to join our [Slack](https://slack.karafka.io) channel.
59
-
60
- ## Note on contributions
61
-
62
- First, thank you for considering contributing to the Karafka ecosystem! It's people like you that make the open source community such a great community!
90
+ Karafka has [Wiki pages](https://github.com/karafka/karafka/wiki) for almost everything and a pretty decent [FAQ](https://github.com/karafka/karafka/wiki/FAQ). It covers the installation, setup, and deployment, along with other useful details on how to run Karafka.
63
91
 
64
- Each pull request must pass all the RSpec specs, integration tests and meet our quality requirements.
92
+ If you have questions about using Karafka, feel free to join our [Slack](https://slack.karafka.io) channel.
65
93
 
66
- Fork it, update and wait for the Github Actions results.
94
+ Karafka has priority support for technical and architectural questions that is part of the Karafka Pro subscription.
data/bin/stress_many CHANGED
@@ -8,6 +8,6 @@ set -e
8
8
 
9
9
  while :
10
10
  do
11
- reset
11
+ clear
12
12
  bin/integrations $1
13
13
  done
data/bin/stress_one CHANGED
@@ -8,6 +8,6 @@ set -e
8
8
 
9
9
  while :
10
10
  do
11
- reset
11
+ clear
12
12
  bin/scenario $1
13
13
  done
data/config/errors.yml CHANGED
@@ -1,9 +1,56 @@
1
1
  en:
2
- dry_validation:
3
- errors:
2
+ validations:
3
+ config:
4
+ missing: needs to be present
5
+ client_id_format: 'needs to be a string with a Kafka accepted format'
6
+ license.entity_format: needs to be a string
7
+ license.token_format: needs to be either false or a string
8
+ license.expires_on_format: needs to be a valid date
9
+ concurrency_format: needs to be an integer bigger than 0
10
+ consumer_mapper_format: needs to be present
11
+ consumer_persistence_format: needs to be either true or false
12
+ pause_timeout_format: needs to be an integer bigger than 0
13
+ pause_max_timeout_format: needs to be an integer bigger than 0
14
+ pause_with_exponential_backoff_format: needs to be either true or false
15
+ shutdown_timeout_format: needs to be an integer bigger than 0
16
+ max_wait_time_format: needs to be an integer bigger than 0
17
+ kafka_format: needs to be a filled hash
18
+ internal.status_format: needs to be present
19
+ internal.process_format: needs to be present
20
+ internal.routing.builder_format: needs to be present
21
+ internal.routing.subscription_groups_builder_format: needs to be present
22
+ key_must_be_a_symbol: All keys under the kafka settings scope need to be symbols
4
23
  max_timeout_vs_pause_max_timeout: pause_timeout must be less or equal to pause_max_timeout
5
24
  shutdown_timeout_vs_max_wait_time: shutdown_timeout must be more than max_wait_time
6
- topics_names_not_unique: all topic names within a single consumer group must be unique
7
- required_usage_count: Given topic must be used at least once
25
+
26
+ server_cli_options:
27
+ missing: needs to be present
8
28
  consumer_groups_inclusion: Unknown consumer group
9
- kafka_key_must_be_a_symbol: All keys under the kafka settings scope need to be symbols
29
+
30
+ consumer_group_topic:
31
+ missing: needs to be present
32
+ name_format: 'needs to be a string with a Kafka accepted format'
33
+ deserializer_format: needs to be present
34
+ manual_offset_management_format: needs to be either true or false
35
+ consumer_format: needs to be present
36
+ id_format: 'needs to be a string with a Kafka accepted format'
37
+ initial_offset_format: needs to be either earliest or latest
38
+
39
+ consumer_group:
40
+ missing: needs to be present
41
+ topics_names_not_unique: all topic names within a single consumer group must be unique
42
+ id_format: 'needs to be a string with a Kafka accepted format'
43
+ topics_format: needs to be a non-empty array
44
+
45
+ job_options:
46
+ missing: needs to be present
47
+ dispatch_method_format: needs to be either :produce_async or :produce_sync
48
+ partitioner_format: 'needs to respond to #call'
49
+ partition_key_type_format: 'needs to be either :key or :partition_key'
50
+
51
+ test:
52
+ missing: needs to be present
53
+ id_format: needs to be a String
54
+
55
+ pro_consumer_group_topic:
56
+ consumer_format: needs to inherit from Karafka::Pro::BaseConsumer and not Karafka::Consumer
data/docker-compose.yml CHANGED
@@ -33,14 +33,21 @@ services:
33
33
  integrations_14_02:2:1,\
34
34
  integrations_15_02:2:1,\
35
35
  integrations_16_02:2:1,\
36
+ integrations_17_02:2:1,\
37
+ integrations_18_02:2:1,\
38
+ integrations_19_02:2:1,\
39
+ integrations_20_02:2:1,\
40
+ integrations_21_02:2:1,\
36
41
  integrations_00_03:3:1,\
37
42
  integrations_01_03:3:1,\
38
43
  integrations_02_03:3:1,\
39
44
  integrations_03_03:3:1,\
45
+ integrations_04_03:3:1,\
40
46
  integrations_00_10:10:1,\
41
47
  integrations_01_10:10:1,\
42
48
  benchmarks_00_01:1:1,\
43
49
  benchmarks_00_05:5:1,\
50
+ benchmarks_01_05:5:1,\
44
51
  benchmarks_00_10:10:1"
45
52
  volumes:
46
53
  - /var/run/docker.sock:/var/run/docker.sock
data/karafka.gemspec CHANGED
@@ -12,16 +12,14 @@ Gem::Specification.new do |spec|
12
12
  spec.authors = ['Maciej Mensfeld']
13
13
  spec.email = %w[maciej@mensfeld.pl]
14
14
  spec.homepage = 'https://karafka.io'
15
- spec.summary = 'Ruby based framework for working with Apache Kafka'
15
+ spec.summary = 'Efficient Kafka processing framework for Ruby and Rails '
16
16
  spec.description = 'Framework used to simplify Apache Kafka based Ruby applications development'
17
17
  spec.licenses = ['LGPL-3.0', 'Commercial']
18
18
 
19
- spec.add_dependency 'dry-configurable', '~> 0.13'
20
19
  spec.add_dependency 'dry-monitor', '~> 0.5'
21
- spec.add_dependency 'dry-validation', '~> 1.7'
22
20
  spec.add_dependency 'rdkafka', '>= 0.10'
23
21
  spec.add_dependency 'thor', '>= 0.20'
24
- spec.add_dependency 'waterdrop', '>= 2.3.1', '< 3.0.0'
22
+ spec.add_dependency 'waterdrop', '>= 2.3.3', '< 3.0.0'
25
23
  spec.add_dependency 'zeitwerk', '~> 2.3'
26
24
 
27
25
  spec.required_ruby_version = '>= 2.6.0'
@@ -9,6 +9,8 @@ module Karafka
9
9
  # @note ActiveJob does not support batches, so we just run one message after another
10
10
  def consume
11
11
  messages.each do |message|
12
+ break if Karafka::App.stopping?
13
+
12
14
  ::ActiveJob::Base.execute(
13
15
  # We technically speaking could set this as deserializer and reference it from the
14
16
  # message instead of using the `#raw_payload`. This is not done on purpose to simplify
@@ -7,9 +7,15 @@ module Karafka
7
7
  # we want to keep ActiveJob related Karafka components outside of the core Karafka code and
8
8
  # all in the same place
9
9
  class JobOptionsContract < Contracts::Base
10
- params do
11
- optional(:dispatch_method).value(included_in?: %i[produce_async produce_sync])
10
+ configure do |config|
11
+ config.error_messages = YAML.safe_load(
12
+ File.read(
13
+ File.join(Karafka.gem_root, 'config', 'errors.yml')
14
+ )
15
+ ).fetch('en').fetch('validations').fetch('job_options')
12
16
  end
17
+
18
+ optional(:dispatch_method) { |val| %i[produce_async produce_sync].include?(val) }
13
19
  end
14
20
  end
15
21
  end
@@ -35,9 +35,9 @@ module Karafka
35
35
  consume
36
36
  end
37
37
 
38
- @coordinator.consumption(self).success!
38
+ coordinator.consumption(self).success!
39
39
  rescue StandardError => e
40
- @coordinator.consumption(self).failure!
40
+ coordinator.consumption(self).failure!
41
41
 
42
42
  Karafka.monitor.instrument(
43
43
  'error.occurred',
@@ -47,7 +47,7 @@ module Karafka
47
47
  )
48
48
  ensure
49
49
  # We need to decrease number of jobs that this coordinator coordinates as it has finished
50
- @coordinator.decrement
50
+ coordinator.decrement
51
51
  end
52
52
 
53
53
  # @private
@@ -56,7 +56,7 @@ module Karafka
56
56
  def on_after_consume
57
57
  return if revoked?
58
58
 
59
- if @coordinator.success?
59
+ if coordinator.success?
60
60
  coordinator.pause_tracker.reset
61
61
 
62
62
  # Mark as consumed only if manual offset management is not on
@@ -76,8 +76,6 @@ module Karafka
76
76
  def on_revoked
77
77
  coordinator.revoke
78
78
 
79
- resume
80
-
81
79
  Karafka.monitor.instrument('consumer.revoked', caller: self) do
82
80
  revoked
83
81
  end
@@ -7,6 +7,8 @@ module Karafka
7
7
  class Cli < Thor
8
8
  # Install Karafka Cli action
9
9
  class Install < Base
10
+ include Helpers::Colorize
11
+
10
12
  desc 'Install all required things for Karafka application in current directory'
11
13
 
12
14
  # Directories created by default
@@ -42,14 +44,25 @@ module Karafka
42
44
  FileUtils.mkdir_p Karafka.root.join(dir)
43
45
  end
44
46
 
47
+ puts
48
+ puts 'Installing Karafka framework...'
49
+ puts 'Ruby on Rails detected...' if rails?
50
+ puts
51
+
45
52
  INSTALL_FILES_MAP.each do |source, target|
46
- target = Karafka.root.join(target)
53
+ pathed_target = Karafka.root.join(target)
47
54
 
48
55
  template = File.read(Karafka.core_root.join("templates/#{source}"))
49
56
  render = ::ERB.new(template, trim_mode: '-').result(binding)
50
57
 
51
- File.open(target, 'w') { |file| file.write(render) }
58
+ File.open(pathed_target, 'w') { |file| file.write(render) }
59
+
60
+ puts "#{green('Created')} #{target}"
52
61
  end
62
+
63
+ puts
64
+ puts("Installation #{green('completed')}. Have fun!")
65
+ puts
53
66
  end
54
67
 
55
68
  # @return [Boolean] true if we have Rails loaded
@@ -5,6 +5,8 @@ module Karafka
5
5
  class Cli < Thor
6
6
  # Server Karafka Cli action
7
7
  class Server < Base
8
+ include Helpers::Colorize
9
+
8
10
  desc 'Start the Karafka server (short-cut alias: "s")'
9
11
  option aliases: 's'
10
12
  option :consumer_groups, type: :array, default: nil, aliases: :g
@@ -31,11 +33,11 @@ module Karafka
31
33
 
32
34
  if Karafka.pro?
33
35
  Karafka.logger.info(
34
- "\033[0;32mThank you for investing in the Karafka Pro subscription!\033[0m\n"
36
+ green('Thank you for investing in the Karafka Pro subscription!')
35
37
  )
36
38
  else
37
39
  Karafka.logger.info(
38
- "\033[0;31mYou like Karafka? Please consider getting a Pro subscription!\033[0m\n"
40
+ red('You like Karafka? Please consider getting a Pro version!')
39
41
  )
40
42
  end
41
43
  end
@@ -69,9 +69,6 @@ module Karafka
69
69
  # Put a message to the buffer if there is one
70
70
  @buffer << message if message
71
71
 
72
- # Track time spent on all of the processing and polling
73
- time_poll.checkpoint
74
-
75
72
  # Upon polling rebalance manager might have been updated.
76
73
  # If partition revocation happens, we need to remove messages from revoked partitions
77
74
  # as well as ensure we do not have duplicated due to the offset reset for partitions
@@ -82,6 +79,9 @@ module Karafka
82
79
  break
83
80
  end
84
81
 
82
+ # Track time spent on all of the processing and polling
83
+ time_poll.checkpoint
84
+
85
85
  # Finally once we've (potentially) removed revoked, etc, if no messages were returned
86
86
  # we can break.
87
87
  # Worth keeping in mind, that the rebalance manager might have been updated despite no
@@ -268,7 +268,7 @@ module Karafka
268
268
  true
269
269
  rescue Rdkafka::RdkafkaError => e
270
270
  return false if e.code == :assignment_lost
271
- return false if e.code == :no_offset
271
+ return true if e.code == :no_offset
272
272
 
273
273
  raise e
274
274
  end
@@ -316,37 +316,40 @@ module Karafka
316
316
 
317
317
  time_poll.start
318
318
 
319
- @kafka.poll(time_poll.remaining)
319
+ @kafka.poll(timeout)
320
320
  rescue ::Rdkafka::RdkafkaError => e
321
- raise if time_poll.attempts > MAX_POLL_RETRIES
322
- raise unless time_poll.retryable?
323
-
321
+ # We return nil, so we do not restart until running the whole loop
322
+ # This allows us to run revocation jobs and other things and we will pick up new work
323
+ # next time after dispatching all the things that are needed
324
+ #
325
+ # If we would retry here, the client reset would become transparent and we would not have
326
+ # a chance to take any actions
324
327
  case e.code
325
328
  when :max_poll_exceeded # -147
326
329
  reset
330
+ return nil
327
331
  when :transport # -195
328
332
  reset
333
+ return nil
329
334
  when :rebalance_in_progress # -27
330
335
  reset
336
+ return nil
331
337
  when :not_coordinator # 16
332
338
  reset
339
+ return nil
333
340
  when :network_exception # 13
334
341
  reset
342
+ return nil
335
343
  end
336
344
 
337
- time_poll.checkpoint
338
-
345
+ raise if time_poll.attempts > MAX_POLL_RETRIES
339
346
  raise unless time_poll.retryable?
340
347
 
348
+ time_poll.checkpoint
341
349
  time_poll.backoff
342
350
 
343
- # We return nil, so we do not restart until running the whole loop
344
- # This allows us to run revocation jobs and other things and we will pick up new work
345
- # next time after dispatching all the things that are needed
346
- #
347
- # If we would retry here, the client reset would become transparent and we would not have
348
- # a chance to take any actions
349
- nil
351
+ # On unknown errors we do our best to retry and handle them before raising
352
+ retry
350
353
  end
351
354
 
352
355
  # Builds a new rdkafka consumer instance based on the subscription group configuration