sidekiq-scheduler 4.0.2 → 5.0.6

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.
@@ -9,7 +9,7 @@ module SidekiqScheduler
9
9
  #
10
10
  # @return [String] schedule in JSON format
11
11
  def self.get_job_schedule(name)
12
- hget('schedules', name)
12
+ hget(schedules_key, name)
13
13
  end
14
14
 
15
15
  # Returns the state of a given job
@@ -44,7 +44,7 @@ module SidekiqScheduler
44
44
  # @param [String] name The name of the job
45
45
  # @param [Hash] config The new schedule for the job
46
46
  def self.set_job_schedule(name, config)
47
- hset('schedules', name, JSON.generate(config))
47
+ hset(schedules_key, name, JSON.generate(config))
48
48
  end
49
49
 
50
50
  # Sets the state for a given job
@@ -60,7 +60,7 @@ module SidekiqScheduler
60
60
  # @param [String] name The name of the job
61
61
  # @param [String] next_time The next time the job has to be executed
62
62
  def self.set_job_next_time(name, next_time)
63
- hset(next_times_key, name, next_time)
63
+ hset(next_times_key, name, String(next_time))
64
64
  end
65
65
 
66
66
  # Sets the last execution time for a given job
@@ -68,14 +68,14 @@ module SidekiqScheduler
68
68
  # @param [String] name The name of the job
69
69
  # @param [String] last_time The last time the job was executed
70
70
  def self.set_job_last_time(name, last_time)
71
- hset(last_times_key, name, last_time)
71
+ hset(last_times_key, name, String(last_time))
72
72
  end
73
73
 
74
74
  # Removes the schedule for a given job
75
75
  #
76
76
  # @param [String] name The name of the job
77
77
  def self.remove_job_schedule(name)
78
- hdel('schedules', name)
78
+ hdel(schedules_key, name)
79
79
  end
80
80
 
81
81
  # Removes the next execution time for a given job
@@ -89,14 +89,14 @@ module SidekiqScheduler
89
89
  #
90
90
  # @return [Hash] hash with all the job schedules
91
91
  def self.get_all_schedules
92
- Sidekiq.redis { |r| r.hgetall('schedules') }
92
+ Sidekiq.redis { |r| r.hgetall(schedules_key) }
93
93
  end
94
94
 
95
95
  # Returns boolean value that indicates if the schedules value exists
96
96
  #
97
97
  # @return [Boolean] true if the schedules key is set, false otherwise
98
98
  def self.schedule_exist?
99
- Sidekiq.redis { |r| r.exists?('schedules') }
99
+ SidekiqScheduler::SidekiqAdapter.redis_key_exists?(schedules_key)
100
100
  end
101
101
 
102
102
  # Returns all the schedule changes for a given time range.
@@ -106,22 +106,22 @@ module SidekiqScheduler
106
106
  #
107
107
  # @return [Array] array with all the changed job names
108
108
  def self.get_schedule_changes(from, to)
109
- Sidekiq.redis { |r| r.zrangebyscore('schedules_changed', from, "(#{to}") }
109
+ SidekiqScheduler::SidekiqAdapter.redis_zrangebyscore(schedules_changed_key, from, "(#{to}")
110
110
  end
111
111
 
112
112
  # Register a schedule change for a given job
113
113
  #
114
114
  # @param [String] name The name of the job
115
115
  def self.add_schedule_change(name)
116
- Sidekiq.redis { |r| r.zadd('schedules_changed', Time.now.to_f, name) }
116
+ Sidekiq.redis { |r| r.zadd(schedules_changed_key, Time.now.to_f, name) }
117
117
  end
118
118
 
119
119
  # Remove all the schedule changes records
120
120
  def self.clean_schedules_changed
121
- Sidekiq.redis { |r| r.del('schedules_changed') unless r.type('schedules_changed') == 'zset' }
121
+ Sidekiq.redis { |r| r.del(schedules_changed_key) unless r.type(schedules_changed_key) == 'zset' }
122
122
  end
123
123
 
124
- # Removes a queued job instance
124
+ # Registers a queued job instance
125
125
  #
126
126
  # @param [String] job_name The name of the job
127
127
  # @param [Time] time The time at which the job was cleared by the scheduler
@@ -130,13 +130,13 @@ 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
 
139
- registered
139
+ registered.instance_of?(Integer) ? (registered > 0) : registered
140
140
  end
141
141
 
142
142
  # Removes instances of the job older than 24 hours
@@ -156,32 +156,61 @@ module SidekiqScheduler
156
156
  #
157
157
  # @return [String] the pushed job key
158
158
  def self.pushed_job_key(job_name)
159
- "sidekiq-scheduler:pushed:#{job_name}"
159
+ "#{key_prefix}sidekiq-scheduler:pushed:#{job_name}"
160
160
  end
161
161
 
162
162
  # Returns the key of the Redis hash for job's execution times hash
163
163
  #
164
164
  # @return [String] with the key
165
165
  def self.next_times_key
166
- 'sidekiq-scheduler:next_times'
166
+ "#{key_prefix}sidekiq-scheduler:next_times"
167
167
  end
168
168
 
169
169
  # Returns the key of the Redis hash for job's last execution times hash
170
170
  #
171
171
  # @return [String] with the key
172
172
  def self.last_times_key
173
- 'sidekiq-scheduler:last_times'
173
+ "#{key_prefix}sidekiq-scheduler:last_times"
174
174
  end
175
175
 
176
176
  # Returns the Redis's key for saving schedule states.
177
177
  #
178
178
  # @return [String] with the key
179
179
  def self.schedules_state_key
180
- 'sidekiq-scheduler:states'
180
+ "#{key_prefix}sidekiq-scheduler:states"
181
+ end
182
+
183
+ # Returns the Redis's key for saving schedules.
184
+ #
185
+ # @return [String] with the key
186
+ def self.schedules_key
187
+ "#{key_prefix}schedules"
188
+ end
189
+
190
+ # Returns the Redis's key for saving schedule changes.
191
+ #
192
+ # @return [String] with the key
193
+ def self.schedules_changed_key
194
+ "#{key_prefix}schedules_changed"
195
+ end
196
+
197
+ # Returns the key prefix used to generate all scheduler keys
198
+ #
199
+ # @return [String] with the key prefix
200
+ def self.key_prefix
201
+ @key_prefix
202
+ end
203
+
204
+ # Sets the key prefix used to scope all scheduler keys
205
+ #
206
+ # @param [String] value The string to use as the prefix. A ":" will be appended as a delimiter if needed.
207
+ def self.key_prefix=(value)
208
+ value = "#{value}:" if value && !%w[. :].include?(value[-1])
209
+ @key_prefix = value
181
210
  end
182
211
 
183
212
  private
184
-
213
+
185
214
  # Returns the value of a Redis stored hash field
186
215
  #
187
216
  # @param [String] hash_key The key name of the hash
@@ -3,9 +3,9 @@ require 'sidekiq-scheduler/utils'
3
3
  module SidekiqScheduler
4
4
  class RufusUtils
5
5
 
6
- # Normalizes schedule options to rufust scheduler options
6
+ # Normalizes schedule options to rufus scheduler options
7
7
  #
8
- # @param options [String, [Array]
8
+ # @param options [String, Array]
9
9
  #
10
10
  # @return [Array]
11
11
  #
@@ -65,7 +65,7 @@ module SidekiqScheduler
65
65
  end
66
66
  alias_method :schedule!, :reload_schedule!
67
67
 
68
- # Retrive the schedule configuration for the given name
68
+ # Retrieve the schedule configuration for the given name
69
69
  # if the name is nil it returns a hash with all the
70
70
  # names end their schedules.
71
71
  def get_schedule(name = nil)
@@ -148,9 +148,7 @@ module SidekiqScheduler
148
148
  end
149
149
 
150
150
  def try_to_constantize(klass)
151
- klass.is_a?(String) ? klass.constantize : klass
152
- rescue NameError
153
- klass
151
+ SidekiqScheduler::Utils.try_to_constantize(klass)
154
152
  end
155
153
  end
156
154
  end
@@ -2,6 +2,7 @@ require 'rufus/scheduler'
2
2
  require 'json'
3
3
  require 'sidekiq-scheduler/rufus_utils'
4
4
  require 'sidekiq-scheduler/redis_manager'
5
+ require 'sidekiq-scheduler/config'
5
6
 
6
7
  module SidekiqScheduler
7
8
  class Scheduler
@@ -10,6 +11,15 @@ module SidekiqScheduler
10
11
  alias_method :params, :opts
11
12
  end
12
13
 
14
+ # TODO: Can we remove those attr_accessor's? If we need to keep them, we should
15
+ # update those values on the config object instead of just here in the scheduler.
16
+ # That's why we need to do what we do in the set_current_scheduler_options (not
17
+ # saying we will have to do it somehow still)
18
+ #
19
+ # NOTE: ^ Keeping this TODO here for now, in a future version of this project
20
+ # we will remove those attr accessors and use only our config object. For now,
21
+ # let's keep as it is.
22
+
13
23
  # Set to enable or disable the scheduler.
14
24
  attr_accessor :enabled
15
25
 
@@ -41,12 +51,14 @@ module SidekiqScheduler
41
51
  end
42
52
  end
43
53
 
44
- def initialize(options = {})
45
- self.enabled = options[:enabled]
46
- self.dynamic = options[:dynamic]
47
- self.dynamic_every = options[:dynamic_every]
48
- self.listened_queues_only = options[:listened_queues_only]
49
- self.rufus_scheduler_options = options[:rufus_scheduler_options] || {}
54
+ def initialize(config = SidekiqScheduler::Config.new(without_defaults: true))
55
+ @scheduler_config = config
56
+
57
+ self.enabled = config.enabled?
58
+ self.dynamic = config.dynamic?
59
+ self.dynamic_every = config.dynamic_every?
60
+ self.listened_queues_only = config.listened_queues_only?
61
+ self.rufus_scheduler_options = config.rufus_scheduler_options || {}
50
62
  end
51
63
 
52
64
  # the Rufus::Scheduler jobs that are scheduled
@@ -82,7 +94,7 @@ module SidekiqScheduler
82
94
  Sidekiq.logger.info 'Schedule empty! Set Sidekiq.schedule' if Sidekiq.schedule.empty?
83
95
 
84
96
  @scheduled_jobs = {}
85
- queues = sidekiq_queues
97
+ queues = scheduler_config.sidekiq_queues
86
98
 
87
99
  Sidekiq.schedule.each do |name, config|
88
100
  if !listened_queues_only || enabled_queue?(config['queue'].to_s, queues)
@@ -116,6 +128,8 @@ module SidekiqScheduler
116
128
  schedule, options = SidekiqScheduler::RufusUtils.normalize_schedule_options(config_interval_type)
117
129
 
118
130
  rufus_job = new_job(name, interval_type, config, schedule, options)
131
+ return unless rufus_job
132
+
119
133
  @scheduled_jobs[name] = rufus_job
120
134
  SidekiqScheduler::Utils.update_job_next_time(name, rufus_job.next_time)
121
135
 
@@ -158,7 +172,7 @@ module SidekiqScheduler
158
172
  config = prepare_arguments(job_config.dup)
159
173
 
160
174
  if config.delete('include_metadata')
161
- config['args'] = arguments_with_metadata(config['args'], scheduled_at: time.to_f)
175
+ config['args'] = arguments_with_metadata(config['args'], "scheduled_at" => time.to_f.round(3))
162
176
  end
163
177
 
164
178
  if SidekiqScheduler::Utils.active_job_enqueue?(config['class'])
@@ -182,7 +196,7 @@ module SidekiqScheduler
182
196
  @rufus_scheduler = nil
183
197
  end
184
198
 
185
- @@scheduled_jobs = {}
199
+ @scheduled_jobs = {}
186
200
 
187
201
  rufus_scheduler
188
202
  end
@@ -228,13 +242,37 @@ module SidekiqScheduler
228
242
  set_schedule_state(name, state)
229
243
  end
230
244
 
245
+ def toggle_all_jobs(new_state)
246
+ Sidekiq.schedule!.keys.each do |name|
247
+ state = schedule_state(name)
248
+ state['enabled'] = new_state
249
+ set_schedule_state(name, state)
250
+ end
251
+ end
252
+
253
+ def to_hash
254
+ {
255
+ scheduler_config: @scheduler_config.to_hash
256
+ }
257
+ end
258
+
231
259
  private
232
260
 
261
+ attr_reader :scheduler_config
262
+
233
263
  def new_job(name, interval_type, config, schedule, options)
234
264
  options = options.merge({ :job => true, :tags => [name] })
235
265
 
236
266
  rufus_scheduler.send(interval_type, schedule, options) do |job, time|
237
- 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.to_t), conf)
272
+ else
273
+ idempotent_job_enqueue(name, time.to_t, conf)
274
+ end
275
+ end
238
276
  end
239
277
  end
240
278
 
@@ -259,18 +297,18 @@ module SidekiqScheduler
259
297
  # Saves a schedule state
260
298
  #
261
299
  # @param name [String] with the schedule's name
262
- # @param name [Hash] with the schedule's state
300
+ # @param state [Hash] with the schedule's state
263
301
  def set_schedule_state(name, state)
264
302
  SidekiqScheduler::RedisManager.set_job_state(name, state)
265
303
  end
266
304
 
267
305
  # Adds a Hash with schedule metadata as the last argument to call the worker.
268
- # It currently returns the schedule time as a Float number representing the milisencods
306
+ # It currently returns the schedule time as a Float number representing the milliseconds
269
307
  # since epoch.
270
308
  #
271
309
  # @example with hash argument
272
- # arguments_with_metadata({value: 1}, scheduled_at: Time.now)
273
- # #=> [{value: 1}, {scheduled_at: <miliseconds since epoch>}]
310
+ # arguments_with_metadata({value: 1}, scheduled_at: Time.now.round(3))
311
+ # #=> [{value: 1}, {scheduled_at: <milliseconds since epoch>}]
274
312
  #
275
313
  # @param args [Array|Hash]
276
314
  # @param metadata [Hash]
@@ -283,14 +321,6 @@ module SidekiqScheduler
283
321
  end
284
322
  end
285
323
 
286
- def sidekiq_queues
287
- if SIDEKIQ_GTE_6_5_0
288
- Sidekiq[:queues].map(&:to_s)
289
- else
290
- Sidekiq.options[:queues].map(&:to_s)
291
- end
292
- end
293
-
294
324
  # Returns true if a job's queue is included in the array of queues
295
325
  #
296
326
  # If queues are empty, returns true.
@@ -0,0 +1,91 @@
1
+ module SidekiqScheduler
2
+ class OptionNotSupportedAnymore < StandardError; end
3
+
4
+ class SidekiqAdapter
5
+ SIDEKIQ_GTE_6_5_0 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('6.5.0')
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')
8
+
9
+ def self.fetch_scheduler_config_from_sidekiq(sidekiq_config)
10
+ return {} if sidekiq_config.nil?
11
+
12
+ check_using_old_sidekiq_scheduler_config!(sidekiq_config)
13
+
14
+ if SIDEKIQ_GTE_6_5_0
15
+ sidekiq_config.fetch(:scheduler, {})
16
+ else
17
+ sidekiq_config.options.fetch(:scheduler, {})
18
+ end
19
+ end
20
+
21
+ def self.check_using_old_sidekiq_scheduler_config!(sidekiq_config)
22
+ %i[enabled dynamic dynamic_every schedule listened_queues_only rufus_scheduler_options].each do |option|
23
+ if SIDEKIQ_GTE_7_0_0
24
+ if sidekiq_config.key?(option)
25
+ raise OptionNotSupportedAnymore, ":#{option} option should be under the :scheduler: key"
26
+ end
27
+ elsif SIDEKIQ_GTE_6_5_0
28
+ unless sidekiq_config[option].nil?
29
+ raise OptionNotSupportedAnymore, ":#{option} option should be under the :scheduler: key"
30
+ end
31
+ else
32
+ if sidekiq_config.options.key?(option)
33
+ raise OptionNotSupportedAnymore, ":#{option} option should be under the :scheduler: key"
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.start_schedule_manager(sidekiq_config:, schedule_manager:)
40
+ if SIDEKIQ_GTE_6_5_0
41
+ sidekiq_config[:schedule_manager] = schedule_manager
42
+ sidekiq_config[:schedule_manager].start
43
+ else
44
+ sidekiq_config.options[:schedule_manager] = schedule_manager
45
+ sidekiq_config.options[:schedule_manager].start
46
+ end
47
+ end
48
+
49
+ def self.stop_schedule_manager(sidekiq_config:)
50
+ if SIDEKIQ_GTE_6_5_0
51
+ sidekiq_config[:schedule_manager].stop
52
+ else
53
+ sidekiq_config.options[:schedule_manager].stop
54
+ end
55
+ end
56
+
57
+ def self.sidekiq_queues(sidekiq_config)
58
+ if SIDEKIQ_GTE_7_0_0
59
+ if sidekiq_config.nil? || (sidekiq_config.respond_to?(:empty?) && sidekiq_config.empty?)
60
+ Sidekiq.instance_variable_get(:@config).queues.map(&:to_s)
61
+ else
62
+ sidekiq_config.queues.map(&:to_s)
63
+ end
64
+ elsif SIDEKIQ_GTE_6_5_0
65
+ Sidekiq[:queues].map(&:to_s)
66
+ else
67
+ Sidekiq.options[:queues].map(&:to_s)
68
+ end
69
+ end
70
+
71
+ def self.redis_key_exists?(key_name)
72
+ Sidekiq.redis do |r|
73
+ if SIDEKIQ_GTE_7_0_0
74
+ r.exists(key_name) > 0
75
+ else
76
+ r.exists?(key_name)
77
+ end
78
+ end
79
+ end
80
+
81
+ def self.redis_zrangebyscore(key, from, to)
82
+ Sidekiq.redis do |r|
83
+ if SIDEKIQ_GTE_7_0_0
84
+ r.zrange(key, from, to, "BYSCORE")
85
+ else
86
+ r.zrangebyscore(key, from, to)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -49,7 +49,7 @@ module SidekiqScheduler
49
49
  #
50
50
  # @return [Class] the class corresponding to the klass param
51
51
  def self.try_to_constantize(klass)
52
- klass.is_a?(String) ? klass.constantize : klass
52
+ klass.is_a?(String) ? Object.const_get(klass) : klass
53
53
  rescue NameError
54
54
  klass
55
55
  end
@@ -57,12 +57,14 @@ module SidekiqScheduler
57
57
  # Initializes active_job using the passed parameters.
58
58
  #
59
59
  # @param [Class] klass The class to initialize
60
- # @param [Array/Hash] the parameters passed to the klass initializer
60
+ # @param [Array, Hash] args The parameters passed to the klass initializer
61
61
  #
62
62
  # @return [Object] instance of the class klass
63
- def self.initialize_active_job(klass, args)
63
+ def self.initialize_active_job(klass, args, keyword_argument = false)
64
64
  if args.is_a?(Array)
65
65
  klass.new(*args)
66
+ elsif args.is_a?(Hash) && keyword_argument
67
+ klass.new(**symbolize_keys(args))
66
68
  else
67
69
  klass.new(args)
68
70
  end
@@ -71,7 +73,7 @@ module SidekiqScheduler
71
73
  # Returns true if the enqueuing needs to be done for an ActiveJob
72
74
  # class false otherwise.
73
75
  #
74
- # @param [Class] klass the class to check is decendant from ActiveJob
76
+ # @param [Class] klass the class to check is descendant from ActiveJob
75
77
  #
76
78
  # @return [Boolean]
77
79
  def self.active_job_enqueue?(klass)
@@ -94,7 +96,7 @@ module SidekiqScheduler
94
96
  queue: config['queue']
95
97
  }.keep_if { |_, v| !v.nil? }
96
98
 
97
- initialize_active_job(config['class'], config['args']).enqueue(options)
99
+ initialize_active_job(config['class'], config['args'], config['keyword_argument']).enqueue(options)
98
100
  end
99
101
 
100
102
  # Removes the hash values associated to the rufus metadata keys.
@@ -112,8 +114,10 @@ module SidekiqScheduler
112
114
  def self.new_rufus_scheduler(options = {})
113
115
  Rufus::Scheduler.new(options).tap do |scheduler|
114
116
  scheduler.define_singleton_method(:on_post_trigger) do |job, triggered_time|
115
- SidekiqScheduler::Utils.update_job_last_time(job.tags[0], triggered_time)
116
- SidekiqScheduler::Utils.update_job_next_time(job.tags[0], job.next_time)
117
+ if (job_name = job.tags[0])
118
+ SidekiqScheduler::Utils.update_job_last_time(job_name, triggered_time)
119
+ SidekiqScheduler::Utils.update_job_next_time(job_name, job.next_time)
120
+ end
117
121
  end
118
122
  end
119
123
  end
@@ -137,5 +141,41 @@ module SidekiqScheduler
137
141
  def self.update_job_last_time(name, last_time)
138
142
  SidekiqScheduler::RedisManager.set_job_last_time(name, last_time) if last_time
139
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.floor # remove sub seconds to prevent rounding errors.
159
+ return time if cron.match?(time) # If the time is a perfect match then return it.
160
+
161
+ next_t = cron.next_time(time).to_t
162
+ previous_t = cron.previous_time(time).to_t
163
+ # The `time` var is some point between `previous_t` and `next_t`.
164
+ # Figure out how far off we are from each side in seconds.
165
+ next_diff = next_t - time
166
+ previous_diff = time - previous_t
167
+
168
+ if next_diff == previous_diff
169
+ # In the event `time` is exactly between `previous_t` and `next_t` the diff will not be equal to
170
+ # `cron.rough_frequency`. In that case we round down.
171
+ cron.rough_frequency == next_diff ? time : previous_t
172
+ elsif next_diff > previous_diff
173
+ # We are closer to the previous run time so return that.
174
+ previous_t
175
+ else
176
+ # We are closer to the next run time so return that.
177
+ next_t
178
+ end
179
+ end
140
180
  end
141
181
  end
@@ -1,3 +1,3 @@
1
1
  module SidekiqScheduler
2
- VERSION = "4.0.2"
2
+ VERSION = "5.0.6"
3
3
  end
@@ -3,7 +3,7 @@ require 'sidekiq-scheduler'
3
3
  require_relative 'job_presenter'
4
4
 
5
5
  module SidekiqScheduler
6
- # Hook into *Sidekiq::Web* Sinatra app which adds a new '/recurring-jobs' page
6
+ # Hook into *Sidekiq::Web* app which adds a new '/recurring-jobs' page
7
7
 
8
8
  module Web
9
9
  VIEW_PATH = File.expand_path('../../../web/views', __FILE__)
@@ -27,6 +27,11 @@ module SidekiqScheduler
27
27
  SidekiqScheduler::Scheduler.instance.toggle_job_enabled(params[:name])
28
28
  redirect "#{root_path}recurring-jobs"
29
29
  end
30
+
31
+ app.post '/recurring-jobs/toggle-all' do
32
+ SidekiqScheduler::Scheduler.instance.toggle_all_jobs(params[:action] == 'enable')
33
+ redirect "#{root_path}recurring-jobs"
34
+ end
30
35
  end
31
36
  end
32
37
  end
@@ -5,9 +5,9 @@ require_relative 'sidekiq/scheduler'
5
5
  require_relative 'sidekiq-scheduler/version'
6
6
  require_relative 'sidekiq-scheduler/manager'
7
7
  require_relative 'sidekiq-scheduler/redis_manager'
8
+ require_relative 'sidekiq-scheduler/config'
8
9
  require_relative 'sidekiq-scheduler/extensions/schedule'
9
-
10
- SIDEKIQ_GTE_6_5_0 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('6.5.0')
10
+ require_relative 'sidekiq-scheduler/sidekiq_adapter'
11
11
 
12
12
  Sidekiq.configure_server do |config|
13
13
 
@@ -15,25 +15,14 @@ Sidekiq.configure_server do |config|
15
15
  # schedules_changed's type was changed from SET to ZSET, so we remove old versions at startup
16
16
  SidekiqScheduler::RedisManager.clean_schedules_changed
17
17
 
18
- # Accessing the raw @config hash through .options is deprecated in 6.5 and to be removed in 7.0
19
- config_options = SIDEKIQ_GTE_6_5_0 ? Sidekiq.instance_variable_get(:@config) : config.options
18
+ scheduler_config = SidekiqScheduler::Config.new(sidekiq_config: config)
20
19
 
21
- schedule_manager = SidekiqScheduler::Manager.new(config_options)
22
- if SIDEKIQ_GTE_6_5_0
23
- config[:schedule_manager] = schedule_manager
24
- config[:schedule_manager].start
25
- else
26
- config.options[:schedule_manager] = schedule_manager
27
- config.options[:schedule_manager].start
28
- end
20
+ schedule_manager = SidekiqScheduler::Manager.new(scheduler_config)
21
+ SidekiqScheduler::SidekiqAdapter.start_schedule_manager(sidekiq_config: config, schedule_manager: schedule_manager)
29
22
  end
30
23
 
31
24
  config.on(:quiet) do
32
- if SIDEKIQ_GTE_6_5_0
33
- config[:schedule_manager].stop
34
- else
35
- config.options[:schedule_manager].stop
36
- end
25
+ SidekiqScheduler::SidekiqAdapter.stop_schedule_manager(sidekiq_config: config)
37
26
  end
38
27
 
39
28
  end
@@ -25,3 +25,18 @@
25
25
  border: 1px solid #555;
26
26
  }
27
27
  }
28
+
29
+ .toggle-all-buttons {
30
+ margin-top: 20px;
31
+ margin-bottom: 10px;
32
+ line-height: 45px;
33
+ text-align: right;
34
+ }
35
+
36
+ @media (max-width: 768px) {
37
+ .toggle-all-buttons {
38
+ margin-top: 0;
39
+ text-align: left;
40
+ line-height: inherit;
41
+ }
42
+ }
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
@@ -12,3 +13,5 @@ de:
12
13
  no_next_time: Keine zukünftige Ausführung für diesen Job
13
14
  disable: Deaktivieren
14
15
  enable: Aktivieren
16
+ disable_all: Alle deaktivieren
17
+ enable_all: Alle aktivieren
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
@@ -12,3 +13,5 @@ en:
12
13
  no_next_time: no next execution for this job
13
14
  disable: Disable
14
15
  enable: Enable
16
+ disable_all: Disable all
17
+ enable_all: Enable all
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