sidekiq-cron 1.2.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Changes.md +111 -82
- data/Gemfile +1 -30
- data/README.md +154 -106
- data/Rakefile +3 -42
- data/lib/sidekiq/cron/job.rb +38 -17
- data/lib/sidekiq/cron/locales/en.yml +2 -0
- data/lib/sidekiq/cron/locales/pt.yml +22 -0
- data/lib/sidekiq/cron/poller.rb +17 -5
- data/lib/sidekiq/cron/version.rb +7 -0
- data/lib/sidekiq/cron/views/cron.erb +19 -13
- data/lib/sidekiq/cron/views/cron_show.erb +8 -8
- data/lib/sidekiq/cron/web.rb +1 -7
- data/lib/sidekiq/cron/web_extension.rb +2 -12
- data/sidekiq-cron.gemspec +25 -113
- data/test/integration/performance_test.rb +3 -4
- data/test/test_helper.rb +10 -23
- data/test/unit/job_test.rb +104 -4
- data/test/unit/poller_test.rb +1 -3
- data/test/unit/web_extension_test.rb +38 -38
- metadata +47 -195
- data/.document +0 -5
- data/.travis.yml +0 -18
- data/Dockerfile +0 -32
- data/VERSION +0 -1
- data/config.ru +0 -14
- data/docker-compose.yml +0 -23
- data/examples/web-cron-ui.png +0 -0
- data/lib/sidekiq/cron/views/cron.slim +0 -71
- data/lib/sidekiq/cron/views/cron_show.slim +0 -61
data/README.md
CHANGED
@@ -1,92 +1,114 @@
|
|
1
|
-
Sidekiq-Cron
|
2
|
-
================================================================================================================================================================================================================================================================================================================================================================================================================================================
|
1
|
+
# Sidekiq-Cron
|
3
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/sidekiq-cron.svg)](https://badge.fury.io/rb/sidekiq-cron)
|
4
|
+
[![Build Status](https://github.com/ondrejbartas/sidekiq-cron/workflows/CI/badge.svg?branch=master)](https://github.com/ondrejbartas/sidekiq-cron/actions)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/github/ondrejbartas/sidekiq-cron/badge.svg?branch=master)](https://coveralls.io/github/ondrejbartas/sidekiq-cron?branch=master)
|
4
6
|
[![Join the chat at https://gitter.im/ondrejbartas/sidekiq-cron](https://badges.gitter.im/ondrejbartas/sidekiq-cron.svg)](https://gitter.im/ondrejbartas/sidekiq-cron?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
7
|
|
6
|
-
|
8
|
+
> A scheduling add-on for [Sidekiq](https://sidekiq.org/)
|
7
9
|
|
8
|
-
|
10
|
+
🎬 [Introduction video about Sidekiq-Cron by Drifting Ruby](https://www.driftingruby.com/episodes/periodic-tasks-with-sidekiq-cron)
|
9
11
|
|
10
|
-
|
12
|
+
Sidekiq-Cron runs a thread alongside Sidekiq workers to schedule jobs at specified times (using cron notation `* * * * *` parsed by [Fugit](https://github.com/floraison/fugit)).
|
11
13
|
|
12
14
|
Checks for new jobs to schedule every 30 seconds and doesn't schedule the same job multiple times when more than one Sidekiq worker is running.
|
13
15
|
|
14
16
|
Scheduling jobs are added only when at least one Sidekiq process is running, but it is safe to use Sidekiq-Cron in environments where multiple Sidekiq processes or nodes are running.
|
15
17
|
|
16
|
-
If you want to know how scheduling work, check out [under the hood](#under-the-hood)
|
18
|
+
If you want to know how scheduling work, check out [under the hood](#under-the-hood).
|
17
19
|
|
18
|
-
Works with ActiveJob (Rails 4.2+)
|
20
|
+
Works with ActiveJob (Rails 4.2+).
|
19
21
|
|
20
|
-
You don't need Sidekiq PRO, you can use this gem with plain
|
22
|
+
You don't need Sidekiq PRO, you can use this gem with plain Sidekiq.
|
21
23
|
|
22
|
-
Upgrade from <0.
|
23
|
-
---------------------------
|
24
|
+
## Upgrade from < 0.6 to 1.0
|
24
25
|
|
25
|
-
Please be aware that
|
26
|
+
Please be aware that Sidekiq-Cron < 1.0 was relying on rufus-scheduler < 3.5. Using those older versions 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
27
|
|
27
|
-
|
28
|
-
-----------------
|
28
|
+
## Changelog
|
29
29
|
|
30
|
-
|
31
|
-
- Sidekiq 5, or 4, or 3 and greater is required (for Sidekiq < 4 use version sidekiq-cron 0.3.1)
|
30
|
+
Before upgrading to a new version, please read our [Changelog](Changes.md).
|
32
31
|
|
33
|
-
|
34
|
-
----------
|
35
|
-
before upgrading to new version, please read:
|
36
|
-
[Change Log](https://github.com/ondrejbartas/sidekiq-cron/blob/master/Changes.md)
|
32
|
+
## Installation
|
37
33
|
|
38
|
-
|
39
|
-
------------
|
34
|
+
### Requirements
|
40
35
|
|
41
|
-
|
36
|
+
- Redis 2.8 or greater is required (Redis 3.0.3 or greater is recommended for large scale use)
|
37
|
+
- Sidekiq 4.2 or greater is required (for Sidekiq < 4 use version sidekiq-cron 0.3.1)
|
38
|
+
- Sidekiq 6.5 requires Sidekiq-Cron 1.5+
|
42
39
|
|
43
|
-
|
40
|
+
Install the gem:
|
44
41
|
|
45
|
-
|
42
|
+
```
|
43
|
+
$ gem install sidekiq-cron
|
44
|
+
```
|
46
45
|
|
46
|
+
Or add to your `Gemfile` and run `bundle install`:
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
```ruby
|
49
|
+
gem "sidekiq-cron"
|
50
|
+
```
|
50
51
|
|
52
|
+
**NOTE** If you are not using Rails, you need to add `require 'sidekiq-cron'` somewhere after `require 'sidekiq'`.
|
51
53
|
|
52
|
-
|
54
|
+
## Getting Started
|
53
55
|
|
54
|
-
|
56
|
+
**Job properties:**
|
55
57
|
|
56
58
|
```ruby
|
57
59
|
{
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
60
|
+
'name' => 'name_of_job', # must be uniq!
|
61
|
+
'cron' => '1 * * * *', # execute at 1 minute of every hour, ex: 12:01, 13:01, 14:01, 15:01, ... (HH:MM)
|
62
|
+
'class' => 'MyClass',
|
63
|
+
# OPTIONAL
|
64
|
+
'queue' => 'name of queue',
|
65
|
+
'args' => '[Array or Hash] of arguments which will be passed to perform method',
|
66
|
+
'date_as_argument' => true, # add the time of execution as last argument of the perform method
|
67
|
+
'active_job' => true, # enqueue job through rails 4.2+ active job interface
|
68
|
+
'queue_name_prefix' => 'prefix', # rails 4.2+ active job queue with prefix
|
69
|
+
'queue_name_delimiter' => '.', # rails 4.2+ active job queue with custom delimiter
|
70
|
+
'description' => 'A sentence describing what work this job performs.'
|
71
|
+
'status' => 'disabled' # default: enabled
|
69
72
|
}
|
70
73
|
```
|
71
74
|
|
72
|
-
### Time, cron and
|
75
|
+
### Time, cron and Sidekiq-Cron
|
73
76
|
|
74
77
|
For testing your cron notation you can use [crontab.guru](https://crontab.guru).
|
75
78
|
|
76
|
-
|
79
|
+
Sidekiq-Cron uses [Fugit](https://github.com/floraison/fugit) to parse the cronline. So please, check Fugit documentation for further information about allowed formats.
|
80
|
+
|
77
81
|
If using Rails, this is evaluated against the timezone configured in Rails, otherwise the default is UTC.
|
78
82
|
|
79
83
|
If you want to have your jobs enqueued based on a different time zone you can specify a timezone in the cronline,
|
80
84
|
like this `'0 22 * * 1-5 America/Chicago'`.
|
81
85
|
|
82
|
-
|
86
|
+
#### Second-precision (sub-minute) cronlines
|
87
|
+
|
88
|
+
In addition to the standard 5-parameter cronline format, sidekiq-cron supports scheduling jobs with second-precision using a modified 6-parameter cronline format:
|
89
|
+
|
90
|
+
`Seconds Minutes Hours Days Months DayOfWeek`
|
91
|
+
|
92
|
+
For example: `"*/30 * * * * *"` would schedule a job to run every 30 seconds.
|
93
|
+
|
94
|
+
Note that if you plan to schedule jobs with second precision you may need to override the default schedule poll interval so it is lower than the interval of your jobs:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Sidekiq.options[:average_scheduled_poll_interval] = 10
|
98
|
+
```
|
99
|
+
|
100
|
+
The default value at time of writing is 30 seconds. See [under the hood](#under-the-hood) for more details.
|
83
101
|
|
84
102
|
### What objects/classes can be scheduled
|
103
|
+
|
85
104
|
#### Sidekiq Worker
|
105
|
+
|
86
106
|
In this example, we are using `HardWorker` which looks like:
|
107
|
+
|
87
108
|
```ruby
|
88
109
|
class HardWorker
|
89
110
|
include Sidekiq::Worker
|
111
|
+
|
90
112
|
def perform(*args)
|
91
113
|
# do something
|
92
114
|
end
|
@@ -94,7 +116,9 @@ end
|
|
94
116
|
```
|
95
117
|
|
96
118
|
#### Active Job Worker
|
97
|
-
|
119
|
+
|
120
|
+
You can schedule `ExampleJob` which looks like:
|
121
|
+
|
98
122
|
```ruby
|
99
123
|
class ExampleJob < ActiveJob::Base
|
100
124
|
queue_as :default
|
@@ -105,11 +129,15 @@ class ExampleJob < ActiveJob::Base
|
|
105
129
|
end
|
106
130
|
```
|
107
131
|
|
108
|
-
|
109
|
-
|
132
|
+
For Active jobs you can use `symbolize_args: true` in `Sidekiq::Cron::Job.create` or in Hash configuration,
|
133
|
+
which will ensure that arguments you are passing to it will be symbolized when passed back to `perform` method in worker.
|
134
|
+
|
135
|
+
#### Adding Cron job
|
110
136
|
|
137
|
+
```ruby
|
111
138
|
class HardWorker
|
112
139
|
include Sidekiq::Worker
|
140
|
+
|
113
141
|
def perform(name, count)
|
114
142
|
# do something
|
115
143
|
end
|
@@ -130,16 +158,15 @@ else
|
|
130
158
|
puts job.errors
|
131
159
|
end
|
132
160
|
|
133
|
-
#or simple
|
134
|
-
|
161
|
+
# or simple
|
135
162
|
unless job.save
|
136
|
-
puts job.errors #will return array of errors
|
163
|
+
puts job.errors # will return array of errors
|
137
164
|
end
|
138
165
|
```
|
139
166
|
|
140
167
|
Load more jobs from hash:
|
141
|
-
```ruby
|
142
168
|
|
169
|
+
```ruby
|
143
170
|
hash = {
|
144
171
|
'name_of_job' => {
|
145
172
|
'class' => 'MyClass',
|
@@ -156,6 +183,7 @@ Sidekiq::Cron::Job.load_from_hash hash
|
|
156
183
|
```
|
157
184
|
|
158
185
|
Load more jobs from array:
|
186
|
+
|
159
187
|
```ruby
|
160
188
|
array = [
|
161
189
|
{
|
@@ -174,17 +202,17 @@ array = [
|
|
174
202
|
Sidekiq::Cron::Job.load_from_array array
|
175
203
|
```
|
176
204
|
|
177
|
-
Bang-suffixed methods will remove jobs that are not present in the given hash/array,
|
178
|
-
update jobs that have the same names, and create new ones when the names are previously unknown.
|
205
|
+
Bang-suffixed methods will remove jobs that are not present in the given hash/array, update jobs that have the same names, and create new ones when the names are previously unknown.
|
179
206
|
|
180
207
|
```ruby
|
181
|
-
Sidekiq::Cron::Job
|
182
|
-
Sidekiq::Cron::Job
|
208
|
+
Sidekiq::Cron::Job.load_from_hash! hash
|
209
|
+
Sidekiq::Cron::Job.load_from_array! array
|
183
210
|
```
|
184
211
|
|
185
|
-
|
212
|
+
Or from YAML (same notation as Resque-scheduler):
|
213
|
+
|
186
214
|
```yaml
|
187
|
-
#config/schedule.yml
|
215
|
+
# config/schedule.yml
|
188
216
|
|
189
217
|
my_first_job:
|
190
218
|
cron: "*/5 * * * *"
|
@@ -200,7 +228,7 @@ second_job:
|
|
200
228
|
```
|
201
229
|
|
202
230
|
```ruby
|
203
|
-
#initializers/sidekiq.rb
|
231
|
+
# config/initializers/sidekiq.rb
|
204
232
|
schedule_file = "config/schedule.yml"
|
205
233
|
|
206
234
|
if File.exist?(schedule_file) && Sidekiq.server?
|
@@ -208,56 +236,76 @@ if File.exist?(schedule_file) && Sidekiq.server?
|
|
208
236
|
end
|
209
237
|
```
|
210
238
|
|
211
|
-
|
239
|
+
From version 3.x it is better not to use separate initializer of schedule instead add `config.on(:startup)` to your Sidekiq configuration:
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
Sidekiq.configure_server do |config|
|
243
|
+
config.on(:startup) do
|
244
|
+
schedule_file = "config/schedule.yml"
|
245
|
+
|
246
|
+
if File.exist?(schedule_file)
|
247
|
+
Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
```
|
252
|
+
|
253
|
+
Or you can use for loading jobs from yml file [sidekiq-cron-tasks](https://github.com/coverhound/sidekiq-cron-tasks) which will add rake task `bundle exec rake sidekiq_cron:load` to your rails application.
|
254
|
+
|
255
|
+
### Finding jobs
|
212
256
|
|
213
|
-
#### Finding jobs
|
214
257
|
```ruby
|
215
|
-
#return array of all jobs
|
258
|
+
# return array of all jobs
|
216
259
|
Sidekiq::Cron::Job.all
|
217
260
|
|
218
|
-
#return one job by its unique name - case sensitive
|
261
|
+
# return one job by its unique name - case sensitive
|
219
262
|
Sidekiq::Cron::Job.find "Job Name"
|
220
263
|
|
221
|
-
#return one job by its unique name - you can use hash with 'name' key
|
264
|
+
# return one job by its unique name - you can use hash with 'name' key
|
222
265
|
Sidekiq::Cron::Job.find name: "Job Name"
|
223
266
|
|
224
|
-
#if job can't be found nil is returned
|
267
|
+
# if job can't be found nil is returned
|
225
268
|
```
|
226
269
|
|
227
|
-
|
270
|
+
### Destroy jobs
|
271
|
+
|
228
272
|
```ruby
|
229
|
-
#
|
273
|
+
# destroy all jobs
|
230
274
|
Sidekiq::Cron::Job.destroy_all!
|
231
275
|
|
232
|
-
#destroy job by its name
|
276
|
+
# destroy job by its name
|
233
277
|
Sidekiq::Cron::Job.destroy "Job Name"
|
234
278
|
|
235
|
-
#destroy found job
|
279
|
+
# destroy found job
|
236
280
|
Sidekiq::Cron::Job.find('Job name').destroy
|
237
281
|
```
|
238
282
|
|
239
|
-
|
283
|
+
### Work with job
|
284
|
+
|
240
285
|
```ruby
|
241
286
|
job = Sidekiq::Cron::Job.find('Job name')
|
242
287
|
|
243
|
-
#disable cron scheduling
|
288
|
+
# disable cron scheduling
|
244
289
|
job.disable!
|
245
290
|
|
246
|
-
#enable cron scheduling
|
291
|
+
# enable cron scheduling
|
247
292
|
job.enable!
|
248
293
|
|
249
|
-
#get status of job:
|
294
|
+
# get status of job:
|
250
295
|
job.status
|
251
296
|
# => enabled/disabled
|
252
297
|
|
253
|
-
#enqueue job right now!
|
298
|
+
# enqueue job right now!
|
254
299
|
job.enque!
|
255
300
|
```
|
256
301
|
|
257
|
-
How to start scheduling?
|
302
|
+
### How to start scheduling?
|
303
|
+
|
258
304
|
Just start Sidekiq workers by running:
|
259
305
|
|
260
|
-
|
306
|
+
```
|
307
|
+
$ sidekiq
|
308
|
+
```
|
261
309
|
|
262
310
|
### Web UI for Cron Jobs
|
263
311
|
|
@@ -265,68 +313,68 @@ If you are using Sidekiq's web UI and you would like to add cron jobs too to thi
|
|
265
313
|
add `require 'sidekiq/cron/web'` after `require 'sidekiq/web'`.
|
266
314
|
|
267
315
|
With this, you will get:
|
268
|
-
![Web UI](https://github.com/ondrejbartas/sidekiq-cron/raw/master/examples/web-cron-ui.png)
|
269
316
|
|
270
|
-
|
317
|
+
![Web UI](examples/web-cron-ui.png)
|
318
|
+
|
319
|
+
### Forking Processes or problem with `NotImplementedError`
|
271
320
|
|
272
321
|
If you're using a forking web server like Unicorn you may run into an issue where the Redis connection is used
|
273
|
-
before the process forks, causing the following exception
|
322
|
+
before the process forks, causing the following exception to occur:
|
274
323
|
|
275
|
-
|
324
|
+
```
|
325
|
+
Redis::InheritedError: Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.
|
326
|
+
```
|
276
327
|
|
277
|
-
|
328
|
+
To avoid this, wrap your job creation in the call to `Sidekiq.configure_server`:
|
278
329
|
|
279
330
|
```ruby
|
280
331
|
Sidekiq.configure_server do |config|
|
281
|
-
|
332
|
+
config.on(:startup) do
|
333
|
+
schedule_file = "config/schedule.yml"
|
282
334
|
|
283
|
-
|
284
|
-
|
335
|
+
if File.exist?(schedule_file)
|
336
|
+
Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
|
337
|
+
end
|
285
338
|
end
|
286
339
|
end
|
287
340
|
```
|
288
341
|
|
289
|
-
|
342
|
+
**NOTE** This API is only available in Sidekiq 3.x.
|
290
343
|
|
291
344
|
## Under the hood
|
292
345
|
|
293
346
|
When you start the Sidekiq process, it starts one thread with `Sidekiq::Poller` instance, which perform the adding of scheduled jobs to queues, retries etc.
|
294
347
|
|
295
|
-
Sidekiq-Cron adds itself into this start procedure and starts another thread with `Sidekiq::Cron::Poller` which checks all enabled Sidekiq cron jobs every
|
348
|
+
Sidekiq-Cron adds itself into this start procedure and starts another thread with `Sidekiq::Cron::Poller` which checks all enabled Sidekiq cron jobs every 30 seconds, if they should be added to queue (their cronline matches time of check).
|
296
349
|
|
297
350
|
Sidekiq-Cron is checking jobs to be enqueued every 30s by default, you can change it by setting:
|
298
|
-
```
|
299
|
-
Sidekiq.options[:poll_interval] = 10
|
300
|
-
```
|
301
351
|
|
302
|
-
|
352
|
+
```ruby
|
353
|
+
Sidekiq.options[:average_scheduled_poll_interval] = 10
|
354
|
+
```
|
303
355
|
|
304
|
-
|
305
|
-
* [@7korobi](https://github.com/7korobi)
|
306
|
-
* [@antulik](https://github.com/antulik)
|
307
|
-
* [@felixbuenemann](https://github.com/felixbuenemann)
|
308
|
-
* [@gstark](https://github.com/gstark)
|
309
|
-
* [@RajRoR](https://github.com/RajRoR)
|
310
|
-
* [@romeuhcf](https://github.com/romeuhcf)
|
311
|
-
* [@siruguri](https://github.com/siruguri)
|
312
|
-
* [@Soliah](https://github.com/Soliah)
|
313
|
-
* [@stephankaag](https://github.com/stephankaag)
|
314
|
-
* [@sue445](https://github.com/sue445)
|
315
|
-
* [@sylg](https://github.com/sylg)
|
316
|
-
* [@tmeinlschmidt](https://github.com/tmeinlschmidt)
|
317
|
-
* [@zerobearing2](https://github.com/zerobearing2)
|
356
|
+
Sidekiq-Cron is safe to use with multiple Sidekiq processes or nodes. It uses a Redis sorted set to determine that only the first process who asks can enqueue scheduled jobs into the queue.
|
318
357
|
|
358
|
+
## Contributing
|
319
359
|
|
320
|
-
|
360
|
+
**Thanks to all [contributors](https://github.com/ondrejbartas/sidekiq-cron/graphs/contributors), you’re awesome and this wouldn’t be possible without you!**
|
321
361
|
|
322
362
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
323
363
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
324
364
|
* Fork the project.
|
325
365
|
* Start a feature/bugfix branch.
|
326
366
|
* Commit and push until you are happy with your contribution.
|
327
|
-
* Make sure to add tests for it. This is important so
|
328
|
-
*
|
367
|
+
* Make sure to add tests for it. This is important so we don't break it in a future version unintentionally.
|
368
|
+
* Open a pull request!
|
369
|
+
|
370
|
+
### Testing
|
371
|
+
|
372
|
+
You can execute the test suite by running:
|
373
|
+
|
374
|
+
```
|
375
|
+
$ bundle exec rake test
|
376
|
+
```
|
329
377
|
|
330
|
-
##
|
378
|
+
## License
|
331
379
|
|
332
|
-
Copyright (c) 2013 Ondrej Bartas. See LICENSE.txt for further details.
|
380
|
+
Copyright (c) 2013 Ondrej Bartas. See [LICENSE](LICENSE.txt) for further details.
|
data/Rakefile
CHANGED
@@ -1,43 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'bundler/setup'
|
5
|
-
require 'bundler'
|
6
|
-
|
7
|
-
begin
|
8
|
-
Bundler.setup(:default, :development)
|
9
|
-
rescue Bundler::BundlerError => e
|
10
|
-
$stderr.puts e.message
|
11
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
12
|
-
exit e.status_code
|
13
|
-
end
|
14
|
-
require 'rake'
|
15
|
-
|
16
|
-
require 'jeweler'
|
17
|
-
Jeweler::Tasks.new do |gem|
|
18
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
19
|
-
gem.name = "sidekiq-cron"
|
20
|
-
gem.homepage = "http://github.com/ondrejbartas/sidekiq-cron"
|
21
|
-
gem.license = "MIT"
|
22
|
-
gem.summary = %Q{Sidekiq Cron helps to add repeated scheduled jobs}
|
23
|
-
gem.description = %Q{Enables to set jobs to be run in specified time (using CRON notation)}
|
24
|
-
gem.email = "ondrej@bartas.cz"
|
25
|
-
gem.authors = ["Ondrej Bartas"]
|
26
|
-
# dependencies defined in Gemfile
|
27
|
-
end
|
28
|
-
Jeweler::RubygemsDotOrgTasks.new
|
29
|
-
|
30
|
-
#TESTING
|
31
|
-
|
32
|
-
task :doc do
|
33
|
-
system 'sdoc -N .'
|
34
|
-
end
|
35
|
-
|
1
|
+
require 'bundler/gem_tasks'
|
36
2
|
require 'rake/testtask'
|
3
|
+
|
37
4
|
task :default => :test
|
38
5
|
|
39
6
|
Rake::TestTask.new(:test) do |t|
|
40
|
-
t.test_files = FileList['test/
|
7
|
+
t.test_files = FileList['test/unit/**/*_test.rb', 'test/integration/**/*_test.rb']
|
41
8
|
t.warning = false
|
42
9
|
t.verbose = false
|
43
10
|
end
|
@@ -49,12 +16,6 @@ namespace :test do
|
|
49
16
|
t.verbose = false
|
50
17
|
end
|
51
18
|
|
52
|
-
Rake::TestTask.new(:functional) do |t|
|
53
|
-
t.test_files = FileList['test/functional/**/*_test.rb']
|
54
|
-
t.warning = false
|
55
|
-
t.verbose = false
|
56
|
-
end
|
57
|
-
|
58
19
|
Rake::TestTask.new(:integration) do |t|
|
59
20
|
t.test_files = FileList['test/integration/**/*_test.rb']
|
60
21
|
t.warning = false
|
data/lib/sidekiq/cron/job.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
require 'fugit'
|
2
2
|
require 'sidekiq'
|
3
|
-
require 'sidekiq/util'
|
4
3
|
require 'sidekiq/cron/support'
|
5
4
|
|
6
5
|
module Sidekiq
|
7
6
|
module Cron
|
8
|
-
|
9
7
|
class Job
|
10
|
-
include Util
|
11
|
-
extend Util
|
12
|
-
|
13
8
|
#how long we would like to store informations about previous enqueues
|
14
9
|
REMEMBER_THRESHOLD = 24 * 60 * 60
|
15
10
|
LAST_ENQUEUE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S %z'
|
16
11
|
|
12
|
+
# Use the exists? method if we're on a newer version of redis.
|
13
|
+
REDIS_EXISTS_METHOD = Gem.loaded_specs['redis'].version < Gem::Version.new('4.2') ? :exists : :exists?
|
14
|
+
|
17
15
|
#crucial part of whole enquing job
|
18
16
|
def should_enque? time
|
19
17
|
enqueue = false
|
@@ -73,7 +71,7 @@ module Sidekiq
|
|
73
71
|
|
74
72
|
save_last_enqueue_time
|
75
73
|
add_jid_history jid
|
76
|
-
logger.debug { "enqueued #{@name}: #{@message}" }
|
74
|
+
Sidekiq.logger.debug { "enqueued #{@name}: #{@message}" }
|
77
75
|
end
|
78
76
|
|
79
77
|
def is_active_job?
|
@@ -203,9 +201,9 @@ module Sidekiq
|
|
203
201
|
job_hashes = nil
|
204
202
|
Sidekiq.redis do |conn|
|
205
203
|
set_members = conn.smembers(jobs_key)
|
206
|
-
job_hashes = conn.pipelined do
|
204
|
+
job_hashes = conn.pipelined do |pipeline|
|
207
205
|
set_members.each do |key|
|
208
|
-
|
206
|
+
pipeline.hgetall(key)
|
209
207
|
end
|
210
208
|
end
|
211
209
|
end
|
@@ -233,7 +231,7 @@ module Sidekiq
|
|
233
231
|
output = Job.new conn.hgetall( redis_key(name) )
|
234
232
|
end
|
235
233
|
end
|
236
|
-
output
|
234
|
+
output if output && output.valid?
|
237
235
|
end
|
238
236
|
|
239
237
|
# create new instance of cron job
|
@@ -279,6 +277,7 @@ module Sidekiq
|
|
279
277
|
end
|
280
278
|
|
281
279
|
#get right arguments for job
|
280
|
+
@symbolize_args = args["symbolize_args"] == true || ("#{args["symbolize_args"]}" =~ (/^(true|t|yes|y|1)$/i)) == 0 || false
|
282
281
|
@args = args["args"].nil? ? [] : parse_args( args["args"] )
|
283
282
|
@args += [Time.now.to_f] if args["date_as_argument"]
|
284
283
|
|
@@ -401,6 +400,7 @@ module Sidekiq
|
|
401
400
|
queue_name_prefix: @active_job_queue_name_prefix,
|
402
401
|
queue_name_delimiter: @active_job_queue_name_delimiter,
|
403
402
|
last_enqueue_time: @last_enqueue_time,
|
403
|
+
symbolize_args: @symbolize_args,
|
404
404
|
}
|
405
405
|
end
|
406
406
|
|
@@ -461,9 +461,9 @@ module Sidekiq
|
|
461
461
|
|
462
462
|
#add information about last time! - don't enque right after scheduler poller starts!
|
463
463
|
time = Time.now.utc
|
464
|
-
conn.zadd(job_enqueued_key, time.to_f.to_s, formated_last_time(time).to_s) unless conn.
|
464
|
+
conn.zadd(job_enqueued_key, time.to_f.to_s, formated_last_time(time).to_s) unless conn.public_send(REDIS_EXISTS_METHOD, job_enqueued_key)
|
465
465
|
end
|
466
|
-
logger.info { "Cron Jobs -
|
466
|
+
Sidekiq.logger.info { "Cron Jobs - added job with name: #{@name}" }
|
467
467
|
end
|
468
468
|
|
469
469
|
def save_last_enqueue_time
|
@@ -504,7 +504,7 @@ module Sidekiq
|
|
504
504
|
#delete main job
|
505
505
|
conn.del redis_key
|
506
506
|
end
|
507
|
-
logger.info { "Cron Jobs - deleted job with name: #{@name}" }
|
507
|
+
Sidekiq.logger.info { "Cron Jobs - deleted job with name: #{@name}" }
|
508
508
|
end
|
509
509
|
|
510
510
|
# remove all job from cron
|
@@ -512,7 +512,7 @@ module Sidekiq
|
|
512
512
|
all.each do |job|
|
513
513
|
job.destroy
|
514
514
|
end
|
515
|
-
logger.info { "Cron Jobs - deleted all jobs" }
|
515
|
+
Sidekiq.logger.info { "Cron Jobs - deleted all jobs" }
|
516
516
|
end
|
517
517
|
|
518
518
|
# remove "removed jobs" between current jobs and new jobs
|
@@ -540,7 +540,7 @@ module Sidekiq
|
|
540
540
|
def self.exists? name
|
541
541
|
out = false
|
542
542
|
Sidekiq.redis do |conn|
|
543
|
-
out = conn.
|
543
|
+
out = conn.public_send(REDIS_EXISTS_METHOD, redis_key(name))
|
544
544
|
end
|
545
545
|
out
|
546
546
|
end
|
@@ -571,19 +571,40 @@ module Sidekiq
|
|
571
571
|
case args
|
572
572
|
when String
|
573
573
|
begin
|
574
|
-
Sidekiq.load_json(args)
|
574
|
+
parsed_args = Sidekiq.load_json(args)
|
575
|
+
symbolize_args? ? symbolize_args(parsed_args) : parsed_args
|
575
576
|
rescue JSON::ParserError
|
576
577
|
[*args] # cast to string array
|
577
578
|
end
|
578
579
|
when Hash
|
579
|
-
[args]
|
580
|
+
symbolize_args? ? [symbolize_args(args)] : [args]
|
580
581
|
when Array
|
581
|
-
|
582
|
+
symbolize_args? ? symbolize_args(args) : args
|
582
583
|
else
|
583
584
|
[*args] # cast to string array
|
584
585
|
end
|
585
586
|
end
|
586
587
|
|
588
|
+
def symbolize_args?
|
589
|
+
@symbolize_args
|
590
|
+
end
|
591
|
+
|
592
|
+
def symbolize_args(input)
|
593
|
+
if input.is_a?(Array)
|
594
|
+
input.map do |arg|
|
595
|
+
if arg.respond_to?(:symbolize_keys)
|
596
|
+
arg.symbolize_keys
|
597
|
+
else
|
598
|
+
arg
|
599
|
+
end
|
600
|
+
end
|
601
|
+
elsif input.is_a?(Hash) && input.respond_to?(:symbolize_keys)
|
602
|
+
input.symbolize_keys
|
603
|
+
else
|
604
|
+
input
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
587
608
|
def parse_enqueue_time(timestamp)
|
588
609
|
DateTime.strptime(timestamp, LAST_ENQUEUE_TIME_FORMAT).to_time.utc
|
589
610
|
rescue ArgumentError
|
@@ -8,6 +8,8 @@ en:
|
|
8
8
|
EnqueueAll: Enqueue All
|
9
9
|
DeleteAll: Delete All
|
10
10
|
'Cron string': Cron
|
11
|
+
AreYouSureEnqueueCronJobs: Are you sure you want to enqueue ALL cron jobs?
|
12
|
+
AreYouSureEnqueueCronJob: Are you sure you want to enqueue the %{job} cron job?
|
11
13
|
AreYouSureDeleteCronJobs: Are you sure you want to delete ALL cron jobs?
|
12
14
|
AreYouSureDeleteCronJob: Are you sure you want to delete the %{job} cron job?
|
13
15
|
NoCronJobsWereFound: No cron jobs were found
|