sidekiq-cron 1.12.0 → 2.0.0.rc1

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.
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fugit'
4
+ require 'cronex'
2
5
  require 'globalid'
3
6
  require 'sidekiq'
4
7
  require 'sidekiq/cron/support'
@@ -7,7 +10,7 @@ require 'sidekiq/options'
7
10
  module Sidekiq
8
11
  module Cron
9
12
  class Job
10
- # How long we would like to store informations about previous enqueues.
13
+ # How long we would like to store information about previous enqueues.
11
14
  REMEMBER_THRESHOLD = 24 * 60 * 60
12
15
 
13
16
  # Time format for enqueued jobs.
@@ -19,11 +22,80 @@ module Sidekiq
19
22
  # Use serialize/deserialize key of GlobalID.
20
23
  GLOBALID_KEY = "_sc_globalid"
21
24
 
25
+ attr_accessor :name, :namespace, :cron, :description, :klass, :args, :message
26
+ attr_reader :last_enqueue_time, :fetch_missing_args, :source
27
+
28
+ def initialize input_args = {}
29
+ args = Hash[input_args.map{ |k, v| [k.to_s, v] }]
30
+ @fetch_missing_args = args.delete('fetch_missing_args')
31
+ @fetch_missing_args = true if @fetch_missing_args.nil?
32
+
33
+ @name = args["name"]
34
+ @namespace = args["namespace"] || Sidekiq::Cron.configuration.default_namespace
35
+ @cron = args["cron"]
36
+ @description = args["description"] if args["description"]
37
+ @source = args["source"] == "schedule" ? "schedule" : "dynamic"
38
+
39
+ # Get class from klass or class.
40
+ @klass = args["klass"] || args["class"]
41
+
42
+ # Set status of job.
43
+ @status = args['status'] || status_from_redis
44
+
45
+ # Set last enqueue time - from args or from existing job.
46
+ if args['last_enqueue_time'] && !args['last_enqueue_time'].empty?
47
+ @last_enqueue_time = parse_enqueue_time(args['last_enqueue_time'])
48
+ else
49
+ @last_enqueue_time = last_enqueue_time_from_redis
50
+ end
51
+
52
+ # Get right arguments for job.
53
+ @symbolize_args = args["symbolize_args"] == true || ("#{args["symbolize_args"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
54
+ @args = parse_args(args["args"])
55
+
56
+ @date_as_argument = args["date_as_argument"] == true || ("#{args["date_as_argument"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
57
+
58
+ @active_job = args["active_job"] == true || ("#{args["active_job"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
59
+ @active_job_queue_name_prefix = args["queue_name_prefix"]
60
+ @active_job_queue_name_delimiter = args["queue_name_delimiter"]
61
+
62
+ # symbolize_args is only used when active_job is true
63
+ Sidekiq.logger.warn { "Cron Jobs - 'symbolize_args' is gonna be ignored, as it is only used when 'active_job' is true" } if @symbolize_args && !@active_job
64
+
65
+ if args["message"]
66
+ @message = args["message"]
67
+ message_data = Sidekiq.load_json(@message) || {}
68
+ @queue = message_data['queue'] || "default"
69
+ elsif @klass
70
+ message_data = {
71
+ "class" => @klass.to_s,
72
+ "args" => @args,
73
+ }
74
+
75
+ # Get right data for message,
76
+ # only if message wasn't specified before.
77
+ klass_data = get_job_class_options(@klass)
78
+ message_data = klass_data.merge(message_data)
79
+
80
+ # Override queue if set in config,
81
+ # only if message is hash - can be string (dumped JSON).
82
+ if args['queue']
83
+ @queue = message_data['queue'] = args['queue']
84
+ else
85
+ @queue = message_data['queue'] || "default"
86
+ end
87
+
88
+ @message = message_data
89
+ end
90
+
91
+ @queue_name_with_prefix = queue_name_with_prefix
92
+ end
93
+
22
94
  # Crucial part of whole enqueuing job.
23
95
  def should_enque? time
24
96
  return false unless status == "enabled"
25
- return false unless not_past_scheduled_time?(time)
26
- return false unless not_enqueued_after?(time)
97
+ return false if past_scheduled_time?(time)
98
+ return false if enqueued_after?(time)
27
99
 
28
100
  enqueue = Sidekiq.redis do |conn|
29
101
  conn.zadd(job_enqueued_key, formatted_enqueue_time(time), formatted_last_time(time))
@@ -152,6 +224,7 @@ module Sidekiq
152
224
  # Input structure should look like:
153
225
  # {
154
226
  # 'name_of_job' => {
227
+ # 'namespace' => 'MyNamespace',
155
228
  # 'class' => 'MyClass',
156
229
  # 'cron' => '1 * * * *',
157
230
  # 'args' => '(OPTIONAL) [Array or Hash]',
@@ -182,6 +255,7 @@ module Sidekiq
182
255
  # Input structure should look like:
183
256
  # [
184
257
  # {
258
+ # 'namespace' => 'MyNamespace',
185
259
  # 'name' => 'name_of_job',
186
260
  # 'class' => 'MyClass',
187
261
  # 'cron' => '1 * * * *',
@@ -207,19 +281,20 @@ module Sidekiq
207
281
  # Like #load_from_array.
208
282
  # If exists old jobs in Redis but removed from args, destroy old jobs.
209
283
  def self.load_from_array!(array, options = {})
210
- job_names = array.map { |job| job["name"] }
284
+ job_names = array.map { |job| job["name"] || job[:name] }
211
285
  destroy_removed_jobs(job_names)
212
286
  load_from_array(array, options)
213
287
  end
214
288
 
215
289
  # Get all cron jobs.
216
- def self.all
290
+ def self.all(namespace = Sidekiq::Cron.configuration.default_namespace)
217
291
  job_hashes = nil
218
292
  Sidekiq.redis do |conn|
219
- set_members = conn.smembers(jobs_key)
293
+ job_keys = job_keys_from_namespace(namespace)
294
+
220
295
  job_hashes = conn.pipelined do |pipeline|
221
- set_members.each do |key|
222
- pipeline.hgetall(key)
296
+ job_keys.each do |job_key|
297
+ pipeline.hgetall(job_key)
223
298
  end
224
299
  end
225
300
  end
@@ -229,22 +304,26 @@ module Sidekiq
229
304
  end
230
305
  end
231
306
 
232
- def self.count
233
- out = 0
234
- Sidekiq.redis do |conn|
235
- out = conn.scard(jobs_key)
307
+ def self.count(namespace = Sidekiq::Cron.configuration.default_namespace)
308
+ if namespace == '*'
309
+ Namespace.all_with_count.reduce(0) do |memo, namespace_count|
310
+ memo + namespace_count[:count]
311
+ end
312
+ else
313
+ Sidekiq.redis { |conn| conn.scard(jobs_key(namespace)) }
236
314
  end
237
- out
238
315
  end
239
316
 
240
- def self.find name
317
+ def self.find(name, namespace = Sidekiq::Cron.configuration.default_namespace)
241
318
  # If name is hash try to get name from it.
242
319
  name = name[:name] || name['name'] if name.is_a?(Hash)
243
- return unless exists? name
320
+ return unless exists? name, namespace
244
321
 
245
322
  output = nil
246
323
  Sidekiq.redis do |conn|
247
- output = Job.new conn.hgetall( redis_key(name) )
324
+ if exists? name, namespace
325
+ output = Job.new conn.hgetall(redis_key(name, namespace))
326
+ end
248
327
  end
249
328
  output if output && output.valid?
250
329
  end
@@ -255,93 +334,17 @@ module Sidekiq
255
334
  end
256
335
 
257
336
  # Destroy job by name.
258
- def self.destroy name
337
+ def self.destroy(name, namespace = Sidekiq::Cron.configuration.default_namespace)
259
338
  # If name is hash try to get name from it.
260
339
  name = name[:name] || name['name'] if name.is_a?(Hash)
261
340
 
262
- if job = find(name)
341
+ if (job = find(name, namespace))
263
342
  job.destroy
264
343
  else
265
344
  false
266
345
  end
267
346
  end
268
347
 
269
- attr_accessor :name, :cron, :description, :klass, :args, :message
270
- attr_reader :last_enqueue_time, :fetch_missing_args, :source
271
-
272
- def initialize input_args = {}
273
- args = Hash[input_args.map{ |k, v| [k.to_s, v] }]
274
- @fetch_missing_args = args.delete('fetch_missing_args')
275
- @fetch_missing_args = true if @fetch_missing_args.nil?
276
-
277
- @name = args["name"]
278
- @cron = args["cron"]
279
- @description = args["description"] if args["description"]
280
- @source = args["source"] == "schedule" ? "schedule" : "dynamic"
281
-
282
- # Get class from klass or class.
283
- @klass = args["klass"] || args["class"]
284
-
285
- # Set status of job.
286
- @status = args['status'] || status_from_redis
287
-
288
- # Set last enqueue time - from args or from existing job.
289
- if args['last_enqueue_time'] && !args['last_enqueue_time'].empty?
290
- @last_enqueue_time = parse_enqueue_time(args['last_enqueue_time'])
291
- else
292
- @last_enqueue_time = last_enqueue_time_from_redis
293
- end
294
-
295
- # Get right arguments for job.
296
- @symbolize_args = args["symbolize_args"] == true || ("#{args["symbolize_args"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
297
- @args = parse_args(args["args"])
298
-
299
- @date_as_argument = args["date_as_argument"] == true || ("#{args["date_as_argument"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
300
-
301
- @active_job = args["active_job"] == true || ("#{args["active_job"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
302
- @active_job_queue_name_prefix = args["queue_name_prefix"]
303
- @active_job_queue_name_delimiter = args["queue_name_delimiter"]
304
-
305
- if args["message"]
306
- @message = args["message"]
307
- message_data = Sidekiq.load_json(@message) || {}
308
- @queue = message_data['queue'] || "default"
309
- elsif @klass
310
- message_data = {
311
- "class" => @klass.to_s,
312
- "args" => @args,
313
- }
314
-
315
- # Get right data for message,
316
- # only if message wasn't specified before.
317
- klass_data = case @klass
318
- when Class
319
- @klass.get_sidekiq_options
320
- when String
321
- begin
322
- Sidekiq::Cron::Support.constantize(@klass).get_sidekiq_options
323
- rescue Exception => e
324
- # Unknown class
325
- {"queue"=>"default"}
326
- end
327
- end
328
-
329
- message_data = klass_data.merge(message_data)
330
-
331
- # Override queue if setted in config,
332
- # only if message is hash - can be string (dumped JSON).
333
- if args['queue']
334
- @queue = message_data['queue'] = args['queue']
335
- else
336
- @queue = message_data['queue'] || "default"
337
- end
338
-
339
- @message = message_data
340
- end
341
-
342
- @queue_name_with_prefix = queue_name_with_prefix
343
- end
344
-
345
348
  def status
346
349
  @status
347
350
  end
@@ -370,6 +373,12 @@ module Sidekiq
370
373
  message
371
374
  end
372
375
 
376
+ def human_cron
377
+ Cronex::ExpressionDescriptor.new(cron).description
378
+ rescue => e
379
+ cron
380
+ end
381
+
373
382
  def status_from_redis
374
383
  out = "enabled"
375
384
  if fetch_missing_args
@@ -406,6 +415,7 @@ module Sidekiq
406
415
  def to_hash
407
416
  hash = {
408
417
  name: @name,
418
+ namespace: @namespace,
409
419
  klass: @klass.to_s,
410
420
  cron: @cron,
411
421
  description: @description,
@@ -436,11 +446,13 @@ module Sidekiq
436
446
  @errors = []
437
447
 
438
448
  errors << "'name' must be set" if @name.nil? || @name.size == 0
449
+ errors << "'namespace' must be set" if @namespace.nil? || @namespace.size == 0
450
+
439
451
  if @cron.nil? || @cron.size == 0
440
452
  errors << "'cron' must be set"
441
453
  else
442
454
  begin
443
- @parsed_cron = Fugit.do_parse_cronish(@cron)
455
+ @parsed_cron = do_parse_cron(@cron)
444
456
  rescue => e
445
457
  errors << "'cron' -> #{@cron.inspect} -> #{e.class}: #{e.message}"
446
458
  end
@@ -466,19 +478,18 @@ module Sidekiq
466
478
  return false unless valid?
467
479
 
468
480
  Sidekiq.redis do |conn|
469
-
470
481
  # Add to set of all jobs
471
- conn.sadd self.class.jobs_key, [redis_key]
482
+ conn.sadd self.class.jobs_key(@namespace), [redis_key]
472
483
 
473
- # Add informations for this job!
474
- conn.hset redis_key, to_hash.transform_values! { |v| v || "" }
484
+ # Add information for this job!
485
+ conn.hset redis_key, to_hash.transform_values! { |v| v || '' }
475
486
 
476
487
  # Add information about last time! - don't enque right after scheduler poller starts!
477
488
  time = Time.now.utc
478
489
  exists = conn.public_send(REDIS_EXISTS_METHOD, job_enqueued_key)
479
490
  conn.zadd(job_enqueued_key, time.to_f.to_s, formatted_last_time(time).to_s) unless exists == true || exists == 1
480
491
  end
481
- Sidekiq.logger.info { "Cron Jobs - added job with name: #{@name}" }
492
+ Sidekiq.logger.info { "Cron Jobs - added job with name #{@name} in the namespace #{@namespace}" }
482
493
  end
483
494
 
484
495
  def save_last_enqueue_time
@@ -506,9 +517,9 @@ module Sidekiq
506
517
  def destroy
507
518
  Sidekiq.redis do |conn|
508
519
  # Delete from set.
509
- conn.srem self.class.jobs_key, [redis_key]
520
+ conn.srem self.class.jobs_key(@namespace), [redis_key]
510
521
 
511
- # Delete runned timestamps.
522
+ # Delete ran timestamps.
512
523
  conn.del job_enqueued_key
513
524
 
514
525
  # Delete jid_history.
@@ -518,7 +529,7 @@ module Sidekiq
518
529
  conn.del redis_key
519
530
  end
520
531
 
521
- Sidekiq.logger.info { "Cron Jobs - deleted job with name: #{@name}" }
532
+ Sidekiq.logger.info { "Cron Jobs - deleted job with name #{@name} from namespace #{@namespace}" }
522
533
  end
523
534
 
524
535
  # Remove all job from cron.
@@ -531,9 +542,17 @@ module Sidekiq
531
542
 
532
543
  # Remove "removed jobs" between current jobs and new jobs
533
544
  def self.destroy_removed_jobs new_job_names
534
- current_job_names = Sidekiq::Cron::Job.all.filter_map { |j| j.name if j.source == "schedule" }
545
+ current_jobs = Sidekiq::Cron::Job.all("*").filter_map { |j| j if j.source == "schedule" }
546
+ current_job_names = current_jobs.map(&:name)
535
547
  removed_job_names = current_job_names - new_job_names
536
- removed_job_names.each { |j| Sidekiq::Cron::Job.destroy(j) }
548
+ removed_job_names.each do |j|
549
+ job_to_destroy = current_jobs.detect { |job| job.name == j }
550
+
551
+ Sidekiq::Cron::Job.destroy(
552
+ job_to_destroy.name,
553
+ job_to_destroy.namespace
554
+ )
555
+ end
537
556
  removed_job_names
538
557
  end
539
558
 
@@ -551,15 +570,16 @@ module Sidekiq
551
570
  last_time(now).getutc.iso8601
552
571
  end
553
572
 
554
- def self.exists? name
573
+ def self.exists?(name, namespace = Sidekiq::Cron.configuration.default_namespace)
555
574
  out = Sidekiq.redis do |conn|
556
- conn.public_send(REDIS_EXISTS_METHOD, redis_key(name))
575
+ conn.public_send(REDIS_EXISTS_METHOD, redis_key(name, namespace))
557
576
  end
558
- out == true || out == 1
577
+
578
+ [true, 1].include?(out)
559
579
  end
560
580
 
561
581
  def exists?
562
- self.class.exists? @name
582
+ self.class.exists? @name, @namespace
563
583
  end
564
584
 
565
585
  def sort_name
@@ -573,11 +593,25 @@ module Sidekiq
573
593
  private
574
594
 
575
595
  def parsed_cron
576
- @parsed_cron ||= Fugit.parse_cronish(@cron)
596
+ @parsed_cron ||= do_parse_cron(@cron)
597
+ end
598
+
599
+ def do_parse_cron(cron)
600
+ case Sidekiq::Cron.configuration.natural_cron_parsing_mode
601
+ when :single
602
+ Fugit.do_parse_cronish(cron)
603
+ when :strict
604
+ Fugit.parse_cron(cron) || # Ex. '11 1 * * 1'
605
+ Fugit.parse_nat(cron, :multi => :fail) || # Ex. 'every Monday at 01:11'
606
+ fail(ArgumentError.new("invalid cron string #{cron.inspect}"))
607
+ else
608
+ mode = Sidekiq::Cron.configuration.natural_cron_parsing_mode
609
+ raise ArgumentError, "Unknown natural cron parsing mode: #{mode.inspect}"
610
+ end
577
611
  end
578
612
 
579
- def not_enqueued_after?(time)
580
- @last_enqueue_time.nil? || @last_enqueue_time.to_i < last_time(time).to_i
613
+ def enqueued_after?(time)
614
+ @last_enqueue_time && @last_enqueue_time.to_i >= last_time(time).to_i
581
615
  end
582
616
 
583
617
  # Try parsing inbound args into an array.
@@ -631,48 +665,83 @@ module Sidekiq
631
665
  DateTime.parse(timestamp).to_time.utc
632
666
  end
633
667
 
634
- def not_past_scheduled_time?(current_time)
668
+ def past_scheduled_time?(current_time)
635
669
  last_cron_time = parsed_cron.previous_time(current_time).utc
636
- return false if (current_time.to_i - last_cron_time.to_i) > 60
637
- true
670
+ period = Sidekiq::Cron.configuration.reschedule_grace_period
671
+
672
+ current_time.to_i - last_cron_time.to_i > period
673
+ end
674
+
675
+ def self.default_if_blank(namespace)
676
+ if namespace.nil? || namespace == ''
677
+ Sidekiq::Cron.configuration.default_namespace
678
+ else
679
+ namespace
680
+ end
638
681
  end
639
682
 
640
- # Redis key for set of all cron jobs.
641
- def self.jobs_key
642
- "cron_jobs"
683
+ def self.job_keys_from_namespace(namespace = Sidekiq::Cron.configuration.default_namespace)
684
+ Sidekiq.redis do |conn|
685
+ if namespace == '*'
686
+ namespaces = conn.keys(jobs_key(namespace))
687
+ namespaces.flat_map { |name| conn.smembers(name) }
688
+ else
689
+ conn.smembers(jobs_key(namespace))
690
+ end
691
+ end
643
692
  end
644
693
 
645
- # Redis key for storing one cron job.
646
- def self.redis_key name
647
- "cron_job:#{name}"
694
+ def self.migrate_old_jobs_if_needed!
695
+ Sidekiq.redis do |conn|
696
+ old_job_keys = conn.smembers('cron_jobs')
697
+ old_job_keys.each do |old_job|
698
+ old_job_hash = conn.hgetall(old_job)
699
+ old_job_hash[:namespace] = Sidekiq::Cron.configuration.default_namespace
700
+ create(old_job_hash)
701
+ conn.srem('cron_jobs', old_job)
702
+ end
703
+ end
648
704
  end
649
705
 
650
- # Redis key for storing one cron job.
706
+ # Redis key for set of all cron jobs
707
+ def self.jobs_key(namespace = Sidekiq::Cron.configuration.default_namespace)
708
+ "cron_jobs:#{default_if_blank(namespace)}"
709
+ end
710
+
711
+ # Redis key for storing one cron job
712
+ def self.redis_key(name, namespace = Sidekiq::Cron.configuration.default_namespace)
713
+ "cron_job:#{default_if_blank(namespace)}:#{name}"
714
+ end
715
+
716
+ # Redis key for storing one cron job
651
717
  def redis_key
652
- self.class.redis_key @name
718
+ self.class.redis_key @name, @namespace
653
719
  end
654
720
 
655
- # Redis key for storing one cron job run times (when poller added job to queue)
656
- def self.job_enqueued_key name
657
- "cron_job:#{name}:enqueued"
721
+ # Redis key for storing one cron job run times
722
+ # (when poller added job to queue)
723
+ def self.job_enqueued_key(name, namespace = Sidekiq::Cron.configuration.default_namespace)
724
+ "cron_job:#{default_if_blank(namespace)}:#{name}:enqueued"
658
725
  end
659
726
 
660
- def self.jid_history_key name
661
- "cron_job:#{name}:jid_history"
727
+ def self.jid_history_key(name, namespace = Sidekiq::Cron.configuration.default_namespace)
728
+ "cron_job:#{default_if_blank(namespace)}:#{name}:jid_history"
662
729
  end
663
730
 
731
+ # Redis key for storing one cron job run times
732
+ # (when poller added job to queue)
664
733
  def job_enqueued_key
665
- self.class.job_enqueued_key @name
734
+ self.class.job_enqueued_key @name, @namespace
666
735
  end
667
736
 
668
737
  def jid_history_key
669
- self.class.jid_history_key @name
738
+ self.class.jid_history_key @name, @namespace
670
739
  end
671
740
 
672
741
  def serialized_last_enqueue_time
673
742
  @last_enqueue_time&.strftime(LAST_ENQUEUE_TIME_FORMAT)
674
743
  end
675
-
744
+
676
745
  def convert_to_global_id_hash(argument)
677
746
  { GLOBALID_KEY => argument.to_global_id.to_s }
678
747
  rescue URI::GID::MissingModelIdError
@@ -719,6 +788,23 @@ module Sidekiq
719
788
  argument
720
789
  end
721
790
  end
791
+
792
+ def get_job_class_options(klass)
793
+ klass = klass.is_a?(Class) ? klass : begin
794
+ Sidekiq::Cron::Support.constantize(klass)
795
+ rescue NameError
796
+ # noop
797
+ end
798
+
799
+ if klass.nil?
800
+ # Unknown class
801
+ {"queue"=>"default"}
802
+ elsif is_active_job?(klass)
803
+ {"queue"=>klass.queue_name}
804
+ else
805
+ klass.get_sidekiq_options
806
+ end
807
+ end
722
808
  end
723
809
  end
724
810
  end
@@ -1,7 +1,7 @@
1
1
  require 'sidekiq/cron/poller'
2
2
 
3
3
  # For Cron we need to add some methods to Launcher
4
- # so look at the code bellow.
4
+ # so look at the code below.
5
5
  #
6
6
  # We are creating new cron poller instance and
7
7
  # adding start and stop commands to launcher.
@@ -0,0 +1,22 @@
1
+ id:
2
+ Job: Job
3
+ Cron: Cron
4
+ CronJobs: Cron Job
5
+ EnqueueNow: Tambahkan ke Antrian Sekarang
6
+ EnableAll: Aktifkan Semua
7
+ DisableAll: Nonaktifkan Semua
8
+ EnqueueAll: Tambahkan Semua ke Antrian
9
+ DeleteAll: Hapus Semua
10
+ 'Cron string': Cron string
11
+ AreYouSureEnqueueCronJobs: Apakah Anda yakin ingin menambahkan SEMUA cron job ke antrian?
12
+ AreYouSureEnqueueCronJob: Apakah Anda yakin ingin menambahkan cron job %{job} ke antrian?
13
+ AreYouSureDeleteCronJobs: Apakah Anda yakin ingin menghapus SEMUA cron job?
14
+ AreYouSureDeleteCronJob: Apakah Anda yakin ingin menghapus cron job %{job}?
15
+ NoCronJobsWereFound: Tidak ada cron job
16
+ Enable: Aktifkan
17
+ Disable: Nonaktifkan
18
+ 'Last enqueued': Terakhir kali ditambahkan ke antrian
19
+ disabled: dinonaktifkan
20
+ enabled: diaktifkan
21
+ NoHistoryWereFound: Tidak ada riwayat
22
+ Description: Deskripsi
@@ -0,0 +1,45 @@
1
+ require 'sidekiq'
2
+
3
+ module Sidekiq
4
+ module Cron
5
+ class Namespace
6
+ def self.all
7
+ namespaces = nil
8
+
9
+ Sidekiq.redis do |conn|
10
+ namespaces = conn.keys('cron_jobs:*').collect do |key|
11
+ key.split(':').last
12
+ end
13
+ end
14
+
15
+ # Adds the default namespace if not present
16
+ has_default = namespaces.detect do |name|
17
+ name == Sidekiq::Cron.configuration.default_namespace
18
+ end
19
+
20
+ unless has_default
21
+ namespaces << Sidekiq::Cron.configuration.default_namespace
22
+ end
23
+
24
+ namespaces
25
+ end
26
+
27
+ def self.all_with_count
28
+ all.map do |namespace_name|
29
+ {
30
+ count: count(namespace_name),
31
+ name: namespace_name
32
+ }
33
+ end
34
+ end
35
+
36
+ def self.count(name = Sidekiq::Cron.configuration.default_namespace)
37
+ out = 0
38
+ Sidekiq.redis do |conn|
39
+ out = conn.scard("cron_jobs:#{name}")
40
+ end
41
+ out
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sidekiq'
2
4
  require 'sidekiq/cron'
3
5
  require 'sidekiq/scheduled'
@@ -5,21 +7,26 @@ require 'sidekiq/options'
5
7
 
6
8
  module Sidekiq
7
9
  module Cron
8
- # The Poller checks Redis every N seconds for sheduled cron jobs.
10
+ # The Poller checks Redis every N seconds for scheduled cron jobs.
9
11
  class Poller < Sidekiq::Scheduled::Poller
10
12
  def initialize(config = nil)
11
- if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('6.5.0')
12
- super
13
- else
13
+ if Gem::Version.new(Sidekiq::VERSION) < Gem::Version.new('6.5.0')
14
14
  # Old version of Sidekiq does not accept a config argument.
15
15
  @config = config
16
- super()
17
16
  end
17
+
18
+ super
19
+ end
20
+
21
+ def start
22
+ Sidekiq::Cron::Job.migrate_old_jobs_if_needed!
23
+
24
+ super
18
25
  end
19
26
 
20
27
  def enqueue
21
28
  time = Time.now.utc
22
- Sidekiq::Cron::Job.all.each do |job|
29
+ Sidekiq::Cron::Job.all('*').each do |job|
23
30
  enqueue_job(job, time)
24
31
  end
25
32
  rescue => ex
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Cron
5
- VERSION = "1.12.0"
5
+ VERSION = "2.0.0.rc1"
6
6
  end
7
7
  end