karafka 2.4.8 → 2.4.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ci.yml +0 -1
  4. data/CHANGELOG.md +8 -0
  5. data/Gemfile +8 -5
  6. data/Gemfile.lock +23 -14
  7. data/bin/integrations +5 -0
  8. data/certs/cert.pem +26 -0
  9. data/config/locales/errors.yml +4 -0
  10. data/config/locales/pro_errors.yml +17 -0
  11. data/karafka.gemspec +1 -1
  12. data/lib/karafka/admin.rb +42 -0
  13. data/lib/karafka/contracts/config.rb +2 -0
  14. data/lib/karafka/errors.rb +3 -2
  15. data/lib/karafka/pro/loader.rb +2 -1
  16. data/lib/karafka/pro/processing/strategies/dlq/default.rb +16 -1
  17. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +5 -1
  18. data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +17 -1
  19. data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +17 -1
  20. data/lib/karafka/pro/processing/strategies/dlq/mom.rb +22 -6
  21. data/lib/karafka/pro/recurring_tasks/consumer.rb +105 -0
  22. data/lib/karafka/pro/recurring_tasks/contracts/config.rb +53 -0
  23. data/lib/karafka/pro/recurring_tasks/contracts/task.rb +41 -0
  24. data/lib/karafka/pro/recurring_tasks/deserializer.rb +35 -0
  25. data/lib/karafka/pro/recurring_tasks/dispatcher.rb +87 -0
  26. data/lib/karafka/pro/recurring_tasks/errors.rb +34 -0
  27. data/lib/karafka/pro/recurring_tasks/executor.rb +152 -0
  28. data/lib/karafka/pro/recurring_tasks/listener.rb +38 -0
  29. data/lib/karafka/pro/recurring_tasks/matcher.rb +38 -0
  30. data/lib/karafka/pro/recurring_tasks/schedule.rb +63 -0
  31. data/lib/karafka/pro/recurring_tasks/serializer.rb +113 -0
  32. data/lib/karafka/pro/recurring_tasks/setup/config.rb +52 -0
  33. data/lib/karafka/pro/recurring_tasks/task.rb +151 -0
  34. data/lib/karafka/pro/recurring_tasks.rb +87 -0
  35. data/lib/karafka/pro/routing/features/recurring_tasks/builder.rb +130 -0
  36. data/lib/karafka/pro/routing/features/recurring_tasks/config.rb +28 -0
  37. data/lib/karafka/pro/routing/features/recurring_tasks/contracts/topic.rb +40 -0
  38. data/lib/karafka/pro/routing/features/recurring_tasks/proxy.rb +27 -0
  39. data/lib/karafka/pro/routing/features/recurring_tasks/topic.rb +44 -0
  40. data/lib/karafka/pro/routing/features/recurring_tasks.rb +25 -0
  41. data/lib/karafka/processing/strategies/dlq.rb +16 -2
  42. data/lib/karafka/processing/strategies/dlq_mom.rb +25 -6
  43. data/lib/karafka/processing/worker.rb +11 -1
  44. data/lib/karafka/railtie.rb +11 -22
  45. data/lib/karafka/routing/features/dead_letter_queue/config.rb +3 -0
  46. data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +1 -0
  47. data/lib/karafka/routing/features/dead_letter_queue/topic.rb +7 -2
  48. data/lib/karafka/routing/features/eofed/contracts/topic.rb +12 -0
  49. data/lib/karafka/routing/topic.rb +14 -0
  50. data/lib/karafka/setup/config.rb +3 -0
  51. data/lib/karafka/version.rb +1 -1
  52. data.tar.gz.sig +0 -0
  53. metadata +44 -24
  54. metadata.gz.sig +0 -0
  55. data/certs/cert_chain.pem +0 -26
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Recurring Tasks related contracts
18
+ module Contracts
19
+ # Ensures that task details are as expected
20
+ class Task < ::Karafka::Contracts::Base
21
+ configure do |config|
22
+ config.error_messages = YAML.safe_load(
23
+ File.read(
24
+ File.join(Karafka.gem_root, 'config', 'locales', 'pro_errors.yml')
25
+ )
26
+ ).fetch('en').fetch('validations').fetch('recurring_tasks')
27
+ end
28
+
29
+ # Regexp to ensure all tasks ids are URL safe
30
+ ID_REGEXP = /\A[a-zA-Z0-9_-]{1,}\z/
31
+
32
+ required(:id) { |val| val.is_a?(String) && val.match?(ID_REGEXP) }
33
+ required(:cron) { |val| val.is_a?(String) && val.length.positive? }
34
+ required(:enabled) { |val| [true, false].include?(val) }
35
+ required(:changed) { |val| [true, false].include?(val) }
36
+ required(:previous_time) { |val| val.is_a?(Numeric) || val.is_a?(Time) }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Recurring Tasks data deserializer. We compress data ourselves because we cannot rely on
18
+ # any external optional features like certain compression types, etc. By doing this that way
19
+ # we can ensure we have full control over the compression.
20
+ #
21
+ # @note We use `symbolize_names` because we want to use the same convention of hash building
22
+ # for producing, consuming and displaying related data as in other places.
23
+ class Deserializer
24
+ # @param message [::Karafka::Messages::Message]
25
+ # @return [Hash] deserialized data
26
+ def call(message)
27
+ ::JSON.parse(
28
+ Zlib::Inflate.inflate(message.raw_payload),
29
+ symbolize_names: true
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Dispatches appropriate recurring tasks related messages to expected topics
18
+ class Dispatcher
19
+ class << self
20
+ # Snapshots to Kafka current schedule state
21
+ def schedule
22
+ produce(
23
+ topics.schedules,
24
+ 'state:schedule',
25
+ serializer.schedule(::Karafka::Pro::RecurringTasks.schedule)
26
+ )
27
+ end
28
+
29
+ # Dispatches the command request
30
+ #
31
+ # @param name [String, Symbol] name of the command we want to deal with in the process
32
+ # @param task_id [String] id of the process. We use name instead of id only
33
+ # because in the web ui we work with the full name and it is easier. Since
34
+ def command(name, task_id)
35
+ produce(
36
+ topics.schedules,
37
+ "command:#{name}:#{task_id}",
38
+ serializer.command(name, task_id)
39
+ )
40
+ end
41
+
42
+ # Dispatches the task execution log record
43
+ # @param event [Karafka::Core::Monitoring::Event]
44
+ def log(event)
45
+ produce(
46
+ topics.logs,
47
+ event[:task].id,
48
+ serializer.log(event)
49
+ )
50
+ end
51
+
52
+ private
53
+
54
+ # @return [::WaterDrop::Producer] web ui producer
55
+ def producer
56
+ ::Karafka::App.config.recurring_tasks.producer
57
+ end
58
+
59
+ # @return [String] consumers commands topic
60
+ def topics
61
+ ::Karafka::App.config.recurring_tasks.topics
62
+ end
63
+
64
+ # @return [Serializer]
65
+ def serializer
66
+ Serializer.new
67
+ end
68
+
69
+ # Converts payload to json, compresses it and dispatches to Kafka
70
+ #
71
+ # @param topic [String] target topic
72
+ # @param key [String]
73
+ # @param payload [Hash] hash with payload
74
+ def produce(topic, key, payload)
75
+ producer.produce_async(
76
+ topic: topic,
77
+ key: key,
78
+ partition: 0,
79
+ payload: payload,
80
+ headers: { 'zlib' => 'true' }
81
+ )
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Recurring Tasks related errors
18
+ module Errors
19
+ # Base for all the recurring tasks errors
20
+ BaseError = Class.new(::Karafka::Errors::BaseError)
21
+
22
+ # Raised when older cron manager version is trying to work with newer schema
23
+ IncompatibleSchemaError = Class.new(BaseError)
24
+
25
+ # Raised if you use versioned schedule and an existing schedule from Kafka was picked up
26
+ # by a process with older schedule version.
27
+ # This is a safe-guard to protect against a cases where there would be a temporary
28
+ # reassignment of newer schedule data into older process during deployment. It should go
29
+ # away once all processes are rolled.
30
+ IncompatibleScheduleError = Class.new(BaseError)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Executor is responsible for management of the state of recurring tasks schedule and
18
+ # is the heart of recurring tasks. It coordinates the replaying process as well as
19
+ # tracking of data on changes.
20
+ class Executor
21
+ # Task commands we support and that can be triggered on tasks (if matched)
22
+ COMMANDS = %w[
23
+ disable
24
+ enable
25
+ trigger
26
+ ].freeze
27
+
28
+ def initialize
29
+ @replaying = true
30
+ @incompatible = false
31
+ @catchup_commands = []
32
+ @catchup_schedule = nil
33
+ @matcher = Matcher.new
34
+ end
35
+
36
+ # @return [Boolean] are we in the replaying phase or not (false means, regular operations)
37
+ def replaying?
38
+ @replaying
39
+ end
40
+
41
+ # @return [Boolean] Is the current process schedule incompatible (older) than the one
42
+ # that we have in memory
43
+ def incompatible?
44
+ @incompatible
45
+ end
46
+
47
+ # Applies given command to task (or many tasks) by running the command on tasks that match
48
+ # @param command_hash [Hash] deserialized command data
49
+ def apply_command(command_hash)
50
+ cmd_name = command_hash[:command][:name]
51
+
52
+ raise(Karafka::Errors::UnsupportedCaseError, cmd_name) unless COMMANDS.include?(cmd_name)
53
+
54
+ schedule.each do |task|
55
+ next unless @matcher.matches?(task, command_hash)
56
+
57
+ task.public_send(cmd_name)
58
+ end
59
+ end
60
+
61
+ # Updates the catchup state
62
+ # @param schedule_hash [Hash] deserialized schedule hash hash
63
+ def update_state(schedule_hash)
64
+ @catchup_schedule = schedule_hash
65
+ end
66
+
67
+ # Once all previous data is accumulated runs the catchup process to establish current
68
+ # state of the recurring tasks schedule execution.
69
+ #
70
+ # It includes applying any requested commands as well as synchronizing execution details
71
+ # for existing schedule and making sure all is loaded correctly.
72
+ def replay
73
+ # Ensure replaying happens only once
74
+ return unless @replaying
75
+
76
+ @replaying = false
77
+
78
+ # When there is nothing to replay and synchronize, we can just save the state and
79
+ # proceed
80
+ if @catchup_commands.empty? && @catchup_schedule.nil?
81
+ snapshot
82
+
83
+ return
84
+ end
85
+
86
+ # If the schedule version we have in Kafka is higher than ours, we cannot proceed
87
+ # This prevents us from applying older changes to a new schedule
88
+ if @catchup_schedule[:schedule_version] > schedule.version
89
+ @incompatible = true
90
+
91
+ return
92
+ end
93
+
94
+ # Now we can synchronize the in-memory state based on the last state stored in Kafka
95
+ schedule.each do |task|
96
+ stored_task = @catchup_schedule[:tasks][task.id.to_sym]
97
+
98
+ next unless stored_task
99
+
100
+ stored_previous_time = stored_task[:previous_time]
101
+ task.previous_time = stored_previous_time.zero? ? 0 : Time.at(stored_previous_time)
102
+
103
+ stored_task[:enabled] ? task.enable : task.disable
104
+ end
105
+
106
+ @catchup_commands.each do |cmd|
107
+ apply_command(cmd)
108
+ end
109
+
110
+ # We make sure to save in Kafka once more once everything is up to date
111
+ snapshot
112
+
113
+ @catchup_schedule = nil
114
+ @catchup_commands = []
115
+ end
116
+
117
+ # Run all tasks that should run at a given time and if any tasks were changed in any way
118
+ # or executed, stores the most recent state back to Kafka
119
+ def call
120
+ changed = false
121
+
122
+ schedule.each do |task|
123
+ changed = true if task.changed?
124
+
125
+ unless task.call?
126
+ task.clear
127
+
128
+ next
129
+ end
130
+
131
+ changed = true
132
+ task.call
133
+ end
134
+
135
+ snapshot if changed
136
+ end
137
+
138
+ private
139
+
140
+ # @return [Karafka::Pro::RecurringTasks::Schedule] current in-memory schedule
141
+ def schedule
142
+ ::Karafka::Pro::RecurringTasks.schedule
143
+ end
144
+
145
+ # Dispatches the current schedule state to Kafka
146
+ def snapshot
147
+ Dispatcher.schedule
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Listener we use to track execution of recurring tasks and publish those events into the
18
+ # recurring tasks log table
19
+ class Listener
20
+ # @param event [Karafka::Core::Monitoring::Event] task execution event
21
+ def on_recurring_tasks_task_executed(event)
22
+ Dispatcher.log(event)
23
+ end
24
+
25
+ # @param event [Karafka::Core::Monitoring::Event] error that occurred
26
+ # @note We do nothing with other errors. We only want to log and dispatch information about
27
+ # the recurring tasks errors. The general Web UI error tracking may also work but those
28
+ # are independent. It is not to replace the Web UI tracking but to just log failed
29
+ # executions in the same way as successful but just with the failure as an outcome.
30
+ def on_error_occurred(event)
31
+ return unless event[:type] == 'recurring_tasks.task.execute.error'
32
+
33
+ Dispatcher.log(event)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Matcher used to check if given command can be applied to a given task.
18
+ class Matcher
19
+ # @param task [Karafka::Pro::RecurringTasks::Task]
20
+ # @param payload [Hash] command message payload
21
+ # @return [Boolean] is this message dedicated to current process and is actionable
22
+ def matches?(task, payload)
23
+ # We only match commands
24
+ return false unless payload[:type] == 'command'
25
+
26
+ # * is a wildcard to match all for batch commands
27
+ return false unless payload[:task][:id] == '*' || payload[:task][:id] == task.id
28
+
29
+ # Ignore messages that have different schema. This can happen in the middle of
30
+ # upgrades of the framework. We ignore this not to risk compatibility issues
31
+ return false unless payload[:schema_version] == Serializer::SCHEMA_VERSION
32
+
33
+ true
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Represents the current code-context schedule with defined tasks and their cron execution
18
+ # details. Single schedule includes all the information about all the tasks that we have
19
+ # defined and to be executed in a given moment in time.
20
+ class Schedule
21
+ # @return [String]
22
+ attr_reader :version
23
+
24
+ # @return [Hash<String, Task>]
25
+ attr_reader :tasks
26
+
27
+ # @param version [String] schedule version. In case of usage of versioning it is used to
28
+ # ensure, that older still active processes do not intercept the assignment to run older
29
+ # version of the scheduler. It is important to make sure, that this string is comparable.
30
+ def initialize(version:)
31
+ @version = version
32
+ @tasks = {}
33
+ end
34
+
35
+ # Adds task into the tasks accumulator
36
+ # @param task [Task]
37
+ # @note In case of multiple tasks with the same id, it will overwrite
38
+ def <<(task)
39
+ @tasks[task.id] = task
40
+ end
41
+
42
+ # Iterates over tasks yielding them one after another
43
+ # @param block [Proc] block that will be executed with each task
44
+ def each(&block)
45
+ @tasks.each_value(&block)
46
+ end
47
+
48
+ # @param id [String] id of a particular recurring task
49
+ # @return [Task, nil] task with a given id or nil if not found
50
+ def find(id)
51
+ @tasks[id]
52
+ end
53
+
54
+ # Allows us to have a nice DSL for defining schedules
55
+ # @param args [Array] attributes accepted by the task initializer
56
+ # @param block [Proc] block to execute
57
+ def schedule(**args, &block)
58
+ self << Task.new(**args, &block)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Converts schedule command and log details into data we can dispatch to Kafka.
18
+ class Serializer
19
+ # Current recurring tasks related schema structure
20
+ SCHEMA_VERSION = '1.0'
21
+
22
+ # @param schedule [Karafka::Pro::RecurringTasks::Schedule] schedule to serialize
23
+ # @return [String] serialized and compressed current schedule data with its tasks and their
24
+ # current state.
25
+ def schedule(schedule)
26
+ tasks = {}
27
+
28
+ schedule.each do |task|
29
+ tasks[task.id] = {
30
+ id: task.id,
31
+ cron: task.cron.original,
32
+ previous_time: task.previous_time.to_i,
33
+ next_time: task.next_time.to_i,
34
+ enabled: task.enabled?
35
+ }
36
+ end
37
+
38
+ data = {
39
+ schema_version: SCHEMA_VERSION,
40
+ schedule_version: schedule.version,
41
+ dispatched_at: Time.now.to_f,
42
+ type: 'schedule',
43
+ tasks: tasks
44
+ }
45
+
46
+ compress(
47
+ serialize(data)
48
+ )
49
+ end
50
+
51
+ # @param command_name [String] command name
52
+ # @param task_id [String] task id or '*' to match all.
53
+ # @return [String] serialized and compressed command data
54
+ def command(command_name, task_id)
55
+ data = {
56
+ schema_version: SCHEMA_VERSION,
57
+ schedule_version: ::Karafka::Pro::RecurringTasks.schedule.version,
58
+ dispatched_at: Time.now.to_f,
59
+ type: 'command',
60
+ command: {
61
+ name: command_name
62
+ },
63
+ task: {
64
+ id: task_id
65
+ }
66
+ }
67
+
68
+ compress(
69
+ serialize(data)
70
+ )
71
+ end
72
+
73
+ # @param event [Karafka::Core::Monitoring::Event] recurring task dispatch event
74
+ # @return [String] serialized and compressed event log data
75
+ def log(event)
76
+ task = event[:task]
77
+
78
+ data = {
79
+ schema_version: SCHEMA_VERSION,
80
+ schedule_version: ::Karafka::Pro::RecurringTasks.schedule.version,
81
+ dispatched_at: Time.now.to_f,
82
+ type: 'log',
83
+ task: {
84
+ id: task.id,
85
+ time_taken: event.payload[:time] || -1,
86
+ result: event.payload.key?(:error) ? 'failure' : 'success'
87
+ }
88
+ }
89
+
90
+ compress(
91
+ serialize(data)
92
+ )
93
+ end
94
+
95
+ private
96
+
97
+ # @param hash [Hash] hash to cast to json
98
+ # @return [String] json hash
99
+ def serialize(hash)
100
+ hash.to_json
101
+ end
102
+
103
+ # Compresses the provided data
104
+ #
105
+ # @param data [String] data to compress
106
+ # @return [String] compressed data
107
+ def compress(data)
108
+ Zlib::Deflate.deflate(data)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module RecurringTasks
17
+ # Setup and config related recurring tasks components
18
+ module Setup
19
+ # Config for recurring tasks
20
+ class Config
21
+ extend ::Karafka::Core::Configurable
22
+
23
+ setting(:consumer_class, default: Consumer)
24
+ setting(:deserializer, default: Deserializer.new)
25
+ setting(:group_id, default: 'karafka_recurring_tasks')
26
+ # By default we will run the scheduling every 15 seconds since we provide a minute-based
27
+ # precision
28
+ setting(:interval, default: 15_000)
29
+ # Should we log the executions. If true (default) with each cron execution, there will
30
+ # be a special message published. Useful for debugging.
31
+ setting(:logging, default: true)
32
+
33
+ # Producer to be used by the recurring tasks.
34
+ # By default it is a `Karafka.producer`, however it may be overwritten if we want to use
35
+ # a separate instance in case of heavy usage of the transactional producer, etc.
36
+ setting(
37
+ :producer,
38
+ constructor: -> { ::Karafka.producer },
39
+ lazy: true
40
+ )
41
+
42
+ setting(:topics) do
43
+ setting(:schedules, default: 'karafka_recurring_tasks_schedules')
44
+ setting(:logs, default: 'karafka_recurring_tasks_logs')
45
+ end
46
+
47
+ configure
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end