sidekiq-scheduler 5.0.3 → 5.0.4

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: d26f3947b1ef031bc393203e79975cfcc5159d32f7ff3d07a1b3858621d167d4
4
- data.tar.gz: f921936d4d0a8f9942e98cc67da8404738af852042e2f8b23e9c818be14c8b26
3
+ metadata.gz: 17e9ebdeaa24ce323d7b3f94c7481d741e0f0f6d3daeded5eaef94f8b1e09f37
4
+ data.tar.gz: c8e1d62c30406b7928444bdd05a0668aac6bbb47c1bc6a752ff795dbf67b8bb2
5
5
  SHA512:
6
- metadata.gz: 1fdea51e227d0eafcce6cc6973e9e9349788ffd3ff947c3967ca4eceae7fe4c47ec485a72194c36e11b623a3cfa372ba583d6305df57896d7c39fc6c3f687618
7
- data.tar.gz: c217f9992d5cb3fcb78d11dae5273cccdae276fd2d6a7c1166b4faf6aae92ad3b8c2253af2f4f94fffca4027fe0c9ca6720386cb7406d592baa514b63ee5f6ef
6
+ metadata.gz: f94c5008ef8a2ec39837adc8a25145b27c15abf2514ba22f9c2341b1306431aecfcceb877f8b07fe05c0daa09e26e6b4df3f6e10c118893fe78b11ca6b6751cb
7
+ data.tar.gz: 61e7f37615f1c575d51c0e55593c4a82362829e21533182e60ec7a125fe76273e44bc055f6449a43185c083370eb1e416a0f1031671e537b6b85cec0ff3a218b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # 5.0.4
2
+ - [**FIX**] Ensure rufus-scheduler has a default rufus_scheduler_options value [#434](https://github.com/sidekiq-scheduler/sidekiq-scheduler/issues/426)
3
+ - [**ENHANCEMENT**] Remove code related to sidekiq < 6 [#443](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/443)
4
+ - [**ENHANCEMENT**] Change cache-control to `private` [#446](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/446)
5
+ - [**ENHANCEMENT**] Increase compatibility range with tilt dependency [#458](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/458)
6
+ - [**ENHANCEMENT**] Ensure we support Ruby 3.3 [#461](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/461)
7
+ - [**ENHANCEMENT**] Use Redis MULTI command (https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/464)
8
+ - [**ENHANCEMENT**] Don't attempt to set jon next_time when job is nil [#466](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/466)
9
+ - [**ENHANCEMENT**] Improvements to prevent jobs been enqueued multiple times due to a delay in job execution [#463](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/463)
10
+ - [**FIX**] Prevent stack level too deep error by implementing `to_hash` method [#470](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/470)
11
+ - [**ENHANCEMENT**] Support new Sidekiq model for registering UI plugins [#472](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/472)
12
+ - [**ENHANCEMENT**] Stop testing against Ruby 2.7 and 3.0 [#472](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/472#discussion_r1663197863)
13
+ - [**ENHANCEMENT**] Display `at` and `in` in the dashboard [#291](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/291)
14
+ - [**ENHANCEMENT**] Docs enhancements [#442](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/442), [#449](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/449), [#457](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/457), [#465](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/465), [58e1835](https://github.com/sidekiq-scheduler/sidekiq-scheduler/commit/58e18351054fc3c264b2b5a684173316f674c386)
15
+
16
+
1
17
  # 5.0.3
2
18
 
3
19
  - [**FIX**] Fix "uppercase character in header name: Cache-Control" [#432](https://github.com/sidekiq-scheduler/sidekiq-scheduler/pull/432)
data/README.md CHANGED
@@ -45,6 +45,8 @@ class HelloWorld
45
45
  end
46
46
  ```
47
47
 
48
+ __Note:__ In Sidekiq v6.3 `Sidekiq::Job` was introduced as an alias for `Sidekiq::Worker`. `Sidekiq::Worker` has been officially deprecated in Sidekiq v7 although it still exists for backwards compatibility. It is therefore recommended to use `include Sidekiq::Job` in the above example unless an older version of Sidekiq is required.
49
+
48
50
  ``` yaml
49
51
  # config/sidekiq.yml
50
52
 
@@ -55,6 +57,9 @@ end
55
57
  class: HelloWorld
56
58
  ```
57
59
 
60
+ > [!NOTE]
61
+ > sidekiq-scheduler uses [fugit](https://github.com/floraison/fugit) under the hood, which supports up to six arguments as the cron string, [see](https://github.com/floraison/fugit?tab=readme-ov-file#the-second-extension).
62
+
58
63
  Run sidekiq:
59
64
 
60
65
  ``` sh
@@ -122,7 +127,7 @@ The schedule is configured through the `:scheduler:` -> `:schedule` config entry
122
127
 
123
128
  # Deconstructs a hash defined as the `args` to keyword arguments.
124
129
  #
125
- # `flase` by default.
130
+ # `false` by default.
126
131
  #
127
132
  # Example
128
133
  #
@@ -208,7 +213,7 @@ At, and in types push jobs only once. `at` schedules in a point in time:
208
213
  at: '3001/01/01'
209
214
  ```
210
215
 
211
- You can specify any string that `DateTime.parse` and `Chronic` understand. To enable Chronic
216
+ You can specify any string that `DateTime.parse` and `Chronic` understand. To enable [Chronic](https://github.com/mojombo/chronic)
212
217
  strings, you must add it as a dependency.
213
218
 
214
219
  `in` triggers after a time duration has elapsed:
@@ -359,7 +364,7 @@ MyRegularJob:
359
364
  Then we can conditionally load it via an initializer:
360
365
 
361
366
  ```ruby
362
- # config/initializer/sidekiq.rb
367
+ # config/initializers/sidekiq.rb
363
368
  if ENV.fetch("IS_SCHEDULER", false)
364
369
  Sidekiq.configure_server do |config|
365
370
  config.on(:startup) do
@@ -59,6 +59,17 @@ module SidekiqScheduler
59
59
  SidekiqScheduler::SidekiqAdapter.sidekiq_queues(sidekiq_config)
60
60
  end
61
61
 
62
+ def to_hash
63
+ {
64
+ enabled: enabled?,
65
+ dynamic: dynamic?,
66
+ dynamic_every: dynamic_every?,
67
+ shedule: schedule,
68
+ listened_queues_only: listened_queues_only?,
69
+ rufus_scheduler_options: rufus_scheduler_options
70
+ }
71
+ end
72
+
62
73
  private
63
74
 
64
75
  attr_reader :scheduler_config
@@ -1,14 +1,27 @@
1
1
  require 'sidekiq/web' unless defined?(Sidekiq::Web)
2
2
 
3
- ASSETS_PATH = File.expand_path('../../../web/assets', __dir__)
3
+ if SidekiqScheduler::SidekiqAdapter::SIDEKIQ_GTE_7_3_0
4
4
 
5
- Sidekiq::Web.register(SidekiqScheduler::Web)
6
- Sidekiq::Web.tabs['recurring_jobs'] = 'recurring-jobs'
7
- Sidekiq::Web.locales << File.expand_path("#{File.dirname(__FILE__)}/../../../web/locales")
5
+ # Locale and asset cache is configured in `.regiester`
6
+ Sidekiq::Web.register(SidekiqScheduler::Web,
7
+ name: "recurring_jobs",
8
+ tab: ["Recurring Jobs"],
9
+ index: ["recurring-jobs"],
10
+ root_dir: File.expand_path("../../../web", File.dirname(__FILE__)),
11
+ asset_paths: ["stylesheets-scheduler"]) do |app|
12
+ # add middleware or additional settings here
13
+ end
14
+
15
+ else
16
+
17
+ ASSETS_PATH = File.expand_path('../../../web/assets', __dir__)
18
+
19
+ Sidekiq::Web.register(SidekiqScheduler::Web)
20
+ Sidekiq::Web.tabs['recurring_jobs'] = 'recurring-jobs'
21
+ Sidekiq::Web.locales << File.expand_path("#{File.dirname(__FILE__)}/../../../web/locales")
8
22
 
9
- if Sidekiq::VERSION >= '6.0.0'
10
23
  Sidekiq::Web.use Rack::Static, urls: ['/stylesheets-scheduler'],
11
24
  root: ASSETS_PATH,
12
25
  cascade: true,
13
- header_rules: [[:all, { 'cache-control' => 'public, max-age=86400' }]]
26
+ header_rules: [[:all, { 'cache-control' => 'private, max-age=86400' }]]
14
27
  end
@@ -38,7 +38,7 @@ module SidekiqScheduler
38
38
  #
39
39
  # @return [String] with the job's interval
40
40
  def interval
41
- @attributes['cron'] || @attributes['interval'] || @attributes['every']
41
+ @attributes['cron'] || @attributes['interval'] || @attributes['every'] || @attributes['at'] || @attributes['in']
42
42
  end
43
43
 
44
44
  # Returns the queue of the job
@@ -24,6 +24,15 @@ module SidekiqScheduler
24
24
  @scheduler_instance.load_schedule!
25
25
  end
26
26
 
27
+ # This method is needed to avoid exposing unnecessary information.
28
+ # Because ActiveSupport's `as_json` traverses instance values to convert the object to a hash
29
+ # unless it responds to `to_hash`.
30
+ def to_hash
31
+ {
32
+ scheduler: @scheduler_instance.to_hash
33
+ }
34
+ end
35
+
27
36
  private
28
37
 
29
38
  def set_current_scheduler_options(config)
@@ -130,9 +130,9 @@ module SidekiqScheduler
130
130
  def self.register_job_instance(job_name, time)
131
131
  job_key = pushed_job_key(job_name)
132
132
  registered, _ = Sidekiq.redis do |r|
133
- r.pipelined do |pipeline|
134
- pipeline.zadd(job_key, time.to_i, time.to_i)
135
- pipeline.expire(job_key, REGISTERED_JOBS_THRESHOLD_IN_SECONDS)
133
+ r.multi do |m|
134
+ m.zadd(job_key, time.to_i, time.to_i)
135
+ m.expire(job_key, REGISTERED_JOBS_THRESHOLD_IN_SECONDS)
136
136
  end
137
137
  end
138
138
 
@@ -58,7 +58,7 @@ module SidekiqScheduler
58
58
  self.dynamic = config.dynamic?
59
59
  self.dynamic_every = config.dynamic_every?
60
60
  self.listened_queues_only = config.listened_queues_only?
61
- self.rufus_scheduler_options = config.rufus_scheduler_options
61
+ self.rufus_scheduler_options = config.rufus_scheduler_options || {}
62
62
  end
63
63
 
64
64
  # the Rufus::Scheduler jobs that are scheduled
@@ -128,6 +128,8 @@ module SidekiqScheduler
128
128
  schedule, options = SidekiqScheduler::RufusUtils.normalize_schedule_options(config_interval_type)
129
129
 
130
130
  rufus_job = new_job(name, interval_type, config, schedule, options)
131
+ return unless rufus_job
132
+
131
133
  @scheduled_jobs[name] = rufus_job
132
134
  SidekiqScheduler::Utils.update_job_next_time(name, rufus_job.next_time)
133
135
 
@@ -248,6 +250,12 @@ module SidekiqScheduler
248
250
  end
249
251
  end
250
252
 
253
+ def to_hash
254
+ {
255
+ scheduler_config: @scheduler_config.to_hash
256
+ }
257
+ end
258
+
251
259
  private
252
260
 
253
261
  attr_reader :scheduler_config
@@ -256,7 +264,15 @@ module SidekiqScheduler
256
264
  options = options.merge({ :job => true, :tags => [name] })
257
265
 
258
266
  rufus_scheduler.send(interval_type, schedule, options) do |job, time|
259
- idempotent_job_enqueue(name, time, SidekiqScheduler::Utils.sanitize_job_config(config)) if job_enabled?(name)
267
+ if job_enabled?(name)
268
+ conf = SidekiqScheduler::Utils.sanitize_job_config(config)
269
+
270
+ if job.is_a?(Rufus::Scheduler::CronJob)
271
+ idempotent_job_enqueue(name, SidekiqScheduler::Utils.calc_cron_run_time(job.cron_line, time.utc), conf)
272
+ else
273
+ idempotent_job_enqueue(name, time, conf)
274
+ end
275
+ end
260
276
  end
261
277
  end
262
278
 
@@ -4,6 +4,7 @@ module SidekiqScheduler
4
4
  class SidekiqAdapter
5
5
  SIDEKIQ_GTE_6_5_0 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('6.5.0')
6
6
  SIDEKIQ_GTE_7_0_0 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('7.0.0')
7
+ SIDEKIQ_GTE_7_3_0 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('7.3.0')
7
8
 
8
9
  def self.fetch_scheduler_config_from_sidekiq(sidekiq_config)
9
10
  return {} if sidekiq_config.nil?
@@ -141,5 +141,39 @@ module SidekiqScheduler
141
141
  def self.update_job_last_time(name, last_time)
142
142
  SidekiqScheduler::RedisManager.set_job_last_time(name, last_time) if last_time
143
143
  end
144
+
145
+ # Try to figure out when the cron job was supposed to run.
146
+ #
147
+ # Rufus calls the scheduler block with the current time and not the time the block was scheduled to run.
148
+ # This means under certain conditions you could have a job get scheduled multiple times because `time.to_i` is used
149
+ # to key the job in redis. If one server is under load and Rufus tries to run the jobs 1 seconds after the other
150
+ # server then the job will be queued twice.
151
+ # This method essentially makes a best guess at when this job was supposed to run and return that.
152
+ #
153
+ # @param [Fugit::Cron] cron
154
+ # @param [Time] time
155
+ #
156
+ # @return [Time]
157
+ def self.calc_cron_run_time(cron, time)
158
+ time = time.round # remove sub seconds to prevent rounding errors.
159
+ next_t = cron.next_time(time).utc
160
+ previous_t = cron.previous_time(time).utc
161
+ # The `time` var is some point between `previous_t` and `next_t`.
162
+ # Figure out how far off we are from each side in seconds.
163
+ next_diff = next_t - time
164
+ previous_diff = time - previous_t
165
+
166
+ if next_diff == previous_diff
167
+ # In the event `time` is exactly between `previous_t` and `next_t` the diff will not be equal to
168
+ # `cron.rough_frequency`. In that case we round down.
169
+ cron.rough_frequency == next_diff ? time : previous_t
170
+ elsif next_diff > previous_diff
171
+ # We are closer to the previous run time so return that.
172
+ previous_t
173
+ else
174
+ # We are closer to the next run time so return that.
175
+ next_t
176
+ end
177
+ end
144
178
  end
145
179
  end
@@ -1,3 +1,3 @@
1
1
  module SidekiqScheduler
2
- VERSION = "5.0.3"
2
+ VERSION = "5.0.4"
3
3
  end
data/web/locales/cs.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  cs:
2
+ "Recurring Jobs": Pravidelně opakované
2
3
  recurring_jobs: Pravidelně opakované
3
4
  name: Jméno
4
5
  description: Popis
data/web/locales/de.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  de:
2
+ "Recurring Jobs": Wiederkehrende Jobs
2
3
  recurring_jobs: Wiederkehrende Jobs
3
4
  name: Name
4
5
  description: Beschreibung
data/web/locales/en.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  en:
2
+ "Recurring Jobs": Recurring Jobs
2
3
  recurring_jobs: Recurring Jobs
3
4
  name: Name
4
5
  description: Description
data/web/locales/es.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  es:
2
+ "Recurring Jobs": Tareas Recurrentes
2
3
  recurring_jobs: Tareas Recurrentes
3
4
  name: Nombre
4
5
  description: Descripción
data/web/locales/fr.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  fr:
2
+ "Recurring Jobs": Tâches récurrentes
2
3
  recurring_jobs: Tâches récurrentes
3
4
  name: Nom
4
5
  description: Description
data/web/locales/gd.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  gd:
2
+ "Recurring Jobs": Obraichean ath-chùrsach
2
3
  recurring_jobs: Obraichean ath-chùrsach
3
4
  name: Ainm
4
5
  description: Tuairisgeul
data/web/locales/it.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  it:
2
+ "Recurring Jobs": Job ricorrenti
2
3
  recurring_jobs: Job ricorrenti
3
4
  name: Nome
4
5
  description: Descrizione
data/web/locales/ja.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  ja:
2
+ "Recurring Jobs": 定期ジョブ
2
3
  recurring_jobs: 定期ジョブ
3
4
  name: 名前
4
5
  description: 説明
data/web/locales/nl.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  nl:
2
+ "Recurring Jobs": Herhalende taken
2
3
  recurring_jobs: Herhalende taken
3
4
  name: Naam
4
5
  description: Beschrijving
data/web/locales/pl.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  pl:
2
+ "Recurring Jobs": Okresowe
2
3
  recurring_jobs: Okresowe
3
4
  name: Nazwa
4
5
  description: Opis
@@ -1,4 +1,5 @@
1
1
  pt-BR:
2
+ "Recurring Jobs": Jobs Recorrentes
2
3
  recurring_jobs: Jobs Recorrentes
3
4
  name: Nome
4
5
  description: Descrição
@@ -6,7 +7,7 @@ pt-BR:
6
7
  class: Classe
7
8
  queue: Fila
8
9
  arguments: Argumentos
9
- enqueue_now: Enfileirar agora
10
+ enqueue_now: Enfileirar agora
10
11
  last_time: Última execução
11
12
  next_time: Próxima execução
12
13
  no_next_time: Não há mais execuçoẽs
data/web/locales/ru.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  ru:
2
+ "Recurring Jobs": Расписание задач
2
3
  recurring_jobs: Расписание задач
3
4
  name: Название
4
5
  description: Описание
data/web/locales/sv.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  sv:
2
+ "Recurring Jobs": Återkommande jobb
2
3
  recurring_jobs: Återkommande jobb
3
4
  name: Namn
4
5
  description: Beskrivning
@@ -1,4 +1,5 @@
1
1
  zh-cn:
2
+ "Recurring Jobs": 周期作业
2
3
  recurring_jobs: 周期作业
3
4
  name: 名称
4
5
  description: 描述
@@ -1,42 +1,7 @@
1
- <% if Sidekiq::VERSION >= '6.0.0' %>
2
- <link href="<%= root_path %>stylesheets-scheduler/recurring_jobs.css" media="screen" rel="stylesheet" type="text/css" />
1
+ <% if SidekiqScheduler::SidekiqAdapter::SIDEKIQ_GTE_7_3_0 %>
2
+ <%= style_tag "stylesheets-scheduler/recurring_jobs.css" %>
3
3
  <% else %>
4
- <style>
5
- .recurring-jobs { border-top-left-radius: 4px; border-top-right-radius: 4px; }
6
- .recurring-jobs .title { margin-bottom: 5px; }
7
- .recurring-jobs .title .name { font-weight: bold;}
8
- .recurring-jobs .info,
9
- .recurring-jobs .description { margin-bottom: 5px; }
10
- .recurring-jobs .actions { margin-bottom: 5px; }
11
- .recurring-jobs .status,
12
- .recurring-jobs .description { font-size: 12px; }
13
- .recurring-jobs .enqueue { margin-bottom: 0.5rem }
14
-
15
- .list-group-item {
16
- background-color: #f3f3f3;
17
- color: #585454;
18
- border: 1px solid rgba(0, 0, 0, 0.1);
19
- }
20
-
21
- .list-group-item-disabled {
22
- background-color: #f3d3d3;
23
- }
24
-
25
- .toggle-all-buttons {
26
- margin-top: 20px;
27
- margin-bottom: 10px;
28
- line-height: 45px;
29
- text-align: right;
30
- }
31
-
32
- @media (max-width: 768px) {
33
- .toggle-all-buttons {
34
- margin-top: 0;
35
- text-align: left;
36
- line-height: inherit;
37
- }
38
- }
39
- </style>
4
+ <link href="<%= root_path %>stylesheets-scheduler/recurring_jobs.css" media="screen" rel="stylesheet" type="text/css" />
40
5
  <% end %>
41
6
 
42
7
  <div class="row">
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.3
4
+ version: 5.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Morton Jonuschat
8
8
  - Moove-it
9
9
  - Marcelo Lauxen
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-05-31 00:00:00.000000000 Z
13
+ date: 2024-07-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sidekiq
@@ -53,6 +53,9 @@ dependencies:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: 1.4.0
56
+ - - "<"
57
+ - !ruby/object:Gem::Version
58
+ version: '3'
56
59
  type: :runtime
57
60
  prerelease: false
58
61
  version_requirements: !ruby/object:Gem::Requirement
@@ -60,6 +63,9 @@ dependencies:
60
63
  - - ">="
61
64
  - !ruby/object:Gem::Version
62
65
  version: 1.4.0
66
+ - - "<"
67
+ - !ruby/object:Gem::Version
68
+ version: '3'
63
69
  - !ruby/object:Gem::Dependency
64
70
  name: rake
65
71
  requirement: !ruby/object:Gem::Requirement
@@ -234,7 +240,7 @@ homepage: https://sidekiq-scheduler.github.io/sidekiq-scheduler/
234
240
  licenses:
235
241
  - MIT
236
242
  metadata: {}
237
- post_install_message:
243
+ post_install_message:
238
244
  rdoc_options: []
239
245
  require_paths:
240
246
  - lib
@@ -249,8 +255,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
255
  - !ruby/object:Gem::Version
250
256
  version: '0'
251
257
  requirements: []
252
- rubygems_version: 3.2.33
253
- signing_key:
258
+ rubygems_version: 3.5.3
259
+ signing_key:
254
260
  specification_version: 4
255
261
  summary: Light weight job scheduling extension for Sidekiq
256
262
  test_files: []