kaal 0.4.0 → 0.5.0
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 +4 -4
- data/README.md +36 -1
- data/lib/kaal/active_record_support.rb +2 -2
- data/lib/kaal/backend/adapter.rb +4 -0
- data/lib/kaal/backend/memory_adapter.rb +5 -0
- data/lib/kaal/backend/mysql.rb +25 -3
- data/lib/kaal/backend/postgres.rb +6 -2
- data/lib/kaal/backend/redis_adapter.rb +5 -0
- data/lib/kaal/backend/sqlite.rb +4 -0
- data/lib/kaal/cli.rb +1 -0
- data/lib/kaal/config/configuration.rb +33 -2
- data/lib/kaal/config/delayed_job_security_policy.rb +60 -0
- data/lib/kaal/config.rb +1 -0
- data/lib/kaal/core/coordinator.rb +68 -19
- data/lib/kaal/delayed_job/database_engine.rb +116 -0
- data/lib/kaal/delayed_job/dispatch_failure_logger.rb +31 -0
- data/lib/kaal/delayed_job/memory_engine.rb +79 -0
- data/lib/kaal/delayed_job/mysql_version_support.rb +43 -0
- data/lib/kaal/delayed_job/redis_engine.rb +119 -0
- data/lib/kaal/delayed_job/registry.rb +39 -0
- data/lib/kaal/internal/active_record/database_backend.rb +5 -0
- data/lib/kaal/internal/active_record/delayed_job_record.rb +16 -0
- data/lib/kaal/internal/active_record/delayed_job_registry.rb +119 -0
- data/lib/kaal/internal/active_record/migration_templates.rb +33 -3
- data/lib/kaal/internal/active_record/mysql_backend.rb +23 -5
- data/lib/kaal/internal/active_record/postgres_backend.rb +4 -0
- data/lib/kaal/internal/active_record.rb +2 -0
- data/lib/kaal/internal/sequel/database_backend.rb +5 -0
- data/lib/kaal/internal/sequel/mysql_backend.rb +15 -1
- data/lib/kaal/internal/sequel/postgres_backend.rb +4 -0
- data/lib/kaal/internal/sequel.rb +1 -0
- data/lib/kaal/job_dispatcher.rb +108 -0
- data/lib/kaal/persistence/database.rb +4 -0
- data/lib/kaal/persistence/migration_templates.rb +35 -3
- data/lib/kaal/runtime/scheduler_boot_loader.rb +2 -0
- data/lib/kaal/scheduler_file/job_applier.rb +28 -53
- data/lib/kaal/sequel_support.rb +2 -2
- data/lib/kaal/version.rb +1 -1
- data/lib/kaal.rb +111 -0
- metadata +11 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright Codevedas Inc. 2025-present
|
|
4
|
+
#
|
|
5
|
+
# This source code is licensed under the MIT license found in the
|
|
6
|
+
# LICENSE file in the root directory of this source tree.
|
|
7
|
+
module Kaal
|
|
8
|
+
# Shared job-class resolution and dispatch rules used by recurring and delayed jobs.
|
|
9
|
+
module JobDispatcher
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def resolve_job_class(job_class_name:, key:, queue: nil, apply_delayed_job_allow_list: true)
|
|
13
|
+
job_class = normalize_job_class(job_class_name, key, apply_delayed_job_allow_list:)
|
|
14
|
+
validate_dispatch_interface(job_class, key, queue)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def normalized_job_class_name(job_class_name:, key:, apply_delayed_job_allow_list: true)
|
|
18
|
+
normalized_job_class_name = normalize_job_class_name(job_class_name)
|
|
19
|
+
raise SchedulerConfigError, "Job class cannot be blank for key '#{key}'" if normalized_job_class_name.empty?
|
|
20
|
+
|
|
21
|
+
return normalized_job_class_name unless apply_delayed_job_allow_list
|
|
22
|
+
|
|
23
|
+
validate_allowed_job_class_name!(job_class_name: normalized_job_class_name, key:)
|
|
24
|
+
normalized_job_class_name
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def dispatch(job_class:, queue:, args:, key: nil)
|
|
28
|
+
job_class_name = job_class.name
|
|
29
|
+
scheduler_context = key ? " for scheduler job '#{key}'" : ''
|
|
30
|
+
|
|
31
|
+
if queue && !job_class.respond_to?(:set)
|
|
32
|
+
raise SchedulerConfigError,
|
|
33
|
+
"job_class '#{job_class_name}' must respond to .set to use queue #{queue.inspect}#{scheduler_context}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if queue
|
|
37
|
+
job_class.set(queue: queue).perform_later(*args)
|
|
38
|
+
elsif job_class.respond_to?(:perform_later)
|
|
39
|
+
job_class.perform_later(*args)
|
|
40
|
+
elsif job_class.respond_to?(:perform)
|
|
41
|
+
job_class.perform(*args)
|
|
42
|
+
else
|
|
43
|
+
raise SchedulerConfigError,
|
|
44
|
+
"job_class '#{job_class_name}' must respond to .perform, .perform_later, or .set(...).perform_later#{scheduler_context}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def active_job_dispatch?(job_class, queue)
|
|
49
|
+
(queue && job_class.respond_to?(:set)) || job_class.respond_to?(:perform_later)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def normalize_job_class_name(job_class)
|
|
53
|
+
case job_class
|
|
54
|
+
when Module
|
|
55
|
+
job_class.name.to_s.strip
|
|
56
|
+
else
|
|
57
|
+
job_class.to_s.strip
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def normalize_job_class(job_class_name, key, apply_delayed_job_allow_list: true)
|
|
62
|
+
normalized_job_class_name = normalized_job_class_name(
|
|
63
|
+
job_class_name:,
|
|
64
|
+
key:,
|
|
65
|
+
apply_delayed_job_allow_list:
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return job_class_name if job_class_name.is_a?(Module)
|
|
69
|
+
|
|
70
|
+
job_class = begin
|
|
71
|
+
Kaal::Support::HashTools.constantize(normalized_job_class_name)
|
|
72
|
+
rescue NameError
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
return job_class if job_class
|
|
77
|
+
|
|
78
|
+
raise SchedulerConfigError, "Unknown job_class #{normalized_job_class_name.inspect} for key '#{key}'"
|
|
79
|
+
end
|
|
80
|
+
private_class_method :normalize_job_class
|
|
81
|
+
|
|
82
|
+
def validate_allowed_job_class_name!(job_class_name:, key:)
|
|
83
|
+
allowed_prefixes = Array(Kaal.configuration.delayed_job_allowed_class_prefixes)
|
|
84
|
+
return if allowed_prefixes.empty?
|
|
85
|
+
return if allowed_prefixes.any? { |prefix| job_class_name.start_with?(prefix) }
|
|
86
|
+
|
|
87
|
+
raise SchedulerConfigError,
|
|
88
|
+
"job_class '#{job_class_name}' for key '#{key}' is not allowed by delayed_job_allowed_class_prefixes"
|
|
89
|
+
end
|
|
90
|
+
private_class_method :validate_allowed_job_class_name!
|
|
91
|
+
|
|
92
|
+
def validate_dispatch_interface(job_class, key, queue)
|
|
93
|
+
queue_present = !queue.nil?
|
|
94
|
+
no_queue = !queue_present
|
|
95
|
+
supports_set = job_class.respond_to?(:set)
|
|
96
|
+
supports_perform_later = job_class.respond_to?(:perform_later)
|
|
97
|
+
supports_perform = job_class.respond_to?(:perform)
|
|
98
|
+
|
|
99
|
+
return job_class if queue_present && supports_set
|
|
100
|
+
return job_class if no_queue && supports_perform_later
|
|
101
|
+
return job_class if no_queue && supports_perform
|
|
102
|
+
|
|
103
|
+
raise SchedulerConfigError,
|
|
104
|
+
"job_class '#{job_class.name}' for key '#{key}' must respond to .perform, .perform_later, or .set(...).perform_later"
|
|
105
|
+
end
|
|
106
|
+
private_class_method :validate_dispatch_interface
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -11,17 +11,21 @@ module Kaal
|
|
|
11
11
|
module_function
|
|
12
12
|
|
|
13
13
|
def for_backend(backend)
|
|
14
|
-
|
|
14
|
+
backend_name = backend.to_s
|
|
15
|
+
|
|
16
|
+
case backend_name
|
|
15
17
|
when 'sqlite'
|
|
16
18
|
{
|
|
17
19
|
'001_create_kaal_dispatches.rb' => dispatches_template,
|
|
18
20
|
'002_create_kaal_locks.rb' => locks_template,
|
|
19
|
-
'003_create_kaal_definitions.rb' => definitions_template
|
|
21
|
+
'003_create_kaal_definitions.rb' => definitions_template,
|
|
22
|
+
'004_create_kaal_delayed_jobs.rb' => delayed_jobs_template('sqlite')
|
|
20
23
|
}
|
|
21
24
|
when 'postgres', 'mysql'
|
|
22
25
|
{
|
|
23
26
|
'001_create_kaal_dispatches.rb' => dispatches_template,
|
|
24
|
-
'002_create_kaal_definitions.rb' => definitions_template
|
|
27
|
+
'002_create_kaal_definitions.rb' => definitions_template,
|
|
28
|
+
'003_create_kaal_delayed_jobs.rb' => delayed_jobs_template(backend_name)
|
|
25
29
|
}
|
|
26
30
|
else
|
|
27
31
|
{}
|
|
@@ -92,6 +96,34 @@ module Kaal
|
|
|
92
96
|
end
|
|
93
97
|
RUBY
|
|
94
98
|
end
|
|
99
|
+
|
|
100
|
+
def delayed_jobs_template(backend)
|
|
101
|
+
args_definition =
|
|
102
|
+
if backend == 'mysql'
|
|
103
|
+
'String :args, text: true, null: false'
|
|
104
|
+
else
|
|
105
|
+
"String :args, text: true, null: false, default: '[]'"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
<<~RUBY
|
|
109
|
+
Sequel.migration do
|
|
110
|
+
change do
|
|
111
|
+
create_table?(:kaal_delayed_jobs) do
|
|
112
|
+
primary_key :id
|
|
113
|
+
String :job_id, null: false
|
|
114
|
+
Time :run_at, null: false
|
|
115
|
+
String :job_class, null: false
|
|
116
|
+
#{args_definition}
|
|
117
|
+
String :queue
|
|
118
|
+
Time :created_at, null: false
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
add_index :kaal_delayed_jobs, :job_id, unique: true
|
|
122
|
+
add_index :kaal_delayed_jobs, :run_at
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
RUBY
|
|
126
|
+
end
|
|
95
127
|
end
|
|
96
128
|
end
|
|
97
129
|
end
|
|
@@ -22,6 +22,8 @@ module Kaal
|
|
|
22
22
|
configuration = fetch_configuration
|
|
23
23
|
return unless configuration
|
|
24
24
|
|
|
25
|
+
Kaal.warn_on_risky_configuration!(configuration:, logger: @logger)
|
|
26
|
+
|
|
25
27
|
return load_scheduler_file if configuration.scheduler_missing_file_policy == :error
|
|
26
28
|
|
|
27
29
|
scheduler_path = configuration.scheduler_config_path.to_s.strip
|
|
@@ -77,7 +77,12 @@ module Kaal
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def resolved_job_class(job_class_name:, key:, queue: nil)
|
|
80
|
-
resolve_job_class(
|
|
80
|
+
Kaal::JobDispatcher.resolve_job_class(
|
|
81
|
+
job_class_name:,
|
|
82
|
+
key:,
|
|
83
|
+
queue:,
|
|
84
|
+
apply_delayed_job_allow_list: false
|
|
85
|
+
)
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
def conflict?(key:, existing_definition:)
|
|
@@ -157,7 +162,7 @@ module Kaal
|
|
|
157
162
|
validate_keyword_keys(raw_kwargs, key)
|
|
158
163
|
|
|
159
164
|
resolved_kwargs = raw_kwargs.transform_keys(&:to_sym)
|
|
160
|
-
dispatch_job(job_class, queue, resolved_args, resolved_kwargs)
|
|
165
|
+
dispatch_job(job_class, queue, resolved_args, resolved_kwargs, key)
|
|
161
166
|
end
|
|
162
167
|
end
|
|
163
168
|
|
|
@@ -178,64 +183,34 @@ module Kaal
|
|
|
178
183
|
nil
|
|
179
184
|
end
|
|
180
185
|
|
|
181
|
-
|
|
182
|
-
normalized_job_class_name = job_class_name.to_s.strip
|
|
183
|
-
raise SchedulerConfigError, "Job class cannot be blank for key '#{key}'" if normalized_job_class_name.empty?
|
|
184
|
-
|
|
185
|
-
error_message = "Unknown job_class #{normalized_job_class_name.inspect} for key '#{key}'"
|
|
186
|
-
job_class = begin
|
|
187
|
-
Kaal::Support::HashTools.constantize(normalized_job_class_name)
|
|
188
|
-
rescue NameError
|
|
189
|
-
nil
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
return validate_dispatch_interface(job_class, key, queue) if job_class
|
|
193
|
-
|
|
194
|
-
raise_unknown_job_class(error_message)
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
private :build_callback, :resolve_job_class
|
|
198
|
-
|
|
199
|
-
def dispatch_job(job_class, queue, args, kwargs)
|
|
200
|
-
job_class_name = job_class.name
|
|
201
|
-
|
|
202
|
-
if queue && !job_class.respond_to?(:set)
|
|
203
|
-
raise SchedulerConfigError,
|
|
204
|
-
"job_class '#{job_class_name}' must respond to .set to use queue #{queue.inspect}"
|
|
205
|
-
end
|
|
186
|
+
private :build_callback
|
|
206
187
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
job_class.perform_later(*args, **kwargs)
|
|
211
|
-
elsif job_class.respond_to?(:perform)
|
|
212
|
-
job_class.perform(*args, **kwargs)
|
|
188
|
+
def dispatch_job(job_class, queue, args, kwargs, key)
|
|
189
|
+
if kwargs.empty?
|
|
190
|
+
Kaal::JobDispatcher.dispatch(job_class:, queue:, args:, key:)
|
|
213
191
|
else
|
|
214
|
-
|
|
215
|
-
"job_class '#{job_class_name}' must respond to .perform, .perform_later, or .set(...).perform_later"
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def raise_unknown_job_class(error_message)
|
|
220
|
-
raise SchedulerConfigError, error_message
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def validate_dispatch_interface(job_class, key, queue)
|
|
224
|
-
queue_present = !queue.nil?
|
|
225
|
-
supports_set = job_class.respond_to?(:set)
|
|
226
|
-
supports_perform_later = job_class.respond_to?(:perform_later)
|
|
227
|
-
supports_perform = job_class.respond_to?(:perform)
|
|
192
|
+
job_class_name = job_class.name
|
|
228
193
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
194
|
+
if queue && !job_class.respond_to?(:set)
|
|
195
|
+
raise SchedulerConfigError,
|
|
196
|
+
"job_class '#{job_class_name}' must respond to .set to use queue #{queue.inspect} for scheduler job '#{key}'"
|
|
197
|
+
end
|
|
232
198
|
|
|
233
|
-
|
|
234
|
-
|
|
199
|
+
if queue
|
|
200
|
+
job_class.set(queue: queue).perform_later(*args, **kwargs)
|
|
201
|
+
elsif job_class.respond_to?(:perform_later)
|
|
202
|
+
job_class.perform_later(*args, **kwargs)
|
|
203
|
+
elsif job_class.respond_to?(:perform)
|
|
204
|
+
job_class.perform(*args, **kwargs)
|
|
205
|
+
else
|
|
206
|
+
raise SchedulerConfigError,
|
|
207
|
+
"job_class '#{job_class_name}' must respond to .perform, .perform_later, or .set(...).perform_later for scheduler job '#{key}'"
|
|
208
|
+
end
|
|
209
|
+
end
|
|
235
210
|
end
|
|
236
211
|
|
|
237
212
|
def active_job_dispatch?(job_class, queue)
|
|
238
|
-
|
|
213
|
+
Kaal::JobDispatcher.active_job_dispatch?(job_class, queue)
|
|
239
214
|
end
|
|
240
215
|
end
|
|
241
216
|
end
|
data/lib/kaal/sequel_support.rb
CHANGED
|
@@ -62,9 +62,9 @@ module Kaal
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def migration_suffixes_for(backend)
|
|
65
|
-
return %w[dispatches locks definitions] if backend.to_s == 'sqlite'
|
|
65
|
+
return %w[dispatches locks definitions delayed_jobs] if backend.to_s == 'sqlite'
|
|
66
66
|
|
|
67
|
-
%w[dispatches definitions]
|
|
67
|
+
%w[dispatches definitions delayed_jobs]
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def timestamp(offset = 0)
|
data/lib/kaal/version.rb
CHANGED
data/lib/kaal.rb
CHANGED
|
@@ -10,6 +10,11 @@ require 'kaal/registry'
|
|
|
10
10
|
require 'kaal/dispatch/registry'
|
|
11
11
|
require 'kaal/dispatch/memory_engine'
|
|
12
12
|
require 'kaal/dispatch/redis_engine'
|
|
13
|
+
require 'kaal/delayed_job/registry'
|
|
14
|
+
require 'kaal/delayed_job/memory_engine'
|
|
15
|
+
require 'kaal/delayed_job/redis_engine'
|
|
16
|
+
require 'kaal/delayed_job/dispatch_failure_logger'
|
|
17
|
+
require 'kaal/delayed_job/mysql_version_support'
|
|
13
18
|
require 'kaal/definition/registry'
|
|
14
19
|
require 'kaal/definition/memory_engine'
|
|
15
20
|
require 'kaal/definition/redis_engine'
|
|
@@ -25,6 +30,7 @@ require 'kaal/persistence/migration_templates'
|
|
|
25
30
|
require 'kaal/sequel_support'
|
|
26
31
|
require 'kaal/active_record_support'
|
|
27
32
|
require 'kaal/utils'
|
|
33
|
+
require 'kaal/job_dispatcher'
|
|
28
34
|
require 'kaal/register_conflict_support'
|
|
29
35
|
require 'kaal/definitions/registry_accessor'
|
|
30
36
|
require 'kaal/definitions/registration_service'
|
|
@@ -56,12 +62,15 @@ module Kaal
|
|
|
56
62
|
@definition_registry = nil
|
|
57
63
|
@definitions_registry_accessor = nil
|
|
58
64
|
@dispatch_registry_accessor = nil
|
|
65
|
+
@risky_configuration_warnings_emitted = {}
|
|
59
66
|
end
|
|
60
67
|
|
|
61
68
|
def reset_registry!
|
|
62
69
|
@registry = Registry.new
|
|
63
70
|
definition_registry = @definition_registry
|
|
64
71
|
definition_registry.clear if definition_registry.respond_to?(:clear)
|
|
72
|
+
delayed_store = configuration.backend&.delayed_store
|
|
73
|
+
delayed_store.clear if delayed_store.respond_to?(:clear)
|
|
65
74
|
@coordinator = nil
|
|
66
75
|
end
|
|
67
76
|
|
|
@@ -84,6 +93,7 @@ module Kaal
|
|
|
84
93
|
end
|
|
85
94
|
|
|
86
95
|
def load_scheduler_file!(runtime_context: RuntimeContext.default)
|
|
96
|
+
warn_on_risky_configuration!
|
|
87
97
|
SchedulerFileLoader.new(
|
|
88
98
|
configuration: configuration,
|
|
89
99
|
definition_registry: definition_registry,
|
|
@@ -119,6 +129,7 @@ module Kaal
|
|
|
119
129
|
end
|
|
120
130
|
|
|
121
131
|
def start!
|
|
132
|
+
warn_on_risky_configuration!
|
|
122
133
|
coordinator.start!
|
|
123
134
|
end
|
|
124
135
|
|
|
@@ -138,6 +149,30 @@ module Kaal
|
|
|
138
149
|
coordinator.tick!
|
|
139
150
|
end
|
|
140
151
|
|
|
152
|
+
# Enqueue a one-off delayed job. Delivery is at-most-once after claim.
|
|
153
|
+
def enqueue_at(at:, job_class:, args:, job_id:, queue: nil, connection: nil)
|
|
154
|
+
delayed_store = delayed_store!
|
|
155
|
+
resolved_run_at = normalize_delayed_run_at(at)
|
|
156
|
+
resolved_args = normalize_delayed_args(args)
|
|
157
|
+
resolved_queue = normalize_delayed_queue(queue)
|
|
158
|
+
resolved_job_id = normalize_delayed_job_id(job_id)
|
|
159
|
+
resolved_job_class = JobDispatcher.resolve_job_class(
|
|
160
|
+
job_class_name: job_class,
|
|
161
|
+
key: resolved_job_id,
|
|
162
|
+
queue: resolved_queue
|
|
163
|
+
)
|
|
164
|
+
resolved_job_class_name = JobDispatcher.normalize_job_class_name(resolved_job_class)
|
|
165
|
+
|
|
166
|
+
delayed_store.enqueue(
|
|
167
|
+
job_id: resolved_job_id,
|
|
168
|
+
run_at: resolved_run_at,
|
|
169
|
+
job_class: resolved_job_class_name,
|
|
170
|
+
args: resolved_args,
|
|
171
|
+
queue: resolved_queue,
|
|
172
|
+
connection: connection
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
|
|
141
176
|
def with_idempotency(key, fire_time)
|
|
142
177
|
raise ArgumentError, 'block required' unless block_given?
|
|
143
178
|
|
|
@@ -193,6 +228,14 @@ module Kaal
|
|
|
193
228
|
configuration.time_zone = value
|
|
194
229
|
end
|
|
195
230
|
|
|
231
|
+
def delayed_job_allowed_class_prefixes
|
|
232
|
+
configuration.delayed_job_allowed_class_prefixes
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def delayed_job_allowed_class_prefixes=(value)
|
|
236
|
+
configuration.delayed_job_allowed_class_prefixes = value
|
|
237
|
+
end
|
|
238
|
+
|
|
196
239
|
def definition_registry
|
|
197
240
|
definitions_registry_accessor.call
|
|
198
241
|
end
|
|
@@ -205,6 +248,25 @@ module Kaal
|
|
|
205
248
|
configuration.validate!
|
|
206
249
|
end
|
|
207
250
|
|
|
251
|
+
def validation_warnings
|
|
252
|
+
configuration.validation_warnings
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def warn_on_risky_configuration!(configuration: self.configuration, logger: configuration.logger)
|
|
256
|
+
warnings = configuration.validation_warnings
|
|
257
|
+
return [] if warnings.empty?
|
|
258
|
+
|
|
259
|
+
@risky_configuration_warnings_emitted ||= {}
|
|
260
|
+
warnings.each do |warning|
|
|
261
|
+
next if @risky_configuration_warnings_emitted[warning]
|
|
262
|
+
|
|
263
|
+
logger&.warn(warning)
|
|
264
|
+
@risky_configuration_warnings_emitted[warning] = true
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
warnings
|
|
268
|
+
end
|
|
269
|
+
|
|
208
270
|
def valid?(expression)
|
|
209
271
|
CronUtils.valid?(expression)
|
|
210
272
|
end
|
|
@@ -253,5 +315,54 @@ module Kaal
|
|
|
253
315
|
def dispatch_registry_accessor
|
|
254
316
|
@dispatch_registry_accessor ||= Backend::DispatchRegistryAccessor.new(configuration: configuration)
|
|
255
317
|
end
|
|
318
|
+
|
|
319
|
+
def delayed_store!
|
|
320
|
+
delayed_store = configuration.backend&.delayed_store
|
|
321
|
+
return delayed_store if delayed_store
|
|
322
|
+
|
|
323
|
+
raise ArgumentError, 'Configured backend does not support delayed jobs'
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def normalize_delayed_run_at(at)
|
|
327
|
+
time = at.is_a?(Time) ? at : at&.to_time
|
|
328
|
+
ensure_delayed_time!(time)
|
|
329
|
+
|
|
330
|
+
time.utc
|
|
331
|
+
rescue NoMethodError
|
|
332
|
+
ensure_delayed_time!(nil)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def normalize_delayed_args(args)
|
|
336
|
+
raise ArgumentError, 'args must be an array' unless args.is_a?(Array)
|
|
337
|
+
|
|
338
|
+
args.dup
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def normalize_delayed_queue(queue)
|
|
342
|
+
case queue
|
|
343
|
+
when nil
|
|
344
|
+
return nil
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
normalized_queue = queue.to_s.strip
|
|
348
|
+
raise ArgumentError, 'queue cannot be blank' if normalized_queue.empty?
|
|
349
|
+
|
|
350
|
+
normalized_queue
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def normalize_delayed_job_id(job_id)
|
|
354
|
+
normalized_job_id = job_id.to_s.strip
|
|
355
|
+
raise ArgumentError, 'job_id cannot be blank' if normalized_job_id.empty?
|
|
356
|
+
|
|
357
|
+
normalized_job_id
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def invalid_delayed_time_error
|
|
361
|
+
ArgumentError.new('at must be a Time or time-like value')
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def ensure_delayed_time!(time)
|
|
365
|
+
raise invalid_delayed_time_error unless time
|
|
366
|
+
end
|
|
256
367
|
end
|
|
257
368
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kaal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nitesh Purohit
|
|
@@ -97,6 +97,7 @@ files:
|
|
|
97
97
|
- lib/kaal/cli.rb
|
|
98
98
|
- lib/kaal/config.rb
|
|
99
99
|
- lib/kaal/config/configuration.rb
|
|
100
|
+
- lib/kaal/config/delayed_job_security_policy.rb
|
|
100
101
|
- lib/kaal/config/scheduler_config_error.rb
|
|
101
102
|
- lib/kaal/config/scheduler_time_zone_resolver.rb
|
|
102
103
|
- lib/kaal/core.rb
|
|
@@ -110,6 +111,12 @@ files:
|
|
|
110
111
|
- lib/kaal/definition/registry.rb
|
|
111
112
|
- lib/kaal/definitions/registration_service.rb
|
|
112
113
|
- lib/kaal/definitions/registry_accessor.rb
|
|
114
|
+
- lib/kaal/delayed_job/database_engine.rb
|
|
115
|
+
- lib/kaal/delayed_job/dispatch_failure_logger.rb
|
|
116
|
+
- lib/kaal/delayed_job/memory_engine.rb
|
|
117
|
+
- lib/kaal/delayed_job/mysql_version_support.rb
|
|
118
|
+
- lib/kaal/delayed_job/redis_engine.rb
|
|
119
|
+
- lib/kaal/delayed_job/registry.rb
|
|
113
120
|
- lib/kaal/dispatch/database_engine.rb
|
|
114
121
|
- lib/kaal/dispatch/memory_engine.rb
|
|
115
122
|
- lib/kaal/dispatch/redis_engine.rb
|
|
@@ -120,6 +127,8 @@ files:
|
|
|
120
127
|
- lib/kaal/internal/active_record/database_backend.rb
|
|
121
128
|
- lib/kaal/internal/active_record/definition_record.rb
|
|
122
129
|
- lib/kaal/internal/active_record/definition_registry.rb
|
|
130
|
+
- lib/kaal/internal/active_record/delayed_job_record.rb
|
|
131
|
+
- lib/kaal/internal/active_record/delayed_job_registry.rb
|
|
123
132
|
- lib/kaal/internal/active_record/dispatch_record.rb
|
|
124
133
|
- lib/kaal/internal/active_record/dispatch_registry.rb
|
|
125
134
|
- lib/kaal/internal/active_record/lock_record.rb
|
|
@@ -130,6 +139,7 @@ files:
|
|
|
130
139
|
- lib/kaal/internal/sequel/database_backend.rb
|
|
131
140
|
- lib/kaal/internal/sequel/mysql_backend.rb
|
|
132
141
|
- lib/kaal/internal/sequel/postgres_backend.rb
|
|
142
|
+
- lib/kaal/job_dispatcher.rb
|
|
133
143
|
- lib/kaal/persistence/database.rb
|
|
134
144
|
- lib/kaal/persistence/migration_templates.rb
|
|
135
145
|
- lib/kaal/register_conflict_support.rb
|