sidekiq-cron 1.0.4 → 1.2.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 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