karafka 2.4.8 → 2.4.9

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.
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