sidekiq-cron 1.4.0 → 1.8.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/{Changes.md → CHANGELOG.md} +33 -5
- data/README.md +32 -46
- data/lib/sidekiq/cron/job.rb +108 -99
- data/lib/sidekiq/cron/launcher.rb +15 -13
- data/lib/sidekiq/cron/locales/it.yml +23 -0
- data/lib/sidekiq/cron/locales/pt.yml +22 -0
- data/lib/sidekiq/cron/poller.rb +16 -8
- data/lib/sidekiq/cron/schedule_loader.rb +22 -0
- data/lib/sidekiq/cron/support.rb +0 -1
- data/lib/sidekiq/cron/version.rb +1 -1
- data/lib/sidekiq/cron/views/cron.erb +1 -1
- data/lib/sidekiq/cron/web_extension.rb +6 -9
- data/lib/sidekiq/cron.rb +1 -0
- data/lib/sidekiq/options.rb +18 -0
- data/sidekiq-cron.gemspec +13 -15
- data/test/integration/performance_test.rb +1 -1
- data/test/test_helper.rb +1 -0
- data/test/unit/fixtures/schedule_array.yml +13 -0
- data/test/unit/fixtures/schedule_hash.yml +12 -0
- data/test/unit/fixtures/schedule_string.yml +1 -0
- data/test/unit/job_test.rb +125 -21
- data/test/unit/launcher_test.rb +33 -0
- data/test/unit/poller_test.rb +6 -6
- data/test/unit/schedule_loader_test.rb +45 -0
- data/test/unit/web_extension_test.rb +2 -2
- metadata +37 -27
data/lib/sidekiq/cron/job.rb
CHANGED
@@ -1,23 +1,21 @@
|
|
1
1
|
require 'fugit'
|
2
2
|
require 'sidekiq'
|
3
|
-
require 'sidekiq/util'
|
4
3
|
require 'sidekiq/cron/support'
|
4
|
+
require 'sidekiq/options'
|
5
5
|
|
6
6
|
module Sidekiq
|
7
7
|
module Cron
|
8
|
-
|
9
8
|
class Job
|
10
|
-
|
11
|
-
extend Util
|
12
|
-
|
13
|
-
#how long we would like to store informations about previous enqueues
|
9
|
+
# How long we would like to store informations about previous enqueues.
|
14
10
|
REMEMBER_THRESHOLD = 24 * 60 * 60
|
11
|
+
|
12
|
+
# Time format for enqueued jobs.
|
15
13
|
LAST_ENQUEUE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S %z'
|
16
14
|
|
17
|
-
# Use the exists? method if we're on a newer version of
|
15
|
+
# Use the exists? method if we're on a newer version of Redis.
|
18
16
|
REDIS_EXISTS_METHOD = Gem.loaded_specs['redis'].version < Gem::Version.new('4.2') ? :exists : :exists?
|
19
17
|
|
20
|
-
#
|
18
|
+
# Crucial part of whole enqueuing job.
|
21
19
|
def should_enque? time
|
22
20
|
enqueue = false
|
23
21
|
enqueue = Sidekiq.redis do |conn|
|
@@ -29,18 +27,16 @@ module Sidekiq
|
|
29
27
|
enqueue
|
30
28
|
end
|
31
29
|
|
32
|
-
#
|
33
|
-
# this will clear
|
34
|
-
# not overflow with memory
|
30
|
+
# Remove previous information about run times,
|
31
|
+
# this will clear Redis and make sure that Redis will not overflow with memory.
|
35
32
|
def remove_previous_enques time
|
36
33
|
Sidekiq.redis do |conn|
|
37
34
|
conn.zremrangebyscore(job_enqueued_key, 0, "(#{(time.to_f - REMEMBER_THRESHOLD).to_s}")
|
38
35
|
end
|
39
36
|
end
|
40
37
|
|
41
|
-
#
|
38
|
+
# Test if job should be enqueued.
|
42
39
|
def test_and_enque_for_time! time
|
43
|
-
#should this job be enqued?
|
44
40
|
if should_enque?(time)
|
45
41
|
enque!
|
46
42
|
|
@@ -48,7 +44,7 @@ module Sidekiq
|
|
48
44
|
end
|
49
45
|
end
|
50
46
|
|
51
|
-
#
|
47
|
+
# Enqueue cron job to queue.
|
52
48
|
def enque! time = Time.now.utc
|
53
49
|
@last_enqueue_time = time.strftime(LAST_ENQUEUE_TIME_FORMAT)
|
54
50
|
|
@@ -76,7 +72,7 @@ module Sidekiq
|
|
76
72
|
|
77
73
|
save_last_enqueue_time
|
78
74
|
add_jid_history jid
|
79
|
-
logger.debug { "enqueued #{@name}: #{@message}" }
|
75
|
+
Sidekiq.logger.debug { "enqueued #{@name}: #{@message}" }
|
80
76
|
end
|
81
77
|
|
82
78
|
def is_active_job?
|
@@ -85,17 +81,27 @@ module Sidekiq
|
|
85
81
|
false
|
86
82
|
end
|
87
83
|
|
84
|
+
def date_as_argument?
|
85
|
+
!!@date_as_argument
|
86
|
+
end
|
87
|
+
|
88
|
+
def enqueue_args
|
89
|
+
date_as_argument? ? @args + [Time.now.to_f] : @args
|
90
|
+
end
|
91
|
+
|
88
92
|
def enqueue_active_job(klass_const)
|
89
|
-
klass_const.set(queue: @queue).perform_later(
|
93
|
+
klass_const.set(queue: @queue).perform_later(*enqueue_args)
|
90
94
|
end
|
91
95
|
|
92
96
|
def enqueue_sidekiq_worker(klass_const)
|
93
|
-
klass_const.set(queue: queue_name_with_prefix).perform_async(
|
97
|
+
klass_const.set(queue: queue_name_with_prefix).perform_async(*enqueue_args)
|
94
98
|
end
|
95
99
|
|
96
|
-
#
|
100
|
+
# Sidekiq worker message.
|
97
101
|
def sidekiq_worker_message
|
98
|
-
@message.is_a?(String) ? Sidekiq.load_json(@message) : @message
|
102
|
+
message = @message.is_a?(String) ? Sidekiq.load_json(@message) : @message
|
103
|
+
message["args"] = enqueue_args
|
104
|
+
message
|
99
105
|
end
|
100
106
|
|
101
107
|
def queue_name_with_prefix
|
@@ -120,8 +126,8 @@ module Sidekiq
|
|
120
126
|
queue_name
|
121
127
|
end
|
122
128
|
|
123
|
-
#
|
124
|
-
# queue, it
|
129
|
+
# Active Job has different structure how it is loading data from Sidekiq
|
130
|
+
# queue, it creates a wrapper around job.
|
125
131
|
def active_job_message
|
126
132
|
{
|
127
133
|
'class' => 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper',
|
@@ -132,13 +138,13 @@ module Sidekiq
|
|
132
138
|
'job_class' => @klass,
|
133
139
|
'job_id' => SecureRandom.uuid,
|
134
140
|
'queue_name' => @queue_name_with_prefix,
|
135
|
-
'arguments' =>
|
141
|
+
'arguments' => enqueue_args
|
136
142
|
}]
|
137
143
|
}
|
138
144
|
end
|
139
145
|
|
140
|
-
#
|
141
|
-
#
|
146
|
+
# Load cron jobs from Hash.
|
147
|
+
# Input structure should look like:
|
142
148
|
# {
|
143
149
|
# 'name_of_job' => {
|
144
150
|
# 'class' => 'MyClass',
|
@@ -160,15 +166,15 @@ module Sidekiq
|
|
160
166
|
load_from_array array
|
161
167
|
end
|
162
168
|
|
163
|
-
#
|
164
|
-
# If exists old jobs in
|
169
|
+
# Like #load_from_hash.
|
170
|
+
# If exists old jobs in Redis but removed from args, destroy old jobs.
|
165
171
|
def self.load_from_hash! hash
|
166
172
|
destroy_removed_jobs(hash.keys)
|
167
173
|
load_from_hash(hash)
|
168
174
|
end
|
169
175
|
|
170
|
-
#
|
171
|
-
#
|
176
|
+
# Load cron jobs from Array.
|
177
|
+
# Input structure should look like:
|
172
178
|
# [
|
173
179
|
# {
|
174
180
|
# 'name' => 'name_of_job',
|
@@ -193,15 +199,15 @@ module Sidekiq
|
|
193
199
|
errors
|
194
200
|
end
|
195
201
|
|
196
|
-
#
|
197
|
-
# If exists old jobs in
|
202
|
+
# Like #load_from_array.
|
203
|
+
# If exists old jobs in Redis but removed from args, destroy old jobs.
|
198
204
|
def self.load_from_array! array
|
199
205
|
job_names = array.map { |job| job["name"] }
|
200
206
|
destroy_removed_jobs(job_names)
|
201
207
|
load_from_array(array)
|
202
208
|
end
|
203
209
|
|
204
|
-
#
|
210
|
+
# Get all cron jobs.
|
205
211
|
def self.all
|
206
212
|
job_hashes = nil
|
207
213
|
Sidekiq.redis do |conn|
|
@@ -213,7 +219,7 @@ module Sidekiq
|
|
213
219
|
end
|
214
220
|
end
|
215
221
|
job_hashes.compact.reject(&:empty?).collect do |h|
|
216
|
-
#
|
222
|
+
# No need to fetch missing args from Redis since we just got this hash from there
|
217
223
|
Sidekiq::Cron::Job.new(h.merge(fetch_missing_args: false))
|
218
224
|
end
|
219
225
|
end
|
@@ -227,7 +233,7 @@ module Sidekiq
|
|
227
233
|
end
|
228
234
|
|
229
235
|
def self.find name
|
230
|
-
#
|
236
|
+
# If name is hash try to get name from it.
|
231
237
|
name = name[:name] || name['name'] if name.is_a?(Hash)
|
232
238
|
|
233
239
|
output = nil
|
@@ -239,14 +245,14 @@ module Sidekiq
|
|
239
245
|
output if output && output.valid?
|
240
246
|
end
|
241
247
|
|
242
|
-
#
|
248
|
+
# Create new instance of cron job.
|
243
249
|
def self.create hash
|
244
250
|
new(hash).save
|
245
251
|
end
|
246
252
|
|
247
|
-
#
|
253
|
+
# Destroy job by name.
|
248
254
|
def self.destroy name
|
249
|
-
#
|
255
|
+
# If name is hash try to get name from it.
|
250
256
|
name = name[:name] || name['name'] if name.is_a?(Hash)
|
251
257
|
|
252
258
|
if job = find(name)
|
@@ -268,23 +274,24 @@ module Sidekiq
|
|
268
274
|
@cron = args["cron"]
|
269
275
|
@description = args["description"] if args["description"]
|
270
276
|
|
271
|
-
#
|
277
|
+
# Get class from klass or class.
|
272
278
|
@klass = args["klass"] || args["class"]
|
273
279
|
|
274
|
-
#
|
280
|
+
# Set status of job.
|
275
281
|
@status = args['status'] || status_from_redis
|
276
282
|
|
277
|
-
#
|
283
|
+
# Set last enqueue time - from args or from existing job.
|
278
284
|
if args['last_enqueue_time'] && !args['last_enqueue_time'].empty?
|
279
285
|
@last_enqueue_time = parse_enqueue_time(args['last_enqueue_time'])
|
280
286
|
else
|
281
287
|
@last_enqueue_time = last_enqueue_time_from_redis
|
282
288
|
end
|
283
289
|
|
284
|
-
#
|
290
|
+
# Get right arguments for job.
|
285
291
|
@symbolize_args = args["symbolize_args"] == true || ("#{args["symbolize_args"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
|
286
292
|
@args = args["args"].nil? ? [] : parse_args( args["args"] )
|
287
|
-
|
293
|
+
|
294
|
+
@date_as_argument = args["date_as_argument"] == true || ("#{args["date_as_argument"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
|
288
295
|
|
289
296
|
@active_job = args["active_job"] == true || ("#{args["active_job"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
|
290
297
|
@active_job_queue_name_prefix = args["queue_name_prefix"]
|
@@ -300,8 +307,8 @@ module Sidekiq
|
|
300
307
|
"args" => @args,
|
301
308
|
}
|
302
309
|
|
303
|
-
#
|
304
|
-
#only if message wasn't specified before
|
310
|
+
# Get right data for message,
|
311
|
+
# only if message wasn't specified before.
|
305
312
|
klass_data = case @klass
|
306
313
|
when Class
|
307
314
|
@klass.get_sidekiq_options
|
@@ -309,21 +316,21 @@ module Sidekiq
|
|
309
316
|
begin
|
310
317
|
Sidekiq::Cron::Support.constantize(@klass).get_sidekiq_options
|
311
318
|
rescue Exception => e
|
312
|
-
#Unknown class
|
319
|
+
# Unknown class
|
313
320
|
{"queue"=>"default"}
|
314
321
|
end
|
315
322
|
end
|
316
323
|
|
317
324
|
message_data = klass_data.merge(message_data)
|
318
|
-
|
319
|
-
#
|
325
|
+
|
326
|
+
# Override queue if setted in config,
|
327
|
+
# only if message is hash - can be string (dumped JSON).
|
320
328
|
if args['queue']
|
321
329
|
@queue = message_data['queue'] = args['queue']
|
322
330
|
else
|
323
331
|
@queue = message_data['queue'] || "default"
|
324
332
|
end
|
325
333
|
|
326
|
-
#dump message as json
|
327
334
|
@message = message_data
|
328
335
|
end
|
329
336
|
|
@@ -385,13 +392,12 @@ module Sidekiq
|
|
385
392
|
conn.lrange(jid_history_key, 0, -1) rescue nil
|
386
393
|
end
|
387
394
|
|
388
|
-
# returns nil if out nil
|
389
395
|
out && out.map do |jid_history_raw|
|
390
396
|
Sidekiq.load_json jid_history_raw
|
391
397
|
end
|
392
398
|
end
|
393
399
|
|
394
|
-
#
|
400
|
+
# Export job data to hash.
|
395
401
|
def to_hash
|
396
402
|
{
|
397
403
|
name: @name,
|
@@ -399,6 +405,7 @@ module Sidekiq
|
|
399
405
|
cron: @cron,
|
400
406
|
description: @description,
|
401
407
|
args: @args.is_a?(String) ? @args : Sidekiq.dump_json(@args || []),
|
408
|
+
date_as_argument: @date_as_argument,
|
402
409
|
message: @message.is_a?(String) ? @message : Sidekiq.dump_json(@message || {}),
|
403
410
|
status: @status,
|
404
411
|
active_job: @active_job,
|
@@ -414,7 +421,7 @@ module Sidekiq
|
|
414
421
|
end
|
415
422
|
|
416
423
|
def valid?
|
417
|
-
#
|
424
|
+
# Clear previous errors.
|
418
425
|
@errors = []
|
419
426
|
|
420
427
|
errors << "'name' must be set" if @name.nil? || @name.size == 0
|
@@ -422,7 +429,15 @@ module Sidekiq
|
|
422
429
|
errors << "'cron' must be set"
|
423
430
|
else
|
424
431
|
begin
|
425
|
-
|
432
|
+
c = Fugit.do_parse(@cron)
|
433
|
+
|
434
|
+
# Since `Fugit.do_parse` might yield a Fugit::Duration or an EtOrbi::EoTime
|
435
|
+
# https://github.com/floraison/fugit#fugitparses
|
436
|
+
if c.is_a?(Fugit::Cron)
|
437
|
+
@parsed_cron = c
|
438
|
+
else
|
439
|
+
errors << "'cron' -> #{@cron.inspect} -> not a cron but a #{c.class}"
|
440
|
+
end
|
426
441
|
rescue => e
|
427
442
|
errors << "'cron' -> #{@cron.inspect} -> #{e.class}: #{e.message}"
|
428
443
|
end
|
@@ -443,37 +458,28 @@ module Sidekiq
|
|
443
458
|
end
|
444
459
|
end
|
445
460
|
|
446
|
-
# add job to cron jobs
|
447
|
-
# input:
|
448
|
-
# name: (string) - name of job
|
449
|
-
# cron: (string: '* * * * *' - cron specification when to run job
|
450
|
-
# class: (string|class) - which class to perform
|
451
|
-
# optional input:
|
452
|
-
# queue: (string) - which queue to use for enquing (will override class queue)
|
453
|
-
# args: (array|hash|nil) - arguments for permorm method
|
454
|
-
|
455
461
|
def save
|
456
|
-
#
|
462
|
+
# If job is invalid, return false.
|
457
463
|
return false unless valid?
|
458
464
|
|
459
465
|
Sidekiq.redis do |conn|
|
460
466
|
|
461
|
-
#
|
462
|
-
conn.sadd self.class.jobs_key, redis_key
|
467
|
+
# Add to set of all jobs
|
468
|
+
conn.sadd self.class.jobs_key, [redis_key]
|
463
469
|
|
464
|
-
#
|
470
|
+
# Add informations for this job!
|
465
471
|
conn.hmset redis_key, *hash_to_redis(to_hash)
|
466
472
|
|
467
|
-
#
|
473
|
+
# Add information about last time! - don't enque right after scheduler poller starts!
|
468
474
|
time = Time.now.utc
|
469
475
|
conn.zadd(job_enqueued_key, time.to_f.to_s, formated_last_time(time).to_s) unless conn.public_send(REDIS_EXISTS_METHOD, job_enqueued_key)
|
470
476
|
end
|
471
|
-
logger.info { "Cron Jobs - added job with name: #{@name}" }
|
477
|
+
Sidekiq.logger.info { "Cron Jobs - added job with name: #{@name}" }
|
472
478
|
end
|
473
479
|
|
474
480
|
def save_last_enqueue_time
|
475
481
|
Sidekiq.redis do |conn|
|
476
|
-
#
|
482
|
+
# Update last enqueue time.
|
477
483
|
conn.hset redis_key, 'last_enqueue_time', @last_enqueue_time
|
478
484
|
end
|
479
485
|
end
|
@@ -483,44 +489,43 @@ module Sidekiq
|
|
483
489
|
jid: jid,
|
484
490
|
enqueued: @last_enqueue_time
|
485
491
|
}
|
486
|
-
|
492
|
+
|
493
|
+
@history_size ||= (Sidekiq::Options[:cron_history_size] || 10).to_i - 1
|
487
494
|
Sidekiq.redis do |conn|
|
488
495
|
conn.lpush jid_history_key,
|
489
496
|
Sidekiq.dump_json(jid_history)
|
490
|
-
#
|
497
|
+
# Keep only last 10 entries in a fifo manner.
|
491
498
|
conn.ltrim jid_history_key, 0, @history_size
|
492
499
|
end
|
493
500
|
end
|
494
501
|
|
495
|
-
# remove job from cron jobs by name
|
496
|
-
# input:
|
497
|
-
# first arg: name (string) - name of job (must be same - case sensitive)
|
498
502
|
def destroy
|
499
503
|
Sidekiq.redis do |conn|
|
500
|
-
#
|
501
|
-
conn.srem self.class.jobs_key, redis_key
|
504
|
+
# Delete from set.
|
505
|
+
conn.srem self.class.jobs_key, [redis_key]
|
502
506
|
|
503
|
-
#
|
507
|
+
# Delete runned timestamps.
|
504
508
|
conn.del job_enqueued_key
|
505
509
|
|
506
|
-
#
|
510
|
+
# Delete jid_history.
|
507
511
|
conn.del jid_history_key
|
508
512
|
|
509
|
-
#
|
513
|
+
# Delete main job.
|
510
514
|
conn.del redis_key
|
511
515
|
end
|
512
|
-
|
516
|
+
|
517
|
+
Sidekiq.logger.info { "Cron Jobs - deleted job with name: #{@name}" }
|
513
518
|
end
|
514
519
|
|
515
|
-
#
|
520
|
+
# Remove all job from cron.
|
516
521
|
def self.destroy_all!
|
517
522
|
all.each do |job|
|
518
523
|
job.destroy
|
519
524
|
end
|
520
|
-
logger.info { "Cron Jobs - deleted all jobs" }
|
525
|
+
Sidekiq.logger.info { "Cron Jobs - deleted all jobs" }
|
521
526
|
end
|
522
527
|
|
523
|
-
#
|
528
|
+
# Remove "removed jobs" between current jobs and new jobs
|
524
529
|
def self.destroy_removed_jobs new_job_names
|
525
530
|
current_job_names = Sidekiq::Cron::Job.all.map(&:name)
|
526
531
|
removed_job_names = current_job_names - new_job_names
|
@@ -561,7 +566,19 @@ module Sidekiq
|
|
561
566
|
private
|
562
567
|
|
563
568
|
def parsed_cron
|
564
|
-
@parsed_cron ||=
|
569
|
+
@parsed_cron ||= begin
|
570
|
+
c = Fugit.parse(@cron)
|
571
|
+
|
572
|
+
# Since `Fugit.parse` might yield a Fugit::Duration or an EtOrbi::EoTime
|
573
|
+
# https://github.com/floraison/fugit#fugitparses
|
574
|
+
if c.is_a?(Fugit::Cron)
|
575
|
+
c
|
576
|
+
else
|
577
|
+
errors << "'cron' -> #{@cron.inspect} -> not a cron but a #{c.class}"
|
578
|
+
end
|
579
|
+
rescue => e
|
580
|
+
errors << "'cron' -> #{@cron.inspect} -> #{e.class}: #{e.message}"
|
581
|
+
end
|
565
582
|
end
|
566
583
|
|
567
584
|
def not_enqueued_after?(time)
|
@@ -569,9 +586,8 @@ module Sidekiq
|
|
569
586
|
end
|
570
587
|
|
571
588
|
# Try parsing inbound args into an array.
|
572
|
-
#
|
573
|
-
# try to load JSON, then failover
|
574
|
-
# to string array.
|
589
|
+
# Args from Redis will be encoded JSON,
|
590
|
+
# try to load JSON, then failover to string array.
|
575
591
|
def parse_args(args)
|
576
592
|
case args
|
577
593
|
when String
|
@@ -579,14 +595,14 @@ module Sidekiq
|
|
579
595
|
parsed_args = Sidekiq.load_json(args)
|
580
596
|
symbolize_args? ? symbolize_args(parsed_args) : parsed_args
|
581
597
|
rescue JSON::ParserError
|
582
|
-
[*args]
|
598
|
+
[*args]
|
583
599
|
end
|
584
600
|
when Hash
|
585
601
|
symbolize_args? ? [symbolize_args(args)] : [args]
|
586
602
|
when Array
|
587
603
|
symbolize_args? ? symbolize_args(args) : args
|
588
604
|
else
|
589
|
-
[*args]
|
605
|
+
[*args]
|
590
606
|
end
|
591
607
|
end
|
592
608
|
|
@@ -618,29 +634,26 @@ module Sidekiq
|
|
618
634
|
|
619
635
|
def not_past_scheduled_time?(current_time)
|
620
636
|
last_cron_time = parsed_cron.previous_time(current_time).utc
|
621
|
-
# or could it be?
|
622
|
-
#last_cron_time = last_time(current_time)
|
623
637
|
return false if (current_time.to_i - last_cron_time.to_i) > 60
|
624
638
|
true
|
625
639
|
end
|
626
640
|
|
627
|
-
# Redis key for set of all cron jobs
|
641
|
+
# Redis key for set of all cron jobs.
|
628
642
|
def self.jobs_key
|
629
643
|
"cron_jobs"
|
630
644
|
end
|
631
645
|
|
632
|
-
# Redis key for storing one cron job
|
646
|
+
# Redis key for storing one cron job.
|
633
647
|
def self.redis_key name
|
634
648
|
"cron_job:#{name}"
|
635
649
|
end
|
636
650
|
|
637
|
-
# Redis key for storing one cron job
|
651
|
+
# Redis key for storing one cron job.
|
638
652
|
def redis_key
|
639
653
|
self.class.redis_key @name
|
640
654
|
end
|
641
655
|
|
642
|
-
# Redis key for storing one cron job run times
|
643
|
-
# (when poller added job to queue)
|
656
|
+
# Redis key for storing one cron job run times (when poller added job to queue)
|
644
657
|
def self.job_enqueued_key name
|
645
658
|
"cron_job:#{name}:enqueued"
|
646
659
|
end
|
@@ -649,8 +662,6 @@ module Sidekiq
|
|
649
662
|
"cron_job:#{name}:jid_history"
|
650
663
|
end
|
651
664
|
|
652
|
-
# Redis key for storing one cron job run times
|
653
|
-
# (when poller added job to queue)
|
654
665
|
def job_enqueued_key
|
655
666
|
self.class.job_enqueued_key @name
|
656
667
|
end
|
@@ -659,12 +670,10 @@ module Sidekiq
|
|
659
670
|
self.class.jid_history_key @name
|
660
671
|
end
|
661
672
|
|
662
|
-
# Give Hash
|
663
|
-
# returns array for using it for redis.hmset
|
673
|
+
# Give Hash returns array for using it for redis.hmset
|
664
674
|
def hash_to_redis hash
|
665
675
|
hash.inject([]){ |arr,kv| arr + [kv[0], kv[1]] }
|
666
676
|
end
|
667
|
-
|
668
677
|
end
|
669
678
|
end
|
670
679
|
end
|
@@ -1,38 +1,41 @@
|
|
1
|
-
# require cron poller
|
2
1
|
require 'sidekiq/cron/poller'
|
3
2
|
|
4
3
|
# For Cron we need to add some methods to Launcher
|
5
4
|
# so look at the code bellow.
|
6
5
|
#
|
7
|
-
#
|
8
|
-
# adding start and stop commands to launcher
|
6
|
+
# We are creating new cron poller instance and
|
7
|
+
# adding start and stop commands to launcher.
|
9
8
|
module Sidekiq
|
10
9
|
module Cron
|
11
10
|
module Launcher
|
12
|
-
|
11
|
+
DEFAULT_POLL_INTERVAL = 30
|
12
|
+
|
13
|
+
# Add cron poller to launcher.
|
13
14
|
attr_reader :cron_poller
|
14
15
|
|
15
|
-
#
|
16
|
+
# Add cron poller and execute normal initialize of Sidekiq launcher.
|
16
17
|
def initialize(options)
|
17
|
-
|
18
|
+
options[:cron_poll_interval] = DEFAULT_POLL_INTERVAL if options[:cron_poll_interval].nil?
|
19
|
+
|
20
|
+
@cron_poller = Sidekiq::Cron::Poller.new(options) if options[:cron_poll_interval] > 0
|
18
21
|
super(options)
|
19
22
|
end
|
20
23
|
|
21
|
-
#
|
24
|
+
# Execute normal run of launcher and run cron poller.
|
22
25
|
def run
|
23
26
|
super
|
24
|
-
cron_poller.start
|
27
|
+
cron_poller.start if @cron_poller
|
25
28
|
end
|
26
29
|
|
27
|
-
#
|
30
|
+
# Execute normal quiet of launcher and quiet cron poller.
|
28
31
|
def quiet
|
29
|
-
cron_poller.terminate
|
32
|
+
cron_poller.terminate if @cron_poller
|
30
33
|
super
|
31
34
|
end
|
32
35
|
|
33
|
-
#
|
36
|
+
# Execute normal stop of launcher and stop cron poller.
|
34
37
|
def stop
|
35
|
-
cron_poller.terminate
|
38
|
+
cron_poller.terminate if @cron_poller
|
36
39
|
super
|
37
40
|
end
|
38
41
|
end
|
@@ -40,7 +43,6 @@ module Sidekiq
|
|
40
43
|
end
|
41
44
|
|
42
45
|
Sidekiq.configure_server do
|
43
|
-
# require Sidekiq original launcher
|
44
46
|
require 'sidekiq/launcher'
|
45
47
|
|
46
48
|
::Sidekiq::Launcher.prepend(Sidekiq::Cron::Launcher)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
it:
|
2
|
+
Job: Job
|
3
|
+
Cron: Cron
|
4
|
+
CronJobs: Cron job
|
5
|
+
EnqueueNow: Accoda
|
6
|
+
EnableAll: Attiva tutto
|
7
|
+
DisableAll: Disattiva tutto
|
8
|
+
EnqueueAll: Accoda tutto
|
9
|
+
DeleteAll: Cancella tutto
|
10
|
+
"Cron string": Cron
|
11
|
+
AreYouSureEnqueueCronJobs: Vuoi accodare TUTTI i cron job?
|
12
|
+
AreYouSureEnqueueCronJob: "Vuoi accodare il cron job '%{job}'?"
|
13
|
+
AreYouSureDeleteCronJobs: Vuoi cancellare TUTTI i cron job?
|
14
|
+
AreYouSureDeleteCronJob: "Vuoi cancellare il cron job '%{job}'?"
|
15
|
+
NoCronJobsWereFound: Nessun cron job trovato
|
16
|
+
Enable: Attiva
|
17
|
+
Disable: Disattiva
|
18
|
+
"Last enqueued": Ultimo accodamento
|
19
|
+
disabled: disattivato
|
20
|
+
enabled: attivato
|
21
|
+
NoHistoryWereFound: Nessun evento in cronologia
|
22
|
+
Description: Descrizione
|
23
|
+
Message: Payload
|
@@ -0,0 +1,22 @@
|
|
1
|
+
pt:
|
2
|
+
Job: Tarefa
|
3
|
+
Cron: Cron
|
4
|
+
CronJobs: Tarefas do Cron
|
5
|
+
EnqueueNow: Enfileirar agora
|
6
|
+
EnableAll: Habilitar todos
|
7
|
+
DisableAll: Desabilitar todos
|
8
|
+
EnqueueAll: Enfileirar todos
|
9
|
+
DeleteAll: Excluir todos
|
10
|
+
'Cron string': Cron
|
11
|
+
AreYouSureEnqueueCronJobs: Tem certeza de que deseja enfileirar TODOS as tarefas?
|
12
|
+
AreYouSureEnqueueCronJob: Tem certeza de que deseja enfileirar a tarefa %{job}?
|
13
|
+
AreYouSureDeleteCronJobs: Tem certeza de que deseja excluir TODOS as tarefas?
|
14
|
+
AreYouSureDeleteCronJob: Tem certeza de que deseja excluir a tarefa %{job}?
|
15
|
+
NoCronJobsWereFound: Nenhuma tarefa foi encontrada
|
16
|
+
Enable: Habilitar
|
17
|
+
Disable: Desabilitar
|
18
|
+
'Last enqueued': Último enfileirado
|
19
|
+
disabled: desabilitado
|
20
|
+
enabled: habilitado
|
21
|
+
NoHistoryWereFound: Nenhum histórico foi encontrado
|
22
|
+
Description: Descrição
|
data/lib/sidekiq/cron/poller.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
require 'sidekiq'
|
2
|
-
require 'sidekiq/util'
|
3
2
|
require 'sidekiq/cron'
|
4
3
|
require 'sidekiq/scheduled'
|
4
|
+
require 'sidekiq/options'
|
5
5
|
|
6
6
|
module Sidekiq
|
7
7
|
module Cron
|
8
|
-
|
9
|
-
|
10
|
-
# The Poller checks Redis every N seconds for sheduled cron jobs
|
8
|
+
# The Poller checks Redis every N seconds for sheduled cron jobs.
|
11
9
|
class Poller < Sidekiq::Scheduled::Poller
|
10
|
+
def initialize(options = {})
|
11
|
+
if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('6.5.0')
|
12
|
+
super
|
13
|
+
else
|
14
|
+
# Old version of Sidekiq does not accept a config argument.
|
15
|
+
@config = options
|
16
|
+
super()
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
12
20
|
def enqueue
|
13
21
|
time = Time.now.utc
|
14
22
|
Sidekiq::Cron::Job.all.each do |job|
|
@@ -16,7 +24,7 @@ module Sidekiq
|
|
16
24
|
end
|
17
25
|
rescue => ex
|
18
26
|
# Most likely a problem with redis networking.
|
19
|
-
# Punt and try again at the next interval
|
27
|
+
# Punt and try again at the next interval.
|
20
28
|
Sidekiq.logger.error ex.message
|
21
29
|
Sidekiq.logger.error ex.backtrace.first
|
22
30
|
handle_exception(ex) if respond_to?(:handle_exception)
|
@@ -27,14 +35,14 @@ module Sidekiq
|
|
27
35
|
def enqueue_job(job, time = Time.now.utc)
|
28
36
|
job.test_and_enque_for_time! time if job && job.valid?
|
29
37
|
rescue => ex
|
30
|
-
#
|
38
|
+
# Problem somewhere in one job.
|
31
39
|
Sidekiq.logger.error "CRON JOB: #{ex.message}"
|
32
40
|
Sidekiq.logger.error "CRON JOB: #{ex.backtrace.first}"
|
33
41
|
handle_exception(ex) if respond_to?(:handle_exception)
|
34
42
|
end
|
35
43
|
|
36
|
-
def poll_interval_average
|
37
|
-
|
44
|
+
def poll_interval_average(process_count = 1)
|
45
|
+
@config[:cron_poll_interval]
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|