sidekiq-cron 1.4.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|