sidekiq-cron 1.0.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6e4efebfa16f1bedd09081f160e3db3d778e0b9
4
- data.tar.gz: b23fe76d331791eabd457cd85f797181bf086712
3
+ metadata.gz: cb2f152cb3faf85dbc089e10820fd48d7c23f6ad
4
+ data.tar.gz: 4ced419b5c9ddaeb43a6ebd62221cdbd95eb2c91
5
5
  SHA512:
6
- metadata.gz: 3286595909fbc0c05504fb38b12f79544b020a627454701adc8e7b10fd7afc7a27cf27a3edf062b3840eca9e4ebc4964149bc9742e6d1bd85d0177cdea6fe18b
7
- data.tar.gz: 337457599316fcdec08c10d29fab8b7d130584c345c97f3e4ad2bc93a2c7f2a240689776be8da24d380057ec23481995f0eff456e3789e68a3cc979012f817bf
6
+ metadata.gz: d882bd7a34f478fc9ea3eb591c6ffe01df2b360ba501ef2df13aa3d7631f77a97a393bc5a391ec682810766dbfe8790bb8a42ed29fc69a666623753103c4c994
7
+ data.tar.gz: 4bbdf927f3830a9a62e2bf622bf34492555e0a8051f303a0a712eda46a818a5dfd78b5de913e137e39b91f046a05247ae2a133cabe1573fa1b4f21307f721b24
data/.travis.yml CHANGED
@@ -1,9 +1,10 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.5.0
4
- - 2.4.3
5
- - 2.3.6
6
- - 2.2.9
3
+ - 2.6
4
+ - 2.5
5
+ - 2.4
6
+ - 2.3
7
+ - 2.2
7
8
  services:
8
9
  - redis-server
9
10
  branches:
@@ -15,7 +16,3 @@ notifications:
15
16
  - ondrej@bartas.cz
16
17
  env:
17
18
  travis: 'yes'
18
- matrix:
19
- allow_failures:
20
- - rvm: jruby-19mode
21
- - rvm: rbx-19mode
data/Changes.md CHANGED
@@ -1,3 +1,21 @@
1
+ v 1.2.0
2
+ -------
3
+
4
+ - updated readme
5
+ - fix problem with Sidekiq::Launcher and requiring it when not needed
6
+ - better patching of Sidekiq::Launcher
7
+ - fixed Dockerfile
8
+
9
+ v 1.1.0
10
+ -------
11
+
12
+ - updated readme
13
+ - fix unit tests - changed argument error when getting invalid cron format
14
+ - when fallbacking old job enqueued time use `Time.parse` šwithout format (so ruby can decide best method to parse it)
15
+ - add option `date_as_argument` which will add to your job arguments on last place `Time.now.to_f` when it was eneuqued
16
+ - add option `description` which will allow you to add notes to your jobs so in web view you can see it
17
+ - fixed translations
18
+
1
19
  v 1.0.4
2
20
  -------
3
21
 
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:2.3.1
1
+ FROM ruby:2.4
2
2
  MAINTAINER Joao Serra <joaopfserra@gmail.com>
3
3
 
4
4
  RUN apt-get update && \
data/README.md CHANGED
@@ -19,6 +19,11 @@ Works with ActiveJob (Rails 4.2+)
19
19
 
20
20
  You don't need Sidekiq PRO, you can use this gem with plain __Sidekiq__.
21
21
 
22
+ Upgrade from <0.6x to 1.0.x
23
+ ---------------------------
24
+
25
+ Please be aware that sidekiq-cron < 1.0 was relying on rufus-scheduler < 3.5. Using those older sidekiq-cron with rufus-scheduler >= 3.5 ends up with jobs failing on creation. Sidekiq-cron 1.0 includes a patch that switches from rufus-scheduler to rufus-scheduler's core dependency, fugit.
26
+
22
27
  Requirements
23
28
  -----------------
24
29
 
@@ -37,7 +42,7 @@ Installation
37
42
 
38
43
  or add to your `Gemfile`
39
44
 
40
- gem "sidekiq-cron", "~> 0.6.3"
45
+ gem "sidekiq-cron", "~> 1.1"
41
46
 
42
47
 
43
48
  Getting Started
@@ -56,9 +61,11 @@ _Job properties_:
56
61
  #OPTIONAL
57
62
  'queue' => 'name of queue',
58
63
  'args' => '[Array or Hash] of arguments which will be passed to perform method',
64
+ 'date_as_argument' => true, # add the time of execution as last argument of the perform method
59
65
  'active_job' => true, # enqueue job through rails 4.2+ active job interface
60
66
  'queue_name_prefix' => 'prefix', # rails 4.2+ active job queue with prefix
61
- 'queue_name_delimiter' => '.' # rails 4.2+ active job queue with custom delimiter
67
+ 'queue_name_delimiter' => '.', # rails 4.2+ active job queue with custom delimiter
68
+ 'description' => 'A sentence describing what work this job performs.' # Optional
62
69
  }
63
70
  ```
64
71
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.4
1
+ 1.2.0
data/docker-compose.yml CHANGED
@@ -18,4 +18,6 @@ services:
18
18
  - redis:redis.test
19
19
  depends_on:
20
20
  - common
21
- command: dockerize -wait tcp://redis.test:6379 -timeout 60s rake test
21
+ command: dockerize -wait tcp://redis.test:6379 -timeout 60s bundle exec rake test
22
+ volumes:
23
+ - .:/sidekiq-cron
@@ -13,7 +13,6 @@ module Sidekiq
13
13
  #how long we would like to store informations about previous enqueues
14
14
  REMEMBER_THRESHOLD = 24 * 60 * 60
15
15
  LAST_ENQUEUE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S %z'
16
- LAST_ENQUEUE_TIME_FORMAT_OLD = '%Y-%m-%d %H:%M:%S'
17
16
 
18
17
  #crucial part of whole enquing job
19
18
  def should_enque? time
@@ -57,21 +56,23 @@ module Sidekiq
57
56
  nil
58
57
  end
59
58
 
60
- if klass_const
61
- if defined?(ActiveJob::Base) && klass_const < ActiveJob::Base
62
- enqueue_active_job(klass_const)
63
- else
64
- enqueue_sidekiq_worker(klass_const)
65
- end
66
- else
67
- if @active_job
68
- Sidekiq::Client.push(active_job_message)
59
+ jid =
60
+ if klass_const
61
+ if defined?(ActiveJob::Base) && klass_const < ActiveJob::Base
62
+ enqueue_active_job(klass_const).try :provider_job_id
63
+ else
64
+ enqueue_sidekiq_worker(klass_const)
65
+ end
69
66
  else
70
- Sidekiq::Client.push(sidekiq_worker_message)
67
+ if @active_job
68
+ Sidekiq::Client.push(active_job_message)
69
+ else
70
+ Sidekiq::Client.push(sidekiq_worker_message)
71
+ end
71
72
  end
72
- end
73
73
 
74
74
  save_last_enqueue_time
75
+ add_jid_history jid
75
76
  logger.debug { "enqueued #{@name}: #{@message}" }
76
77
  end
77
78
 
@@ -83,14 +84,10 @@ module Sidekiq
83
84
 
84
85
  def enqueue_active_job(klass_const)
85
86
  klass_const.set(queue: @queue).perform_later(*@args)
86
-
87
- true
88
87
  end
89
88
 
90
89
  def enqueue_sidekiq_worker(klass_const)
91
90
  klass_const.set(queue: queue_name_with_prefix).perform_async(*@args)
92
-
93
- true
94
91
  end
95
92
 
96
93
  # siodekiq worker message
@@ -283,6 +280,7 @@ module Sidekiq
283
280
 
284
281
  #get right arguments for job
285
282
  @args = args["args"].nil? ? [] : parse_args( args["args"] )
283
+ @args += [Time.now.to_f] if args["date_as_argument"]
286
284
 
287
285
  @active_job = args["active_job"] == true || ("#{args["active_job"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
288
286
  @active_job_queue_name_prefix = args["queue_name_prefix"]
@@ -350,6 +348,12 @@ module Sidekiq
350
348
  !enabled?
351
349
  end
352
350
 
351
+ def pretty_message
352
+ JSON.pretty_generate Sidekiq.load_json(message)
353
+ rescue JSON::ParserError
354
+ message
355
+ end
356
+
353
357
  def status_from_redis
354
358
  out = "enabled"
355
359
  if fetch_missing_args
@@ -371,6 +375,18 @@ module Sidekiq
371
375
  out
372
376
  end
373
377
 
378
+ def jid_history_from_redis
379
+ out =
380
+ Sidekiq.redis do |conn|
381
+ conn.lrange(jid_history_key, 0, -1) rescue nil
382
+ end
383
+
384
+ # returns nil if out nil
385
+ out && out.map do |jid_history_raw|
386
+ Sidekiq.load_json jid_history_raw
387
+ end
388
+ end
389
+
374
390
  #export job data to hash
375
391
  def to_hash
376
392
  {
@@ -457,6 +473,20 @@ module Sidekiq
457
473
  end
458
474
  end
459
475
 
476
+ def add_jid_history(jid)
477
+ jid_history = {
478
+ jid: jid,
479
+ enqueued: @last_enqueue_time
480
+ }
481
+ @history_size ||= (Sidekiq.options[:cron_history_size] || 10).to_i - 1
482
+ Sidekiq.redis do |conn|
483
+ conn.lpush jid_history_key,
484
+ Sidekiq.dump_json(jid_history)
485
+ # keep only last 10 entries in a fifo manner
486
+ conn.ltrim jid_history_key, 0, @history_size
487
+ end
488
+ end
489
+
460
490
  # remove job from cron jobs by name
461
491
  # input:
462
492
  # first arg: name (string) - name of job (must be same - case sensitive)
@@ -468,6 +498,9 @@ module Sidekiq
468
498
  #delete runned timestamps
469
499
  conn.del job_enqueued_key
470
500
 
501
+ # delete jid_history
502
+ conn.del jid_history_key
503
+
471
504
  #delete main job
472
505
  conn.del redis_key
473
506
  end
@@ -554,7 +587,7 @@ module Sidekiq
554
587
  def parse_enqueue_time(timestamp)
555
588
  DateTime.strptime(timestamp, LAST_ENQUEUE_TIME_FORMAT).to_time.utc
556
589
  rescue ArgumentError
557
- DateTime.strptime(timestamp, LAST_ENQUEUE_TIME_FORMAT_OLD).to_time.utc
590
+ DateTime.parse(timestamp).to_time.utc
558
591
  end
559
592
 
560
593
  def not_past_scheduled_time?(current_time)
@@ -586,12 +619,20 @@ module Sidekiq
586
619
  "cron_job:#{name}:enqueued"
587
620
  end
588
621
 
622
+ def self.jid_history_key name
623
+ "cron_job:#{name}:jid_history"
624
+ end
625
+
589
626
  # Redis key for storing one cron job run times
590
627
  # (when poller added job to queue)
591
628
  def job_enqueued_key
592
629
  self.class.job_enqueued_key @name
593
630
  end
594
631
 
632
+ def jid_history_key
633
+ self.class.jid_history_key @name
634
+ end
635
+
595
636
  # Give Hash
596
637
  # returns array for using it for redis.hmset
597
638
  def hash_to_redis hash
@@ -1,6 +1,3 @@
1
- # require Sidekiq original launcher
2
- require 'sidekiq/launcher'
3
-
4
1
  # require cron poller
5
2
  require 'sidekiq/cron/poller'
6
3
 
@@ -10,44 +7,41 @@ require 'sidekiq/cron/poller'
10
7
  # we are creating new cron poller instance and
11
8
  # adding start and stop commands to launcher
12
9
  module Sidekiq
13
- class Launcher
14
- # Add cron poller to launcher
15
- attr_reader :cron_poller
16
-
17
- # remember old initialize
18
- alias_method :old_initialize, :initialize
19
-
20
- # add cron poller and execute normal initialize of Sidekiq launcher
21
- def initialize(options)
22
- @cron_poller = Sidekiq::Cron::Poller.new
23
- old_initialize options
24
- end
25
-
26
- # remember old run
27
- alias_method :old_run, :run
28
-
29
- # execute normal run of launcher and run cron poller
30
- def run
31
- old_run
32
- cron_poller.start
33
- end
34
-
35
- # remember old quiet
36
- alias_method :old_quiet, :quiet
37
-
38
- # execute normal quiet of launcher and quiet cron poller
39
- def quiet
40
- cron_poller.terminate
41
- old_quiet
10
+ module Cron
11
+ module Launcher
12
+ # Add cron poller to launcher
13
+ attr_reader :cron_poller
14
+
15
+ # add cron poller and execute normal initialize of Sidekiq launcher
16
+ def initialize(options)
17
+ @cron_poller = Sidekiq::Cron::Poller.new
18
+ super(options)
19
+ end
20
+
21
+ # execute normal run of launcher and run cron poller
22
+ def run
23
+ super
24
+ cron_poller.start
25
+ end
26
+
27
+ # execute normal quiet of launcher and quiet cron poller
28
+ def quiet
29
+ cron_poller.terminate
30
+ super
31
+ end
32
+
33
+ # execute normal stop of launcher and stop cron poller
34
+ def stop
35
+ cron_poller.terminate
36
+ super
37
+ end
42
38
  end
39
+ end
40
+ end
43
41
 
44
- # remember old stop
45
- alias_method :old_stop, :stop
42
+ Sidekiq.configure_server do
43
+ # require Sidekiq original launcher
44
+ require 'sidekiq/launcher'
46
45
 
47
- # execute normal stop of launcher and stop cron poller
48
- def stop
49
- cron_poller.terminate
50
- old_stop
51
- end
52
- end
46
+ ::Sidekiq::Launcher.prepend(Sidekiq::Cron::Launcher)
53
47
  end
@@ -8,6 +8,6 @@ de:
8
8
  NoCronJobsWereFound: Keine Cronjobs gefunden
9
9
  Enable: Aktivieren
10
10
  Disable: Deaktivieren
11
- 'Last enque': Eingereiht
11
+ 'Last enqueued': Eingereiht
12
12
  disabled: deaktiviert
13
13
  enabled: aktiviert
@@ -13,6 +13,8 @@ en:
13
13
  NoCronJobsWereFound: No cron jobs were found
14
14
  Enable: Enable
15
15
  Disable: Disable
16
- 'Last enque': Last enqueued
16
+ 'Last enqueued': Last enqueued
17
17
  disabled: disabled
18
18
  enabled: enabled
19
+ NoHistoryWereFound: No history were found
20
+ Description: Description
@@ -13,6 +13,6 @@ ja:
13
13
  NoCronJobsWereFound: Cronジョブが見つかりませんでした
14
14
  Enable: 有効にする
15
15
  Disable: 無効にする
16
- 'Last enque': 最後のキュー
16
+ 'Last enqueued': 最後のキュー
17
17
  disabled: 無効
18
18
  enabled: 有効
@@ -9,6 +9,6 @@ ru:
9
9
  NoCronJobsWereFound: Не найдено периодических задач
10
10
  Enable: Включить
11
11
  Disable: Отключить
12
- 'Last enque': Последний запуск
12
+ 'Last enqueued': Последний запуск
13
13
  disabled: отключено
14
14
  enabled: включено
@@ -13,7 +13,7 @@ zh-CN:
13
13
  NoCronJobsWereFound: 没有定时任务
14
14
  Enable: 启用
15
15
  Disable: 禁用
16
- 'Last enque': 放入队列时间
16
+ 'Last enqueued': 放入队列时间
17
17
  disabled: 已禁用
18
18
  enabled: 已启用
19
19
 
@@ -17,8 +17,8 @@ module Sidekiq
17
17
  rescue => ex
18
18
  # Most likely a problem with redis networking.
19
19
  # Punt and try again at the next interval
20
- logger.error ex.message
21
- logger.error ex.backtrace.first
20
+ Sidekiq.logger.error ex.message
21
+ Sidekiq.logger.error ex.backtrace.first
22
22
  handle_exception(ex) if respond_to?(:handle_exception)
23
23
  end
24
24
 
@@ -28,8 +28,8 @@ module Sidekiq
28
28
  job.test_and_enque_for_time! time if job && job.valid?
29
29
  rescue => ex
30
30
  # problem somewhere in one job
31
- logger.error "CRON JOB: #{ex.message}"
32
- logger.error "CRON JOB: #{ex.backtrace.first}"
31
+ Sidekiq.logger.error "CRON JOB: #{ex.message}"
32
+ Sidekiq.logger.error "CRON JOB: #{ex.backtrace.first}"
33
33
  handle_exception(ex) if respond_to?(:handle_exception)
34
34
  end
35
35
 
@@ -31,7 +31,7 @@
31
31
  <th><%= t('Status') %></th>
32
32
  <th><%= t('Name') %></th>
33
33
  <th><%= t('Cron string') %></th>
34
- <th><%= t('Last enque') %></th>
34
+ <th><%= t('Last enqueued') %></th>
35
35
  <th width="180"><%= t('Actions')%></th>
36
36
  </thead>
37
37
 
@@ -41,7 +41,9 @@
41
41
  <tr>
42
42
  <td style="<%= style %>"><%= t job.status %></td>
43
43
  <td style="<%= style %>">
44
- <b><%= job.name %></b>
44
+ <a href="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>">
45
+ <b><%= job.name %></b>
46
+ </a>
45
47
  <hr style="margin:3px;border:0;">
46
48
  <small>
47
49
  <% if job.message and job.message.to_s.size > 100 %>
@@ -24,7 +24,7 @@ header.row
24
24
  th = t('Status')
25
25
  th = t('Name')
26
26
  th = t('Cron')
27
- th = t('Last enque')
27
+ th = t('Last enqueued')
28
28
  th width="180px"
29
29
  = t('Actions')
30
30
 
@@ -34,7 +34,8 @@ header.row
34
34
  tr
35
35
  td[style="#{style}"]= job.status
36
36
  td[style="#{style}"]
37
- b job.name
37
+ a href="#{root_path}cron/#{CGI.escape(job.name).gsub('+', '%20')}"
38
+ b = job.name
38
39
  hr style="margin:3px;border:0;"
39
40
  small
40
41
  - if job.message and job.message.to_s.size > 100
@@ -0,0 +1,88 @@
1
+ <header class="row">
2
+ <div class="span col-sm-5 pull-left">
3
+ <h3>
4
+ <%= "#{t('Cron')} #{t('Job')}" %>
5
+ <small><%= @job.name %></small>
6
+ </h3>
7
+ </div>
8
+ <div class="span col-sm-7 pull-right" style="margin-top: 20px; margin-bottom: 10px;">
9
+ <% cron_job_path = "#{root_path}cron/#{CGI.escape(@job.name).gsub('+', '%20')}" %>
10
+ <form action="<%= cron_job_path %>/enque?redirect=<%= cron_job_path %>" class="pull-right" method="post">
11
+ <%= csrf_tag if respond_to?(:csrf_tag) %>
12
+ <input class="btn btn-small pull-left" name="enque" type="submit" value="<%= t('EnqueueNow') %>" />
13
+ </form>
14
+ <% if @job.status == 'enabled' %>
15
+ <form action="<%= cron_job_path %>/disable?redirect=<%= cron_job_path %>" class="pull-right" method="post">
16
+ <%= csrf_tag if respond_to?(:csrf_tag) %>
17
+ <input class="btn btn-small pull-left" name="disable" type="submit" value="<%= t('Disable') %>" />
18
+ </form>
19
+ <% else %>
20
+ <form action="<%= cron_job_path %>/enable?redirect=<%= cron_job_path %>" class="pull-right" method="post">
21
+ <%= csrf_tag if respond_to?(:csrf_tag) %>
22
+ <input class="btn btn-small pull-left" name="enable" type="submit" value="<%= t('Enable') %>" />
23
+ </form>
24
+ <form action="<%= cron_job_path %>/delete" class="pull-right" method="post">
25
+ <%= csrf_tag if respond_to?(:csrf_tag) %>
26
+ <input class="btn btn-danger btn-small" data-confirm="<%= t('AreYouSureDeleteCronJob', :job => @job.name) %>" name="delete" type="submit" value="<%= t('Delete') %>" />
27
+ </form>
28
+ <% end %>
29
+ </div>
30
+ </header>
31
+
32
+ <table class="table table-bordered table-striped">
33
+ <tbody>
34
+ <tr>
35
+ <th><%= t 'Status' %></th>
36
+ <td><%= @job.status %></td>
37
+ </tr>
38
+ <tr>
39
+ <th><%= t 'Name' %></th>
40
+ <td><%= @job.name %></td>
41
+ </tr>
42
+ <tr>
43
+ <th><%= t 'Description' %></th>
44
+ <td><%= @job.description %></td>
45
+ </tr>
46
+ <tr>
47
+ <th><%= t 'Message' %></th>
48
+ <td><pre><%= @job.pretty_message %></pre></td>
49
+ </tr>
50
+ <tr>
51
+ <th><%= t 'Cron' %></th>
52
+ <td><%= @job.cron.gsub(" ", "&nbsp;") %></td>
53
+ </tr>
54
+ <tr>
55
+ <th><%= t 'Last enqueued' %></th>
56
+ <td><%= @job.last_enqueue_time ? relative_time(@job.last_enqueue_time) : "-" %></td>
57
+ </tr>
58
+ </tbody>
59
+ </table>
60
+
61
+ <header class="row">
62
+ <div class="col-sm-12">
63
+ <h4>
64
+ <%= t 'History' %>
65
+ </h4>
66
+ </div>
67
+ </header>
68
+
69
+ <% if @job.jid_history_from_redis.size > 0 %>
70
+ <table class="table table-hover table-bordered table-striped">
71
+ <thead>
72
+ <tr>
73
+ <th><%= t 'Enqueued' %></th>
74
+ <th><%= t 'JID' %></th>
75
+ </tr>
76
+ </thead>
77
+ <tbody>
78
+ <% @job.jid_history_from_redis.each do |jid_history| %>
79
+ <tr>
80
+ <td><%= jid_history['enqueued'] %></td>
81
+ <td><%= jid_history['jid'] %></td>
82
+ </tr>
83
+ <% end %>
84
+ </tbody>
85
+ </table>
86
+ <% else %>
87
+ <div class='alert alert-success'><%= t 'NoHistoryWereFound' %></div>
88
+ <% end %>
@@ -0,0 +1,61 @@
1
+ header.row
2
+ .span.col-sm-5.pull-left
3
+ h3
4
+ = "#{t('Cron')} #{t('Job')}"
5
+ small= @job.name
6
+ .span.col-sm-7.pull-right style=("margin-top: 20px; margin-bottom: 10px;")
7
+ - cron_job_path = "#{root_path}cron/#{CGI.escape(@job.name).gsub('+', '%20')}"
8
+ form.pull-right action="#{cron_job_path}/enque?redirect=#{cron_job_path}" method="post"
9
+ = csrf_tag if respond_to?(:csrf_tag)
10
+ input.btn.btn-small.pull-left name="enque" type="submit" value="#{t('EnqueueNow')}"
11
+ - if @job.status == 'enabled'
12
+ form.pull-right action="#{cron_job_path}/disable?redirect=#{cron_job_path}" method="post"
13
+ = csrf_tag if respond_to?(:csrf_tag)
14
+ input.btn.btn-small.pull-left name="disable" type="submit" value="#{t('Disable')}"
15
+ - else
16
+ form.pull-right action="#{cron_job_path}/enable?redirect=#{cron_job_path}" method="post"
17
+ = csrf_tag if respond_to?(:csrf_tag)
18
+ input.btn.btn-small.pull-left name="enable" type="submit" value="#{t('Enable')}"
19
+ form.pull-right action="#{cron_job_path}/delete" method="post"
20
+ = csrf_tag if respond_to?(:csrf_tag)
21
+ input.btn.btn-danger.btn-small data-confirm="#{t('AreYouSureDeleteCronJob' job =@job.name)}" name="delete" type="submit" value="#{t('Delete')}" /
22
+
23
+ table.table.table-bordered.table-striped
24
+ tbody
25
+ tr
26
+ th= t 'Status'
27
+ td= @job.status
28
+ tr
29
+ th= t 'Name'
30
+ td= @job.name
31
+ tr
32
+ th= t 'Description'
33
+ td= @job.description
34
+ tr
35
+ th= t 'Message'
36
+ td
37
+ pre= @job.pretty_message
38
+ tr
39
+ th= t 'Cron'
40
+ td= @job.cron.gsub(" ", "&nbsp;")
41
+ tr
42
+ th= t 'Last enqueued'
43
+ td= @job.last_enqueue_time ? relative_time(@job.last_enqueue_time) : "-"
44
+
45
+ header.row
46
+ .col-sm-12
47
+ h4= t 'History'
48
+
49
+ - if @job.jid_history_from_redis.size > 0
50
+ table.table.table-hover.table-bordered.table-striped
51
+ thead
52
+ tr
53
+ th= t 'Enqueued'
54
+ th= t 'JID'
55
+ tbody
56
+ - @job.jid_history_from_redis.each do |jid_history|
57
+ tr
58
+ td= jid_history['enqueued']
59
+ td= jid_history['jid']
60
+ - else
61
+ .alert.alert-success= t 'NoHistoryWereFound'
@@ -20,6 +20,23 @@ module Sidekiq
20
20
  end
21
21
  end
22
22
 
23
+ # display job detail + jid history
24
+ app.get '/cron/:name' do
25
+ view_path = File.join(File.expand_path("..", __FILE__), "views")
26
+
27
+ @job = Sidekiq::Cron::Job.find(route_params[:name])
28
+ if @job
29
+ #if Slim renderer exists and sidekiq has layout.slim in views
30
+ if defined?(Slim) && File.exists?(File.join(settings.views,"layout.slim"))
31
+ render(:slim, File.read(File.join(view_path, "cron_show.slim")))
32
+ else
33
+ render(:erb, File.read(File.join(view_path, "cron_show.erb")))
34
+ end
35
+ else
36
+ redirect "#{root_path}cron"
37
+ end
38
+ end
39
+
23
40
  #enque cron job
24
41
  app.post '/cron/:name/enque' do
25
42
  if route_params[:name] === '__all__'
@@ -27,7 +44,7 @@ module Sidekiq
27
44
  elsif job = Sidekiq::Cron::Job.find(route_params[:name])
28
45
  job.enque!
29
46
  end
30
- redirect "#{root_path}cron"
47
+ redirect params['redirect'] || "#{root_path}cron"
31
48
  end
32
49
 
33
50
  #delete schedule
@@ -47,7 +64,7 @@ module Sidekiq
47
64
  elsif job = Sidekiq::Cron::Job.find(route_params[:name])
48
65
  job.enable!
49
66
  end
50
- redirect "#{root_path}cron"
67
+ redirect params['redirect'] || "#{root_path}cron"
51
68
  end
52
69
 
53
70
  #disable job
@@ -57,7 +74,7 @@ module Sidekiq
57
74
  elsif job = Sidekiq::Cron::Job.find(route_params[:name])
58
75
  job.disable!
59
76
  end
60
- redirect "#{root_path}cron"
77
+ redirect params['redirect'] || "#{root_path}cron"
61
78
  end
62
79
 
63
80
  end
data/sidekiq-cron.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: sidekiq-cron 1.0.4 ruby lib
5
+ # stub: sidekiq-cron 1.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "sidekiq-cron".freeze
9
- s.version = "1.0.4"
9
+ s.version = "1.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Ondrej Bartas".freeze]
14
- s.date = "2018-08-15"
14
+ s.date = "2020-04-03"
15
15
  s.description = "Enables to set jobs to be run in specified time (using CRON notation)".freeze
16
16
  s.email = "ondrej@bartas.cz".freeze
17
17
  s.extra_rdoc_files = [
@@ -44,6 +44,8 @@ Gem::Specification.new do |s|
44
44
  "lib/sidekiq/cron/support.rb",
45
45
  "lib/sidekiq/cron/views/cron.erb",
46
46
  "lib/sidekiq/cron/views/cron.slim",
47
+ "lib/sidekiq/cron/views/cron_show.erb",
48
+ "lib/sidekiq/cron/views/cron_show.slim",
47
49
  "lib/sidekiq/cron/web.rb",
48
50
  "lib/sidekiq/cron/web_extension.rb",
49
51
  "sidekiq-cron.gemspec",
@@ -55,7 +57,7 @@ Gem::Specification.new do |s|
55
57
  ]
56
58
  s.homepage = "http://github.com/ondrejbartas/sidekiq-cron".freeze
57
59
  s.licenses = ["MIT".freeze]
58
- s.rubygems_version = "2.5.2.1".freeze
60
+ s.rubygems_version = "2.5.2.3".freeze
59
61
  s.summary = "Sidekiq Cron helps to add repeated scheduled jobs".freeze
60
62
 
61
63
  if s.respond_to? :specification_version then
@@ -6,9 +6,7 @@ describe 'Performance Poller' do
6
6
  X = 10000
7
7
  before do
8
8
  Sidekiq.redis = REDIS
9
- Sidekiq.redis do |conn|
10
- conn.flushdb
11
- end
9
+ Redis.current.flushdb
12
10
 
13
11
  #clear all previous saved data from redis
14
12
  Sidekiq.redis do |conn|
@@ -33,7 +31,7 @@ describe 'Performance Poller' do
33
31
  Time.stubs(:now).returns(enqueued_time)
34
32
  end
35
33
 
36
- it 'should enqueue 10000 jobs in less than 30s' do
34
+ it 'should enqueue 10000 jobs in less than 40s' do
37
35
  Sidekiq.redis do |conn|
38
36
  assert_equal 0, conn.llen("queue:default"), 'Queue should be empty'
39
37
  end
@@ -47,6 +45,6 @@ describe 'Performance Poller' do
47
45
  end
48
46
 
49
47
  puts "Performance test finished in #{bench.real}"
50
- assert_operator bench.real, :<, 30
48
+ assert_operator bench.real, :<, 40
51
49
  end
52
50
  end
data/test/test_helper.rb CHANGED
@@ -20,7 +20,7 @@ Coveralls.wear!
20
20
  require "minitest/autorun"
21
21
  require 'shoulda-context'
22
22
  require "rack/test"
23
- require "mocha/setup"
23
+ require 'mocha/minitest'
24
24
 
25
25
  ENV['RACK_ENV'] = 'test'
26
26
 
@@ -66,6 +66,13 @@ end
66
66
 
67
67
  module ActiveJob
68
68
  class Base
69
+ attr_accessor *%i[job_class provider_job_id queue_name arguments]
70
+
71
+ def initialize
72
+ yield self if block_given?
73
+ self.provider_job_id ||= SecureRandom.hex(12)
74
+ end
75
+
69
76
  def self.queue_name_prefix
70
77
  @queue_name_prefix
71
78
  end
@@ -80,12 +87,16 @@ module ActiveJob
80
87
  self
81
88
  end
82
89
 
90
+ def try(method, *args, &block)
91
+ send method, *args, &block if respond_to? method
92
+ end
93
+
83
94
  def self.perform_later(*args)
84
- {
85
- "job_class" => self.class.name,
86
- "queue_name" => @queue,
87
- "args" => [*args],
88
- }
95
+ new do |instance|
96
+ instance.job_class = self.class.name
97
+ instance.queue_name = @queue
98
+ instance.arguments = [*args]
99
+ end
89
100
  end
90
101
  end
91
102
  end
@@ -223,6 +223,34 @@ describe "Cron Job" do
223
223
  "class"=>"CronTestClassWithQueue",
224
224
  "args"=>[]}
225
225
  end
226
+
227
+ it "be initialized with 'class' and date_as_argument" do
228
+ job = Sidekiq::Cron::Job.new('class' => 'CronTestClassWithQueue', "date_as_argument" => true)
229
+
230
+ job_message = job.message
231
+ job_args = job_message.delete("args")
232
+ assert_equal job_message, {"retry"=>false,
233
+ "queue"=>:super,
234
+ "backtrace"=>true,
235
+ "class"=>"CronTestClassWithQueue"}
236
+ assert job_args[-1].is_a?(Float)
237
+ assert job_args[-1].between?(Time.now.to_f - 1, Time.now.to_f)
238
+ end
239
+
240
+ it "be initialized with 'class', 2 arguments and date_as_argument" do
241
+ job = Sidekiq::Cron::Job.new('class' => 'CronTestClassWithQueue', "date_as_argument" => true, "args"=> ["arg1", :arg2])
242
+
243
+ job_message = job.message
244
+ job_args = job_message.delete("args")
245
+ assert_equal job_message, {"retry"=>false,
246
+ "queue"=>:super,
247
+ "backtrace"=>true,
248
+ "class"=>"CronTestClassWithQueue"}
249
+ assert job_args[-1].is_a?(Float)
250
+ assert job_args[-1].between?(Time.now.to_f - 1, Time.now.to_f)
251
+ assert_equal job_args[0..-2], ["arg1", :arg2]
252
+ end
253
+
226
254
  end
227
255
 
228
256
  describe "cron test" do
@@ -381,7 +409,7 @@ describe "Cron Job" do
381
409
 
382
410
  it 'pushes to queue active jobs message' do
383
411
  @job.expects(:enqueue_active_job)
384
- .returns(true)
412
+ .returns(ActiveJobCronTestClass.new)
385
413
  @job.enque!
386
414
  end
387
415
  end
@@ -399,7 +427,7 @@ describe "Cron Job" do
399
427
 
400
428
  it 'pushes to queue active jobs message with queue_name_prefix' do
401
429
  @job.expects(:enqueue_active_job)
402
- .returns(true)
430
+ .returns(ActiveJobCronTestClass.new)
403
431
  @job.enque!
404
432
  end
405
433
  end
@@ -907,7 +935,8 @@ describe "Cron Job" do
907
935
  @jobs_hash['name_of_job']['cron'] = "bad cron"
908
936
  out = Sidekiq::Cron::Job.load_from_hash @jobs_hash
909
937
  assert_equal 1, out.size, "should have 1 error"
910
- assert_equal ({"name_of_job"=>["'cron' -> \"bad cron\" -> ArgumentError: not a cron string \"bad cron\""]}), out
938
+ assert_includes out['name_of_job'].first, "bad cron"
939
+ assert_includes out['name_of_job'].first, "ArgumentError:"
911
940
  assert_equal 1, Sidekiq::Cron::Job.all.size, "Should have only 1 job after load"
912
941
  end
913
942
 
@@ -5,9 +5,7 @@ require './test/test_helper'
5
5
  describe 'Cron Poller' do
6
6
  before do
7
7
  Sidekiq.redis = REDIS
8
- Sidekiq.redis do |conn|
9
- conn.flushdb
10
- end
8
+ Redis.current.flushdb
11
9
 
12
10
  #clear all previous saved data from redis
13
11
  Sidekiq.redis do |conn|
@@ -9,7 +9,7 @@ describe 'Cron web' do
9
9
 
10
10
  before do
11
11
  Sidekiq.redis = REDIS
12
- Sidekiq.redis {|c| c.flushdb }
12
+ Redis.current.flushdb
13
13
 
14
14
  #clear all previous saved data from redis
15
15
  Sidekiq.redis do |conn|
@@ -66,6 +66,25 @@ describe 'Cron web' do
66
66
  @cron_job_name = "TesQueueNameOfCronJob"
67
67
  end
68
68
 
69
+ it 'shows history of a cron job' do
70
+ @job.enque!
71
+ get "/cron/#{@name}"
72
+
73
+ jid =
74
+ Sidekiq.redis do |conn|
75
+ history = conn.lrange Sidekiq::Cron::Job.jid_history_key(@name), 0, -1
76
+ Sidekiq.load_json(history.last)['jid']
77
+ end
78
+
79
+ assert last_response.body.include?(jid)
80
+ end
81
+
82
+ it 'redirects to cron path when name not found' do
83
+ get '/cron/some-fake-name'
84
+
85
+ assert_match %r{\/cron\z}, last_response['Location']
86
+ end
87
+
69
88
  it "disable and enable all cron jobs" do
70
89
  post "/cron/__all__/disable"
71
90
  assert_equal Sidekiq::Cron::Job.find(@name).status, "disabled"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-cron
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ondrej Bartas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-15 00:00:00.000000000 Z
11
+ date: 2020-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -309,6 +309,8 @@ files:
309
309
  - lib/sidekiq/cron/support.rb
310
310
  - lib/sidekiq/cron/views/cron.erb
311
311
  - lib/sidekiq/cron/views/cron.slim
312
+ - lib/sidekiq/cron/views/cron_show.erb
313
+ - lib/sidekiq/cron/views/cron_show.slim
312
314
  - lib/sidekiq/cron/web.rb
313
315
  - lib/sidekiq/cron/web_extension.rb
314
316
  - sidekiq-cron.gemspec
@@ -337,7 +339,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
337
339
  version: '0'
338
340
  requirements: []
339
341
  rubyforge_project:
340
- rubygems_version: 2.5.2.1
342
+ rubygems_version: 2.5.2.3
341
343
  signing_key:
342
344
  specification_version: 4
343
345
  summary: Sidekiq Cron helps to add repeated scheduled jobs