sidekiq-scheduler 3.1.0 → 3.1.1

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
  SHA256:
3
- metadata.gz: 7c9e10cdd3a2bfc144f07860038c95ef459bb2bf8800d763ea90379b6c709472
4
- data.tar.gz: 8f4be75200f8a5c44f53227ba73586e5e6ac9e8885972163382b372372086af0
3
+ metadata.gz: aff61224563645891063110d5f9ae5d16e6ccb0fee92df6a5f26976d0169c01b
4
+ data.tar.gz: d8a6ac2c6e17426bc095904ac3721a9433a21cfd1be433e5f280b9af5469954a
5
5
  SHA512:
6
- metadata.gz: e8dc47d6600676d0de6cac9b508026315c2eefcf6a055b496abd84ed663ec9bb9eddc267246ba877588ec4abb67d79a773664238d1028e23ca2859869e76dedd
7
- data.tar.gz: 78764a88d67d2c501a4df10a8d7b79331146912a4d5fa2c83a04e1b06165bd45ceec0a11232e8e841fc452d6fd79e985142ad72a945e4fc04a8d79aa7090f79c
6
+ metadata.gz: b01ea69bb3bafd959681e3f7cb3a5699385bdf73bf8abeb8e75a6e2765ec1476862f1d499046ae00233539ec266d313c55c03558961fab8f02b048e4164778bd
7
+ data.tar.gz: 7662c439f79b05f2954cfc0e1da2d0a84236334f75101431ed187ae8c69df47baa52cbee901e90a84e81b7ed5b7f81198938ca09cf3710f5885866b334cfcb43
data/README.md CHANGED
@@ -179,6 +179,14 @@ Cron, every, and interval types push jobs into sidekiq in a recurrent manner.
179
179
  every: '45m' # Runs every 45 minutes
180
180
  ```
181
181
 
182
+ The value is parsed by [`Fugit::Duration.parse`](https://github.com/floraison/fugit#fugitduration). It understands quite a number of formats, including human-readable ones:
183
+
184
+ ``` yaml
185
+ every: 45 minutes
186
+ every: 2 hours and 30 minutes
187
+ every: 1.5 hours
188
+ ```
189
+
182
190
  `interval` is similar to `every`, the difference between them is that `interval` type schedules the
183
191
  next execution after the interval has elapsed counting from its last job enqueue.
184
192
 
@@ -313,6 +321,19 @@ Non-normal conditions that could push a specific job multiple times are:
313
321
 
314
322
  `every`, `interval` and `in` jobs will be pushed once per host.
315
323
 
324
+ ## Notes on when sidekiq worker is down
325
+
326
+ For a `cron`/`at` (and all other) job to be successfully enqueued, you need at least one sidekiq worker with scheduler to be up at that moment. Handling this is up to you and depends on your application.
327
+
328
+ Possible solutions include:
329
+ - Simply ignoring this fact, if you only run frequent periodic jobs, that can tolerate some increased interval
330
+ - Abstaining from deploys/restarts during time when critical jobs are usually scheduled
331
+ - Making your infrequent jobs idempotent (so that they can be enqueued multiple times but still produce result as if was run once) and scheduling them multiple times to reduce likelihood of not being run
332
+ - Zero downtime deploy for sidekiq workers: keep at least one worker up during whole deploy and only restart/shut it down after when new one has started
333
+ - Running scheduler inside your unicorn/rails processes (if you already have zero downtime deploy set up for these)
334
+
335
+ Each option has it's own pros and cons.
336
+
316
337
  ## Sidekiq Web Integration
317
338
 
318
339
  sidekiq-scheduler provides an extension to the Sidekiq web interface that adds a `Recurring Jobs` page.
@@ -1,5 +1,11 @@
1
1
  require 'sidekiq/web' unless defined?(Sidekiq::Web)
2
2
 
3
+ ASSETS_PATH = File.expand_path('../../../web/assets', __dir__)
4
+
3
5
  Sidekiq::Web.register(SidekiqScheduler::Web)
4
6
  Sidekiq::Web.tabs['recurring_jobs'] = 'recurring-jobs'
5
- Sidekiq::Web.locales << File.expand_path(File.dirname(__FILE__) + '/../../../web/locales')
7
+ Sidekiq::Web.locales << File.expand_path("#{File.dirname(__FILE__)}/../../../web/locales")
8
+ Sidekiq::Web.use Rack::Static, urls: ['/stylesheets'],
9
+ root: ASSETS_PATH,
10
+ cascade: true,
11
+ header_rules: [[:all, { 'Cache-Control' => 'public, max-age=86400' }]]
@@ -37,10 +37,6 @@ module SidekiqScheduler
37
37
  @scheduler_instance.load_schedule!
38
38
  end
39
39
 
40
- def reset
41
- clear_scheduled_work
42
- end
43
-
44
40
  private
45
41
 
46
42
  def load_scheduler_options(options)
@@ -97,10 +97,11 @@ module SidekiqScheduler
97
97
  # @return [Boolean] true if the schedules key is set, false otherwise
98
98
  def self.schedule_exist?
99
99
  Sidekiq.redis do |r|
100
- if r.respond_to?(:exists?)
101
- r.exists?(:schedules)
100
+ case r.exists(:schedules)
101
+ when true, 1
102
+ true
102
103
  else
103
- !!r.exists(:schedules)
104
+ false
104
105
  end
105
106
  end
106
107
  end
@@ -1,5 +1,5 @@
1
1
  module SidekiqScheduler
2
2
 
3
- VERSION = '3.1.0'
3
+ VERSION = '3.1.1'
4
4
 
5
5
  end
@@ -15,13 +15,13 @@ module SidekiqScheduler
15
15
  erb File.read(File.join(VIEW_PATH, 'recurring_jobs.erb'))
16
16
  end
17
17
 
18
- app.get '/recurring-jobs/:name/enqueue' do
18
+ app.post '/recurring-jobs/:name/enqueue' do
19
19
  schedule = Sidekiq.get_schedule(params[:name])
20
20
  SidekiqScheduler::Scheduler.instance.enqueue_job(schedule)
21
21
  redirect "#{root_path}recurring-jobs"
22
22
  end
23
23
 
24
- app.get '/recurring-jobs/:name/toggle' do
24
+ app.post '/recurring-jobs/:name/toggle' do
25
25
  Sidekiq.reload_schedule!
26
26
 
27
27
  SidekiqScheduler::Scheduler.instance.toggle_job_enabled(params[:name])
@@ -0,0 +1,23 @@
1
+ .recurring-jobs { border-top-left-radius: 4px; border-top-right-radius: 4px; }
2
+ .recurring-jobs .title { margin-bottom: 5px; }
3
+ .recurring-jobs .title .name { font-weight: bold;}
4
+ .recurring-jobs .info,
5
+ .recurring-jobs .description { margin-bottom: 5px; }
6
+ .recurring-jobs .actions { margin-bottom: 5px; }
7
+ .recurring-jobs .status,
8
+ .recurring-jobs .description { font-size: 12px; }
9
+ .recurring-jobs .enqueue { margin-bottom: 0.5rem }
10
+
11
+ .list-group-item {
12
+ background-color: #f3f3f3;
13
+ color: #585454;
14
+ border: 1px solid rgba(0, 0, 0, 0.1);
15
+ }
16
+
17
+ @media (prefers-color-scheme: dark) {
18
+ .list-group-item {
19
+ background-color: #222;
20
+ color: white;
21
+ border: 1px solid #555;
22
+ }
23
+ }
@@ -1,48 +1,50 @@
1
- <h3><%= t('recurring_jobs') %></h3>
1
+ <link href="<%= root_path %>stylesheets/recurring_jobs.css" media="screen" rel="stylesheet" type="text/css" />
2
2
 
3
- <div class="table_container">
4
- <table class="table table-hover table-bordered table-striped table-white">
5
- <thead>
6
- <tr>
7
- <th><%= t('name') %></th>
8
- <th><%= t('description') %></th>
9
- <th><%= t('interval') %></th>
10
- <th><%= t('class') %></th>
11
- <th><%= t('queue') %></th>
12
- <th><%= t('arguments') %></th>
13
- <th><%= t('last_time') %></th>
14
- <th><%= t('next_time') %></th>
15
- <th></th>
16
- </tr>
17
- </thead>
3
+ <h3><%= t('recurring_jobs') %></h3>
18
4
 
19
- <tbody>
20
- <% @presented_jobs.each do |job| %>
21
- <tr>
22
- <td><%= job.name %></td>
23
- <td><%= job['description'] %></td>
24
- <td><%= job.interval %></td>
25
- <td><%= job['class'] %></td>
26
- <td>
27
- <a href="<%= root_path %>queues/<%= job.queue %>"><%= job.queue %></a>
28
- </td>
29
- <td><%= job['args'] %></td>
30
- <td><%= job.last_time %></td>
31
- <td>
32
- <span style="<%= 'text-decoration:line-through' unless job.enabled? %>">
33
- <%= job.next_time || t('no_next_time') %>
5
+ <div class="recurring-jobs">
6
+ <ul class="list-group">
7
+ <% @presented_jobs.each do |job| %>
8
+ <li class="list-group-item">
9
+ <div class="title">
10
+ <div class="row">
11
+ <div class="col-xs-6">
12
+ <span class="name"><%= job.name %></span>
13
+ </div>
14
+ <div class="col-xs-6 text-right">
15
+ <a href="<%= root_path %>queues/<%= job.queue %>"><%= job.queue %></a>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ <div class="description"><%= job['description'] %></div>
20
+ <div class="info">
21
+ <div class="row">
22
+ <div class="col-md-4 class"><%= job['class'] %></div>
23
+ <div class="col-md-4 interval text-left"><%= t('interval') %>: <%= job.interval %></div>
24
+ <div class="col-md-4 args"><%= t('arguments') %>: <%= job['args'] %></div>
25
+ </div>
26
+ </div>
27
+ <div class="status row">
28
+ <div class="col-md-4 actions">
29
+ <form action="<%= root_path %>recurring-jobs/<%= ERB::Util.url_encode(job.name) %>/enqueue" method="post" class="enqueue">
30
+ <%= csrf_tag %>
31
+ <input type="submit" class="btn btn-warn btn-xs" value="<%= t('enqueue_now') %>" />
32
+ </form>
33
+ <form action="<%= root_path %>recurring-jobs/<%= ERB::Util.url_encode(job.name) %>/toggle" method="post">
34
+ <%= csrf_tag %>
35
+ <input type="submit" class="btn <%= job.enabled? ? "btn-primary" : "btn-warn"%> btn-xs" value="<%= job.enabled? ? t('disable') : t('enable') %>" />
36
+ </form>
37
+ </div>
38
+ <div class="col-md-4">
39
+ <span class="last_time"><%= t('last_time') %>: <%= job.last_time %></span>
40
+ </div>
41
+ <div class="col-md-4">
42
+ <span class="next_time text-right" style="<%= 'text-decoration:line-through' unless job.enabled? %>">
43
+ <%= t('next_time') %>: <%= job.next_time || t('no_next_time') %>
34
44
  </span>
35
- </td>
36
- <td class="text-center">
37
- <a class="btn btn-warn btn-xs" href="<%= root_path %>recurring-jobs/<%= ERB::Util.url_encode(job.name) %>/enqueue">
38
- <%= t('enqueue_now') %>
39
- </a>
40
- <a class="btn <%= job.enabled? ? "btn-primary" : "btn-warn"%> btn-xs" href="<%= root_path %>recurring-jobs/<%= ERB::Util.url_encode(job.name) %>/toggle">
41
- <%= job.enabled? ? t('disable') : t('enable') %>
42
- </a>
43
- </td>
44
- </tr>
45
- <% end %>
46
- </tbody>
47
- </table>
45
+ </div>
46
+ </div>
47
+ </li>
48
+ <% end %>
49
+ </ul>
48
50
  </div>
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Morton Jonuschat
8
8
  - Moove-it
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-05-31 00:00:00.000000000 Z
12
+ date: 2022-01-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sidekiq
@@ -279,6 +279,7 @@ files:
279
279
  - lib/sidekiq-scheduler/version.rb
280
280
  - lib/sidekiq-scheduler/web.rb
281
281
  - lib/sidekiq/scheduler.rb
282
+ - web/assets/stylesheets/recurring_jobs.css
282
283
  - web/locales/cs.yml
283
284
  - web/locales/de.yml
284
285
  - web/locales/en.yml
@@ -297,7 +298,7 @@ homepage: https://moove-it.github.io/sidekiq-scheduler/
297
298
  licenses:
298
299
  - MIT
299
300
  metadata: {}
300
- post_install_message:
301
+ post_install_message:
301
302
  rdoc_options: []
302
303
  require_paths:
303
304
  - lib
@@ -312,8 +313,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
312
313
  - !ruby/object:Gem::Version
313
314
  version: '0'
314
315
  requirements: []
315
- rubygems_version: 3.2.18
316
- signing_key:
316
+ rubygems_version: 3.2.19
317
+ signing_key:
317
318
  specification_version: 4
318
319
  summary: Light weight job scheduling extension for Sidekiq
319
320
  test_files: []