delayed_job 3.0.4 → 3.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,153 @@
1
+ 3.0.5 - 2013-01-28
2
+ ==================
3
+ * Better job timeout error logging
4
+ * psych support for delayed_job_data_mapper deserialization
5
+ * User can configure the worker to raise a SignalException on TERM and/or INT
6
+ * Add the ability to run all available jobs and exit when complete
7
+
8
+ 3.0.4 - 2012-11-09
9
+ ==================
10
+ * Allow the app to specify a default queue name
11
+ * Capistrano script now allows user to specify the DJ command, allowing the user to add "bundle exec" if necessary
12
+ * Persisted record check is now more general
13
+
14
+ 3.0.3 - 2012-05-25
15
+ ==================
16
+ * Fix a bug where the worker would not respect the exit condition
17
+ * Properly handle sleep delay command line argument
18
+
19
+ 3.0.2 - 2012-04-02
20
+ ==================
21
+ * Fix deprecation warnings
22
+ * Raise ArgumentError if attempting to enqueue a performable method on an object that hasn't been persisted yet
23
+ * Allow the number of jobs read at a time to be configured from the command line using --read-ahead
24
+ * Allow custom logger to be configured through Delayed::Worker.logger
25
+ * Various documentation improvements
26
+
27
+ 3.0.1 - 2012-01-24
28
+ ==================
29
+ * Added RecordNotFound message to deserialization error
30
+ * Direct JRuby's yecht parser to syck extensions
31
+ * Updated psych extensions for better compatibility with ruby 1.9.2
32
+ * Updated syck extension for increased compatibility with class methods
33
+ * Test grooming
34
+
35
+ 3.0.0 - 2011-12-30
36
+ ==================
37
+ * New: Named queues
38
+ * New: Job/Worker lifecycle callbacks
39
+ * Change: daemons is no longer a runtime dependency
40
+ * Change: Active Record backend support is provided by a separate gem
41
+ * Change: Enqueue hook is called before jobs are saved so that they may be modified
42
+ * Fix problem deserializing models that use a custom primary key column
43
+ * Fix deserializing AR models when the object isn't in the default scope
44
+ * Fix hooks not getting called when delay_jobs is false
45
+
46
+ 2.1.4 - 2011-02-11
47
+ ==================
48
+ * Working around issues when psych is loaded, fixes issues with bundler 1.0.10 and Rails 3.0.4
49
+ * Added -p/--prefix option to help differentiate multiple delayed job workers on the same host.
50
+
51
+ 2.1.3 - 2011-01-20
52
+ ==================
53
+ * Revert worker contention fix due to regressions
54
+ * Added Delayed::Worker.delay_jobs flag to support running jobs immediately
55
+
56
+ 2.1.2 - 2010-12-01
57
+ ==================
58
+ * Remove contention between multiple workers by performing an update to lock a job before fetching it
59
+ * Job payloads may implement #max_attempts to control how many times it should be retried
60
+ * Fix for loading ActionMailer extension
61
+ * Added 'delayed_job_server_role' Capistrano variable to allow delayed_job to run on its own worker server
62
+ set :delayed_job_server_role, :worker
63
+ * Fix `rake jobs:work` so it outputs to the console
64
+
65
+ 2.1.1 - 2010-11-14
66
+ ==================
67
+ * Fix issue with worker name not getting properly set when locking a job
68
+ * Fixes for YAML serialization
69
+
70
+ 2.1.0 - 2010-11-14
71
+ ==================
72
+ * Added enqueue, before, after, success, error, and failure. See the README
73
+ * Remove Merb support
74
+ * Remove all non Active Record backends into separate gems. See https://github.com/collectiveidea/delayed_job/wiki/Backends
75
+ * remove rails 2 support. delayed_job 2.1 will only support Rails 3
76
+ * New pure-YAML serialization
77
+ * Added Rails 3 railtie and generator
78
+ * Changed @@sleep_delay to self.class.sleep_delay to be consistent with other class variable usage
79
+ * Added --sleep-delay command line option
80
+
81
+ 2.0.8 - Unreleased
82
+ ==================
83
+ * Backport fix for deserialization errors that bring down the daemon
84
+
85
+ 2.0.7 - 2011-02-10
86
+ ==================
87
+ * Fixed missing generators and recipes for Rails 2.x
88
+
89
+ 2.0.6 - 2011-01-20
90
+ ==================
91
+ * Revert worker contention fix due to regressions
92
+
93
+ 2.0.5 - 2010-12-01
94
+ ==================
95
+ * Added #reschedule_at hook on payload to determine when the job should be rescheduled [backported from 2.1]
96
+ * Added --sleep-delay command line option [backported from 2.1]
97
+ * Added 'delayed_job_server_role' Capistrano variable to allow delayed_job to run on its own worker server
98
+ set :delayed_job_server_role, :worker
99
+ * Changed AR backend to reserve jobs using an UPDATE query to reduce worker contention [backported from 2.1]
100
+
101
+ 2.0.4 - 2010-11-14
102
+ ==================
103
+ * Fix issue where dirty tracking prevented job from being properly unlocked
104
+ * Add delayed_job_args variable for Capistrano recipe to allow configuration of started workers (e.g. "-n 2 --max-priority 10")
105
+ * Added options to handle_asynchronously
106
+ * Added Delayed::Worker.default_priority
107
+ * Allow private methods to be delayed
108
+ * Fixes for Ruby 1.9
109
+ * Added -m command line option to start a monitor process
110
+ * normalize logging in worker
111
+ * Deprecate #send_later and #send_at in favor of new #delay method
112
+ * Added @#delay@ to Object that allows you to delay any method and pass options:
113
+ options = {:priority => 19, :run_at => 5.minutes.from_now}
114
+ UserMailer.delay(options).deliver_confirmation(@user)
115
+
116
+ 2.0.3 - 2010-04-16
117
+ ==================
118
+ * Fix initialization for Rails 2.x
119
+
120
+ 2.0.2 - 2010-04-08
121
+ ==================
122
+ * Fixes to Mongo Mapper backend [ "14be7a24":http://github.com/collectiveidea/delayed_job/commit/14be7a24, "dafd5f46":http://github.com/collectiveidea/delayed_job/commit/dafd5f46, "54d40913":http://github.com/collectiveidea/delayed_job/commit/54d40913 ]
123
+ * DataMapper backend performance improvements [ "93833cce":http://github.com/collectiveidea/delayed_job/commit/93833cce, "e9b1573e":http://github.com/collectiveidea/delayed_job/commit/e9b1573e, "37a16d11":http://github.com/collectiveidea/delayed_job/commit/37a16d11, "803f2bfa":http://github.com/collectiveidea/delayed_job/commit/803f2bfa ]
124
+ * Fixed Delayed::Command to create tmp/pids directory [ "8ec8ca41":http://github.com/collectiveidea/delayed_job/commit/8ec8ca41 ]
125
+ * Railtie to perform Rails 3 initialization [ "3e0fc41f":http://github.com/collectiveidea/delayed_job/commit/3e0fc41f ]
126
+ * Added on_permanent_failure hook [ "d2f14cd6":http://github.com/collectiveidea/delayed_job/commit/d2f14cd6 ]
127
+
128
+ 2.0.1 - 2010-04-03
129
+ ==================
130
+ * Bug fix for using ActiveRecord backend with daemon [martinbtt]
131
+
132
+ 2.0.0 - 2010-04-03
133
+ ==================
134
+ * Multiple backend support (See README for more details)
135
+ * Added MongoMapper backend [zbelzer, moneypools]
136
+ * Added DataMapper backend [lpetre]
137
+ * Reverse priority so the jobs table can be indexed. Lower numbers have higher priority. The default priority is 0, so increase it for jobs that are not important.
138
+ * Move most of the heavy lifting from Job to Worker (#work_off, #reschedule, #run, #min_priority, #max_priority, #max_run_time, #max_attempts, #worker_name) [albus522]
139
+ * Remove EvaledJob. Implement your own if you need this functionality.
140
+ * Only use Time.zone if it is set. Closes #20
141
+ * Fix for last_error recording when destroy_failed_jobs = false, max_attempts = 1
142
+ * Implemented worker name_prefix to maintain dynamic nature of pid detection
143
+ * Some Rails 3 compatibility fixes [fredwu]
144
+
145
+ 1.8.5 - 2010-03-15
146
+ ==================
147
+ * Set auto_flushing=true on Rails logger to fix logging in production
148
+ * Fix error message when trying to send_later on a method that doesn't exist
149
+ * Don't use rails_env in capistrano if it's not set. closes #22
150
+ * Delayed job should append to delayed_job.log not overwrite
151
+ * Version bump to 1.8.5
152
+ * fixing Time.now to be Time.zone.now if set to honor the app set local TimeZone
153
+ * Replaced @Worker::SLEEP@, @Job::MAX_ATTEMPTS@, and @Job::MAX_RUN_TIME@ with class methods that can be overridden.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,18 @@
1
+ How to contribute
2
+ =================
3
+
4
+ If you find what looks like a bug:
5
+
6
+ * Search the "mailing list":http://groups.google.com/group/delayed_job to see
7
+ if anyone else had the same issue.
8
+ * Check the "GitHub issue tracker":http://github.com/collectiveidea/delayed_job/issues/
9
+ to see if anyone else has reported issue.
10
+ * If you don't see anything, create an issue with information on how to reproduce it.
11
+
12
+ If you want to contribute an enhancement or a fix:
13
+
14
+ * Fork the project on GitHub.
15
+ * Make your changes with tests.
16
+ * Commit the changes without making changes to the Rakefile or any other files
17
+ that aren't related to your enhancement or fix.
18
+ * Send a pull request.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2005 Tobias Luetke
1
+ Copyright (c) 2005 Tobias Lütke
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,8 +1,19 @@
1
- h1. Delayed::Job "!https://travis-ci.org/collectiveidea/delayed_job.png!":http://travis-ci.org/collectiveidea/delayed_job "!https://gemnasium.com/collectiveidea/delayed_job.png?travis!":https://gemnasium.com/collectiveidea/delayed_job
2
-
3
- Delayed_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background.
4
-
5
- It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks. Amongst those tasks are:
1
+ Delayed::Job
2
+ ============
3
+ [![Gem Version](https://badge.fury.io/rb/delayed_job.png)][gem]
4
+ [![Build Status](https://secure.travis-ci.org/collectiveidea/delayed_job.png?branch=master)][travis]
5
+ [![Dependency Status](https://gemnasium.com/collectiveidea/delayed_job.png?travis)][gemnasium]
6
+ [![Code Climate](https://codeclimate.com/badge.png)][codeclimate]
7
+ [gem]: https://rubygems.org/gems/delayed_job
8
+ [travis]: http://travis-ci.org/collectiveidea/delayed_job
9
+ [gemnasium]: https://gemnasium.com/collectiveidea/delayed_job
10
+ [codeclimate]: https://codeclimate.com/github/collectiveidea/delayed_job
11
+
12
+ Delayed::Job (or DJ) encapsulates the common pattern of asynchronously executing
13
+ longer tasks in the background.
14
+
15
+ It is a direct extraction from Shopify where the job table is responsible for a
16
+ multitude of core tasks. Amongst those tasks are:
6
17
 
7
18
  * sending massive newsletters
8
19
  * image resizing
@@ -12,61 +23,57 @@ It is a direct extraction from Shopify where the job table is responsible for a
12
23
  * batch imports
13
24
  * spam checks
14
25
 
15
- "Follow us on Twitter":https://twitter.com/delayedjob to get updates and notices about new releases.
26
+ [Follow us on Twitter][twitter] to get updates and notices about new releases.
16
27
 
17
- h2. Installation
28
+ [twitter]: https://twitter.com/delayedjob
18
29
 
19
- delayed_job 3.0.0 only supports Rails 3.0+. See the "2.0 branch":https://github.com/collectiveidea/delayed_job/tree/v2.0 for Rails 2.
30
+ Installation
31
+ ============
32
+ delayed_job 3.0.0 only supports Rails 3.0+. See the [2.0
33
+ branch](https://github.com/collectiveidea/delayed_job/tree/v2.0) for Rails 2.
20
34
 
21
- delayed_job supports multiple backends for storing the job queue. "See the wiki for other backends":http://wiki.github.com/collectiveidea/delayed_job/backends.
35
+ delayed_job supports multiple backends for storing the job queue. [See the wiki
36
+ for other backends](http://wiki.github.com/collectiveidea/delayed_job/backends).
22
37
 
23
- If you plan to use delayed_job with Active Record, add @delayed_job_active_record@ to your @Gemfile@.
38
+ If you plan to use delayed_job with Active Record, add `delayed_job_active_record` to your `Gemfile`.
24
39
 
25
- <pre>
26
- gem 'delayed_job_active_record'
27
- </pre>
40
+ gem 'delayed_job_active_record'
28
41
 
29
- If you plan to use delayed_job with Mongoid, add @delayed_job_mongoid@ to your @Gemfile@.
42
+ If you plan to use delayed_job with Mongoid, add `delayed_job_mongoid` to your `Gemfile`.
30
43
 
31
- <pre>
32
- gem 'delayed_job_mongoid'
33
- </pre>
44
+ gem 'delayed_job_mongoid'
34
45
 
35
- Run @bundle install@ to install the backend and delayed_job gems.
46
+ Run `bundle install` to install the backend and delayed_job gems.
36
47
 
37
- The Active Record backend requires a jobs table. You can create that table by running the following command:
48
+ The Active Record backend requires a jobs table. You can create that table by
49
+ running the following command:
38
50
 
39
- <pre>
40
- $ rails generate delayed_job:active_record
41
- $ rake db:migrate
42
- </pre>
43
-
44
- h3. Upgrading from 2.x to 3.0.0 on Active Record
51
+ rails generate delayed_job:active_record
52
+ rake db:migrate
45
53
 
54
+ Upgrading from 2.x to 3.0.0 on Active Record
55
+ ============================================
46
56
  Delayed Job 3.0.0 introduces a new column to the delayed_jobs table.
47
57
 
48
58
  If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a migration to add the column.
49
59
 
50
- <pre>
51
- $ rails generate delayed_job:upgrade
52
- $ rake db:migrate
53
- </pre>
60
+ rails generate delayed_job:upgrade
61
+ rake db:migrate
54
62
 
55
- h2. Queuing Jobs
63
+ Queuing Jobs
64
+ ============
65
+ Call `.delay.method(params)` on any object and it will be processed in the background.
56
66
 
57
- Call @.delay.method(params)@ on any object and it will be processed in the background.
67
+ # without delayed_job
68
+ @user.activate!(@device)
58
69
 
59
- <pre>
60
- # without delayed_job
61
- @user.activate!(@device)
70
+ # with delayed_job
71
+ @user.delay.activate!(@device)
62
72
 
63
- # with delayed_job
64
- @user.delay.activate!(@device)
65
- </pre>
66
-
67
- If a method should always be run in the background, you can call @#handle_asynchronously@ after the method declaration:
73
+ If a method should always be run in the background, you can call
74
+ `#handle_asynchronously` after the method declaration:
68
75
 
69
- <pre>
76
+ ```ruby
70
77
  class Device
71
78
  def deliver
72
79
  # long running method
@@ -76,11 +83,13 @@ end
76
83
 
77
84
  device = Device.new
78
85
  device.deliver
79
- </pre>
86
+ ```
80
87
 
81
- handle_asynchronously can take as options anything you can pass to delay. In addition, the values can be Proc objects allowing call time evaluation of the value. For some examples:
88
+ handle_asynchronously can take as options anything you can pass to delay. In
89
+ addition, the values can be Proc objects allowing call time evaluation of the
90
+ value. For some examples:
82
91
 
83
- <pre>
92
+ ```ruby
84
93
  class LongTasks
85
94
  def send_mailer
86
95
  # Some other code
@@ -109,72 +118,84 @@ class LongTasks
109
118
  end
110
119
  handle_asynchronously :call_an_instance_method, :priority => Proc.new {|i| i.how_important }
111
120
  end
112
- </pre>
113
-
114
- h3. Rails 3 Mailers
121
+ ```
115
122
 
123
+ Rails 3 Mailers
124
+ ===============
116
125
  Due to how mailers are implemented in Rails 3, we had to do a little work around to get delayed_job to work.
117
126
 
118
- <pre>
127
+ ```ruby
119
128
  # without delayed_job
120
129
  Notifier.signup(@user).deliver
121
130
 
122
131
  # with delayed_job
123
132
  Notifier.delay.signup(@user)
124
- </pre>
133
+ ```
125
134
 
126
- Remove the @.deliver@ method to make it work. It's not ideal, but it's the best we could do for now.
135
+ Remove the `.deliver` method to make it work. It's not ideal, but it's the best
136
+ we could do for now.
127
137
 
128
- h3. Named Queues
138
+ Named Queues
139
+ ============
140
+ DJ 3 introduces Resque-style named queues while still retaining DJ-style
141
+ priority. The goal is to provide a system for grouping tasks to be worked by
142
+ separate pools of workers, which may be scaled and controlled individually.
129
143
 
130
- DJ 3 introduces Resque-style named queues while still retaining DJ-style priority. The goal is to provide a system for grouping tasks to be worked by separate pools of workers, which may be scaled and controlled individually.
144
+ Jobs can be assigned to a queue by setting the `queue` option:
131
145
 
132
- Jobs can be assigned to a queue by setting the @queue@ option:
133
-
134
- <pre>object.delay(:queue => 'tracking').method
146
+ ```ruby
147
+ object.delay(:queue => 'tracking').method
135
148
 
136
149
  Delayed::Job.enqueue job, :queue => 'tracking'
137
150
 
138
151
  handle_asynchronously :tweet_later, :queue => 'tweets'
139
- </pre>
140
-
141
- h2. Running Jobs
152
+ ```
142
153
 
143
- @script/delayed_job@ can be used to manage a background process which will start working off jobs.
154
+ Running Jobs
155
+ ============
156
+ `script/delayed_job` can be used to manage a background process which will
157
+ start working off jobs.
144
158
 
145
- To do so, add @gem "daemons"@ to your @Gemfile@ and make sure you've run `rails generate delayed_job`.
159
+ To do so, add `gem "daemons"` to your `Gemfile` and make sure you've run `rails
160
+ generate delayed_job`.
146
161
 
147
162
  You can then do the following:
148
163
 
149
- <pre>
150
- $ RAILS_ENV=production script/delayed_job start
151
- $ RAILS_ENV=production script/delayed_job stop
164
+ RAILS_ENV=production script/delayed_job start
165
+ RAILS_ENV=production script/delayed_job stop
152
166
 
153
- # Runs two workers in separate processes.
154
- $ RAILS_ENV=production script/delayed_job -n 2 start
155
- $ RAILS_ENV=production script/delayed_job stop
167
+ # Runs two workers in separate processes.
168
+ RAILS_ENV=production script/delayed_job -n 2 start
169
+ RAILS_ENV=production script/delayed_job stop
156
170
 
157
- # Set the --queue or --queues option to work from a particular queue.
158
- $ RAILS_ENV=production script/delayed_job --queue=tracking start
159
- $ RAILS_ENV=production script/delayed_job --queues=mailers,tasks start
160
- </pre>
171
+ # Set the --queue or --queues option to work from a particular queue.
172
+ RAILS_ENV=production script/delayed_job --queue=tracking start
173
+ RAILS_ENV=production script/delayed_job --queues=mailers,tasks start
161
174
 
162
- Workers can be running on any computer, as long as they have access to the database and their clock is in sync. Keep in mind that each worker will check the database at least every 5 seconds.
175
+ # Runs all available jobs and the exits
176
+ RAILS_ENV=production script/delayed_job start --exit-on-complete
177
+ # or to run in the foreground
178
+ RAILS_ENV=production script/delayed_job run --exit-on-complete
163
179
 
164
- You can also invoke @rake jobs:work@ which will start working off jobs. You can cancel the rake task with @CTRL-C@.
180
+ Workers can be running on any computer, as long as they have access to the
181
+ database and their clock is in sync. Keep in mind that each worker will check
182
+ the database at least every 5 seconds.
165
183
 
166
- Work off queues by setting the @QUEUE@ or @QUEUES@ environment variable.
184
+ You can also invoke `rake jobs:work` which will start working off jobs. You can
185
+ cancel the rake task with `CTRL-C`.
167
186
 
168
- <pre>
169
- QUEUE=tracking rake jobs:work
170
- QUEUES=mailers,tasks rake jobs:work
171
- </pre>
187
+ If you want to just run all available jobs and exit you can use `rake jobs:workoff`
172
188
 
173
- h2. Custom Jobs
189
+ Work off queues by setting the `QUEUE` or `QUEUES` environment variable.
174
190
 
191
+ QUEUE=tracking rake jobs:work
192
+ QUEUES=mailers,tasks rake jobs:work
193
+
194
+ Custom Jobs
195
+ ===========
175
196
  Jobs are simple ruby objects with a method called perform. Any object which responds to perform can be stuffed into the jobs table. Job objects are serialized to yaml so that they can later be resurrected by the job runner.
176
197
 
177
- <pre>
198
+ ```ruby
178
199
  class NewsletterJob < Struct.new(:text, :emails)
179
200
  def perform
180
201
  emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
@@ -182,13 +203,13 @@ class NewsletterJob < Struct.new(:text, :emails)
182
203
  end
183
204
 
184
205
  Delayed::Job.enqueue NewsletterJob.new('lorem ipsum...', Customers.find(:all).collect(&:email))
185
- </pre>
186
-
187
- h2. Hooks
206
+ ```
188
207
 
208
+ Hooks
209
+ =====
189
210
  You can define hooks on your job that will be called at different stages in the process:
190
211
 
191
- <pre>
212
+ ```ruby
192
213
  class ParanoidNewsletterJob < NewsletterJob
193
214
  def enqueue(job)
194
215
  record_stat 'newsletter_job/enqueue'
@@ -218,13 +239,13 @@ class ParanoidNewsletterJob < NewsletterJob
218
239
  page_sysadmin_in_the_middle_of_the_night
219
240
  end
220
241
  end
221
- </pre>
222
-
223
- h2. Gory Details
242
+ ```
224
243
 
244
+ Gory Details
245
+ ============
225
246
  The library revolves around a delayed_jobs table which looks as follows:
226
247
 
227
- <pre>
248
+ ```ruby
228
249
  create_table :delayed_jobs, :force => true do |table|
229
250
  table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
230
251
  table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
@@ -237,7 +258,7 @@ create_table :delayed_jobs, :force => true do |table|
237
258
  table.string :queue # The name of the queue this job is in
238
259
  table.timestamps
239
260
  end
240
- </pre>
261
+ ```
241
262
 
242
263
  On failure, the job is scheduled again in 5 seconds + N ** 4, where N is the number of retries.
243
264
 
@@ -258,7 +279,7 @@ It is possible to disable delayed jobs for testing purposes. Set Delayed::Worker
258
279
 
259
280
  Here is an example of changing job parameters in Rails:
260
281
 
261
- <pre>
282
+ ```ruby
262
283
  # config/initializers/delayed_job_config.rb
263
284
  Delayed::Worker.destroy_failed_jobs = false
264
285
  Delayed::Worker.sleep_delay = 60
@@ -266,12 +287,12 @@ Delayed::Worker.max_attempts = 3
266
287
  Delayed::Worker.max_run_time = 5.minutes
267
288
  Delayed::Worker.read_ahead = 10
268
289
  Delayed::Worker.delay_jobs = !Rails.env.test?
269
- </pre>
270
-
271
- h3. Cleaning up
272
-
273
- You can invoke @rake jobs:clear@ to delete all jobs in the queue.
290
+ ```
274
291
 
275
- h2. Mailing List
292
+ Cleaning up
293
+ ===========
294
+ You can invoke `rake jobs:clear` to delete all jobs in the queue.
276
295
 
277
- Join us on the "mailing list":http://groups.google.com/group/delayed_job
296
+ Mailing List
297
+ ============
298
+ Join us on the [mailing list](http://groups.google.com/group/delayed_job)
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'bundler/setup'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rspec/core/rake_task'
6
+ desc 'Run the specs'
7
+ RSpec::Core::RakeTask.new do |r|
8
+ r.verbose = false
9
+ end
10
+
11
+ task :default => :spec
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.add_dependency 'activesupport', '~> 3.0'
5
+ spec.authors = ["Brandon Keepers", "Brian Ryckbost", "Chris Gaffney", "David Genord II", "Erik Michaels-Ober", "Matt Griffin", "Steve Richert", "Tobias Lütke"]
6
+ spec.description = "Delayed_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background. It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks."
7
+ spec.email = ['brian@collectiveidea.com']
8
+ spec.files = %w(CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md Rakefile delayed_job.gemspec)
9
+ spec.files += Dir.glob('{contrib,lib,recipes,spec}/**/*')
10
+ spec.homepage = 'http://github.com/collectiveidea/delayed_job'
11
+ spec.licenses = ['MIT']
12
+ spec.name = 'delayed_job'
13
+ spec.require_paths = ['lib']
14
+ spec.summary = 'Database-backed asynchronous priority queue system -- Extracted from Shopify'
15
+ spec.test_files = Dir.glob('spec/**/*')
16
+ spec.version = '3.0.5'
17
+ end
@@ -18,6 +18,10 @@ shared_examples_for "a delayed_job backend" do
18
18
  described_class.delete_all
19
19
  end
20
20
 
21
+ after do
22
+ Delayed::Worker.reset
23
+ end
24
+
21
25
  it "sets run_at automatically if not set" do
22
26
  expect(described_class.create(:payload_object => ErrorJob.new ).run_at).not_to be_nil
23
27
  end
@@ -181,6 +185,10 @@ shared_examples_for "a delayed_job backend" do
181
185
  Delayed::Worker.max_run_time = 2.minutes
182
186
  end
183
187
 
188
+ after do
189
+ Time.zone = nil
190
+ end
191
+
184
192
  it "does not reserve failed jobs" do
185
193
  create_job :attempts => 50, :failed_at => described_class.db_time_now
186
194
  expect(described_class.reserve(worker)).to be_nil
@@ -249,7 +257,7 @@ shared_examples_for "a delayed_job backend" do
249
257
  end
250
258
 
251
259
  context "worker prioritization" do
252
- before(:each) do
260
+ after do
253
261
  Delayed::Worker.max_priority = nil
254
262
  Delayed::Worker.min_priority = nil
255
263
  end
@@ -267,15 +275,25 @@ shared_examples_for "a delayed_job backend" do
267
275
  it "only finds jobs greater than or equal to min priority" do
268
276
  min = 5
269
277
  Delayed::Worker.min_priority = min
270
- 10.times {|i| described_class.enqueue SimpleJob.new, :priority => i }
271
- 5.times { expect(described_class.reserve(worker).priority).to be >= min }
278
+ [4,5,6].sort_by {|i| rand }.each {|i| create_job :priority => i }
279
+ 2.times do
280
+ job = described_class.reserve(worker)
281
+ expect(job.priority).to be >= min
282
+ job.destroy
283
+ end
284
+ expect(described_class.reserve(worker)).to be_nil
272
285
  end
273
286
 
274
287
  it "only finds jobs less than or equal to max priority" do
275
288
  max = 5
276
289
  Delayed::Worker.max_priority = max
277
- 10.times {|i| described_class.enqueue SimpleJob.new, :priority => i }
278
- 5.times { expect(described_class.reserve(worker).priority).to be <= max }
290
+ [4,5,6].sort_by {|i| rand }.each {|i| create_job :priority => i }
291
+ 2.times do
292
+ job = described_class.reserve(worker)
293
+ expect(job.priority).to be <= max
294
+ job.destroy
295
+ end
296
+ expect(described_class.reserve(worker)).to be_nil
279
297
  end
280
298
  end
281
299
 
@@ -421,19 +439,19 @@ shared_examples_for "a delayed_job backend" do
421
439
 
422
440
  describe "running a job" do
423
441
  it "fails after Worker.max_run_time" do
424
- begin
425
- old_max_run_time = Delayed::Worker.max_run_time
426
- Delayed::Worker.max_run_time = 1.second
427
- job = Delayed::Job.create :payload_object => LongRunningJob.new
428
- worker.run(job)
429
- expect(job.reload.last_error).to match(/expired/)
430
- expect(job.attempts).to eq(1)
431
- ensure
432
- Delayed::Worker.max_run_time = old_max_run_time
433
- end
442
+ Delayed::Worker.max_run_time = 1.second
443
+ job = Delayed::Job.create :payload_object => LongRunningJob.new
444
+ worker.run(job)
445
+ expect(job.reload.last_error).to match(/expired/)
446
+ expect(job.reload.last_error).to match(/Delayed::Worker.max_run_time is only 1 second/)
447
+ expect(job.attempts).to eq(1)
434
448
  end
435
449
 
436
450
  context "when the job raises a deserialization error" do
451
+ after do
452
+ Delayed::Worker.destroy_failed_jobs = true
453
+ end
454
+
437
455
  it "marks the job as failed" do
438
456
  Delayed::Worker.destroy_failed_jobs = false
439
457
  job = described_class.create! :handler => "--- !ruby/object:JobThatDoesNotExist {}"
@@ -446,11 +464,12 @@ shared_examples_for "a delayed_job backend" do
446
464
 
447
465
  describe "failed jobs" do
448
466
  before do
449
- # reset defaults
450
- Delayed::Worker.destroy_failed_jobs = true
451
- Delayed::Worker.max_attempts = 25
467
+ @job = Delayed::Job.enqueue(ErrorJob.new, :run_at => described_class.db_time_now - 1)
468
+ end
452
469
 
453
- @job = Delayed::Job.enqueue(ErrorJob.new)
470
+ after do
471
+ # reset default
472
+ Delayed::Worker.destroy_failed_jobs = true
454
473
  end
455
474
 
456
475
  it "records last_error when destroy_failed_jobs = false, max_attempts = 1" do
@@ -535,10 +554,6 @@ shared_examples_for "a delayed_job backend" do
535
554
  end
536
555
 
537
556
  context "and we want to destroy jobs" do
538
- before do
539
- Delayed::Worker.destroy_failed_jobs = true
540
- end
541
-
542
557
  it_should_behave_like "any failure more than Worker.max_attempts times"
543
558
 
544
559
  it "is destroyed if it failed more than Worker.max_attempts times" do
@@ -557,6 +572,10 @@ shared_examples_for "a delayed_job backend" do
557
572
  Delayed::Worker.destroy_failed_jobs = false
558
573
  end
559
574
 
575
+ after do
576
+ Delayed::Worker.destroy_failed_jobs = true
577
+ end
578
+
560
579
  it_should_behave_like "any failure more than Worker.max_attempts times"
561
580
 
562
581
  it "is failed if it failed more than Worker.max_attempts times" do
@@ -61,6 +61,9 @@ module Delayed
61
61
  opts.on('--queue=queue', "Specify which queue DJ must look up for jobs") do |queue|
62
62
  @options[:queues] = queue.split(',')
63
63
  end
64
+ opts.on('--exit-on-complete', "Exit when no more jobs are available to run. This will exit if all jobs are scheduled to run in the future.") do
65
+ @options[:exit_on_complete] = true
66
+ end
64
67
  end
65
68
  @args = opts.parse!(args)
66
69
  end
@@ -0,0 +1,9 @@
1
+ require 'timeout'
2
+
3
+ module Delayed
4
+ class WorkerTimeout < Timeout::Error
5
+ def message
6
+ "#{super} (Delayed::Worker.max_run_time is only #{Delayed::Worker.max_run_time.to_i} seconds)"
7
+ end
8
+ end
9
+ end
@@ -111,6 +111,16 @@ module Psych
111
111
  rescue Mongoid::Errors::DocumentNotFound
112
112
  raise Delayed::DeserializationError
113
113
  end
114
+ when /^!ruby\/DataMapper:(.+)$/
115
+ klass = resolve_class($1)
116
+ payload = Hash[*object.children.map { |c| accept c }]
117
+ begin
118
+ primary_keys = klass.properties.select { |p| p.key? }
119
+ key_names = primary_keys.map { |p| p.name.to_s }
120
+ klass.get!(*key_names.map { |k| payload["attributes"][k] })
121
+ rescue DataMapper::ObjectNotFoundError
122
+ raise Delayed::DeserializationError
123
+ end
114
124
  else
115
125
  visit_Psych_Nodes_Mapping_without_class(object)
116
126
  end
data/lib/delayed/tasks.rb CHANGED
@@ -5,7 +5,21 @@ namespace :jobs do
5
5
  end
6
6
 
7
7
  desc "Start a delayed_job worker."
8
- task :work => :environment do
9
- Delayed::Worker.new(:min_priority => ENV['MIN_PRIORITY'], :max_priority => ENV['MAX_PRIORITY'], :queues => (ENV['QUEUES'] || ENV['QUEUE'] || '').split(','), :quiet => false).start
8
+ task :work => :environment_options do
9
+ Delayed::Worker.new(@worker_options).start
10
+ end
11
+
12
+ desc "Start a delayed_job worker and exit when all available jobs are complete."
13
+ task :workoff => :environment_options do
14
+ Delayed::Worker.new(@worker_options.merge({:exit_on_complete => true})).start
15
+ end
16
+
17
+ task :environment_options => :environment do
18
+ @worker_options = {
19
+ :min_priority => ENV['MIN_PRIORITY'],
20
+ :max_priority => ENV['MAX_PRIORITY'],
21
+ :queues => (ENV['QUEUES'] || ENV['QUEUE'] || '').split(','),
22
+ :quiet => false
23
+ }
10
24
  end
11
25
  end
@@ -18,7 +18,7 @@ module Delayed
18
18
 
19
19
  cattr_accessor :min_priority, :max_priority, :max_attempts, :max_run_time,
20
20
  :default_priority, :sleep_delay, :logger, :delay_jobs, :queues,
21
- :read_ahead, :plugins, :destroy_failed_jobs
21
+ :read_ahead, :plugins, :destroy_failed_jobs, :exit_on_complete
22
22
 
23
23
  # Named queue into which jobs are enqueued by default
24
24
  cattr_accessor :default_queue_name
@@ -47,6 +47,15 @@ module Delayed
47
47
  # (perhaps to inspect the reason for the failure), set this to false.
48
48
  self.destroy_failed_jobs = true
49
49
 
50
+ # By default, Signals INT and TERM set @exit, and the worker exits upon completion of the current job.
51
+ # If you would prefer to raise a SignalException and exit immediately you can use this.
52
+ # Be aware daemons uses TERM to stop and restart
53
+ # false - No exceptions will be raised
54
+ # :term - Will only raise an exception on TERM signals but INT will wait for the current job to finish
55
+ # true - Will raise an exception on TERM and INT
56
+ cattr_accessor :raise_signal_exceptions
57
+ self.raise_signal_exceptions = false
58
+
50
59
  self.logger = if defined?(Rails)
51
60
  Rails.logger
52
61
  elsif defined?(RAILS_DEFAULT_LOGGER)
@@ -97,11 +106,10 @@ module Delayed
97
106
 
98
107
  def initialize(options={})
99
108
  @quiet = options.has_key?(:quiet) ? options[:quiet] : true
100
- self.class.min_priority = options[:min_priority] if options.has_key?(:min_priority)
101
- self.class.max_priority = options[:max_priority] if options.has_key?(:max_priority)
102
- self.class.sleep_delay = options[:sleep_delay] if options.has_key?(:sleep_delay)
103
- self.class.read_ahead = options[:read_ahead] if options.has_key?(:read_ahead)
104
- self.class.queues = options[:queues] if options.has_key?(:queues)
109
+
110
+ [:min_priority, :max_priority, :sleep_delay, :read_ahead, :queues, :exit_on_complete].each do |option|
111
+ self.class.send("#{option}=", options[option]) if options.has_key?(option)
112
+ end
105
113
 
106
114
  self.plugins.each { |klass| klass.new }
107
115
  end
@@ -122,29 +130,39 @@ module Delayed
122
130
  end
123
131
 
124
132
  def start
125
- trap('TERM') { say 'Exiting...'; stop }
126
- trap('INT') { say 'Exiting...'; stop }
133
+ trap('TERM') do
134
+ say 'Exiting...'
135
+ stop
136
+ raise SignalException.new('TERM') if self.class.raise_signal_exceptions
137
+ end
138
+
139
+ trap('INT') do
140
+ say 'Exiting...'
141
+ stop
142
+ raise SignalException.new('INT') if self.class.raise_signal_exceptions && self.class.raise_signal_exceptions != :term
143
+ end
127
144
 
128
145
  say "Starting job worker"
129
146
 
130
147
  self.class.lifecycle.run_callbacks(:execute, self) do
131
148
  loop do
132
149
  self.class.lifecycle.run_callbacks(:loop, self) do
133
- result = nil
134
-
135
- realtime = Benchmark.realtime do
136
- result = work_off
150
+ @realtime = Benchmark.realtime do
151
+ @result = work_off
137
152
  end
153
+ end
138
154
 
139
- count = result.sum
140
-
141
- break if stop?
155
+ count = @result.sum
142
156
 
143
- if count.zero?
144
- sleep(self.class.sleep_delay)
157
+ if count.zero?
158
+ if self.class.exit_on_complete
159
+ say "No more jobs available. Exiting"
160
+ break
145
161
  else
146
- say "#{count} jobs processed at %.4f j/s, %d failed ..." % [count / realtime, result.last]
162
+ sleep(self.class.sleep_delay) unless stop?
147
163
  end
164
+ else
165
+ say "#{count} jobs processed at %.4f j/s, %d failed ..." % [count / @realtime, @result.last]
148
166
  end
149
167
 
150
168
  break if stop?
@@ -182,7 +200,7 @@ module Delayed
182
200
 
183
201
  def run(job)
184
202
  runtime = Benchmark.realtime do
185
- Timeout.timeout(self.class.max_run_time.to_i) { job.invoke_job }
203
+ Timeout.timeout(self.class.max_run_time.to_i, WorkerTimeout) { job.invoke_job }
186
204
  job.destroy
187
205
  end
188
206
  say "#{job.name} completed after %.4f" % runtime
data/lib/delayed_job.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'active_support'
2
+ require 'delayed/exceptions'
2
3
  require 'delayed/message_sending'
3
4
  require 'delayed/performable_method'
4
5
 
@@ -67,6 +67,10 @@ describe Delayed::MessageSending do
67
67
  end
68
68
  end
69
69
 
70
+ after do
71
+ Delayed::Worker.default_queue_name = nil
72
+ end
73
+
70
74
  it "creates a new PerformableMethod job" do
71
75
  expect {
72
76
  job = "hello".delay.count('l')
@@ -80,14 +84,12 @@ describe Delayed::MessageSending do
80
84
  Delayed::Worker.default_priority = 99
81
85
  job = FairyTail.delay.to_s
82
86
  expect(job.priority).to eq(99)
83
- Delayed::Worker.default_priority = 0
84
87
  end
85
88
 
86
89
  it "sets default queue name" do
87
90
  Delayed::Worker.default_queue_name = 'abbazabba'
88
91
  job = FairyTail.delay.to_s
89
92
  expect(job.queue).to eq('abbazabba')
90
- Delayed::Worker.default_queue_name = nil
91
93
  end
92
94
 
93
95
  it "sets job options" do
@@ -40,36 +40,44 @@ describe Delayed::PerformableMethod do
40
40
  end
41
41
 
42
42
  describe "hooks" do
43
- %w(enqueue before after success).each do |hook|
43
+ %w(before after success).each do |hook|
44
44
  it "delegates #{hook} hook to object" do
45
45
  story = Story.create
46
- story.should_receive(hook).with(an_instance_of(Delayed::Job))
47
- story.delay.tell.invoke_job
46
+ job = story.delay.tell
47
+
48
+ story.should_receive(hook).with(job)
49
+ job.invoke_job
48
50
  end
49
51
  end
50
52
 
51
53
  %w(before after success).each do |hook|
52
- it "delegates #{hook} hook to object when delay_jobs = false" do
53
- Delayed::Worker.delay_jobs = false
54
+ it "delegates #{hook} hook to object" do
54
55
  story = Story.create
55
- story.should_receive(hook).with(an_instance_of(Delayed::Job))
56
- story.delay.tell
56
+ job = story.delay.tell
57
+
58
+ story.should_receive(hook).with(job)
59
+ job.invoke_job
57
60
  end
58
61
  end
59
62
 
63
+ it "delegates enqueue hook to object" do
64
+ story = Story.create
65
+ story.should_receive(:enqueue).with(an_instance_of(Delayed::Job))
66
+ story.delay.tell
67
+ end
68
+
60
69
  it "delegates error hook to object" do
61
70
  story = Story.create
62
71
  story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
63
72
  story.should_receive(:tell).and_raise(RuntimeError)
64
- expect{story.delay.tell.invoke_job}.to raise_error
73
+ expect { story.delay.tell.invoke_job }.to raise_error
65
74
  end
66
75
 
67
76
  it "delegates error hook to object when delay_jobs = false" do
68
- Delayed::Worker.delay_jobs = false
69
77
  story = Story.create
70
78
  story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
71
79
  story.should_receive(:tell).and_raise(RuntimeError)
72
- expect{story.delay.tell}.to raise_error
80
+ expect { story.delay.tell.invoke_job }.to raise_error
73
81
  end
74
82
 
75
83
  it "delegates failure hook to object" do
@@ -78,12 +86,51 @@ describe Delayed::PerformableMethod do
78
86
  method.failure
79
87
  end
80
88
 
81
- it "delegates failure hook to object when delay_jobs = false" do
82
- Delayed::Worker.delay_jobs = false
83
- method = Delayed::PerformableMethod.new("object", :size, [])
84
- method.object.should_receive(:failure)
85
- method.failure
86
- end
89
+ context 'with delay_job == false' do
90
+ before do
91
+ Delayed::Worker.delay_jobs = false
92
+ end
87
93
 
94
+ after do
95
+ Delayed::Worker.delay_jobs = true
96
+ end
97
+
98
+ %w(before after success).each do |hook|
99
+ it "delegates #{hook} hook to object" do
100
+ story = Story.create
101
+ story.should_receive(hook).with(an_instance_of(Delayed::Job))
102
+ story.delay.tell
103
+ end
104
+ end
105
+
106
+ %w(before after success).each do |hook|
107
+ it "delegates #{hook} hook to object" do
108
+ story = Story.create
109
+ story.should_receive(hook).with(an_instance_of(Delayed::Job))
110
+ story.delay.tell
111
+ end
112
+ end
113
+
114
+ it "delegates error hook to object" do
115
+ story = Story.create
116
+ story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
117
+ story.should_receive(:tell).and_raise(RuntimeError)
118
+ expect { story.delay.tell }.to raise_error
119
+ end
120
+
121
+ it "delegates error hook to object when delay_jobs = false" do
122
+ story = Story.create
123
+ story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
124
+ story.should_receive(:tell).and_raise(RuntimeError)
125
+ expect { story.delay.tell }.to raise_error
126
+ end
127
+
128
+ it "delegates failure hook to object when delay_jobs = false" do
129
+ Delayed::Worker.delay_jobs = false
130
+ method = Delayed::PerformableMethod.new("object", :size, [])
131
+ method.object.should_receive(:failure)
132
+ method.failure
133
+ end
134
+ end
88
135
  end
89
136
  end
data/spec/worker_spec.rb CHANGED
@@ -7,6 +7,10 @@ describe Delayed::Worker do
7
7
  Delayed::Worker.backend = @clazz
8
8
  end
9
9
 
10
+ after do
11
+ Delayed::Worker.backend = :test
12
+ end
13
+
10
14
  it "sets the Delayed::Job constant to the backend" do
11
15
  expect(Delayed::Job).to eq(@clazz)
12
16
  end
@@ -37,4 +41,21 @@ describe Delayed::Worker do
37
41
  Delayed::Job.reserve(Delayed::Worker.new)
38
42
  end
39
43
  end
44
+
45
+ context "worker exit on complete" do
46
+ before do
47
+ Delayed::Worker.exit_on_complete = true
48
+ end
49
+
50
+ after do
51
+ Delayed::Worker.exit_on_complete = false
52
+ end
53
+
54
+ it "exits the loop when no jobs are available" do
55
+ worker = Delayed::Worker.new
56
+ Timeout::timeout(2) do
57
+ worker.start
58
+ end
59
+ end
60
+ end
40
61
  end
metadata CHANGED
@@ -1,137 +1,61 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.4
5
4
  prerelease:
5
+ version: 3.0.5
6
6
  platform: ruby
7
7
  authors:
8
- - Matt Griffin
8
+ - Brandon Keepers
9
9
  - Brian Ryckbost
10
- - Steve Richert
11
10
  - Chris Gaffney
12
- - Brandon Keepers
13
- - Tobias Lütke
14
11
  - David Genord II
12
+ - Erik Michaels-Ober
13
+ - Matt Griffin
14
+ - Steve Richert
15
+ - Tobias Lütke
15
16
  autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
- date: 2012-11-09 00:00:00.000000000 Z
19
+ date: 2013-01-28 00:00:00.000000000 Z
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
- name: activesupport
22
- requirement: !ruby/object:Gem::Requirement
23
- none: false
24
- requirements:
25
- - - ~>
26
- - !ruby/object:Gem::Version
27
- version: '3.0'
28
22
  type: :runtime
29
- prerelease: false
30
23
  version_requirements: !ruby/object:Gem::Requirement
31
24
  none: false
32
25
  requirements:
33
26
  - - ~>
34
27
  - !ruby/object:Gem::Version
35
28
  version: '3.0'
36
- - !ruby/object:Gem::Dependency
37
- name: activerecord
38
- requirement: !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ~>
42
- - !ruby/object:Gem::Version
43
- version: '3.0'
44
- type: :development
29
+ name: activesupport
45
30
  prerelease: false
46
- version_requirements: !ruby/object:Gem::Requirement
47
- none: false
48
- requirements:
49
- - - ~>
50
- - !ruby/object:Gem::Version
51
- version: '3.0'
52
- - !ruby/object:Gem::Dependency
53
- name: actionmailer
54
31
  requirement: !ruby/object:Gem::Requirement
55
32
  none: false
56
33
  requirements:
57
34
  - - ~>
58
35
  - !ruby/object:Gem::Version
59
36
  version: '3.0'
60
- type: :development
61
- prerelease: false
62
- version_requirements: !ruby/object:Gem::Requirement
63
- none: false
64
- requirements:
65
- - - ~>
66
- - !ruby/object:Gem::Version
67
- version: '3.0'
68
- - !ruby/object:Gem::Dependency
69
- name: rspec
70
- requirement: !ruby/object:Gem::Requirement
71
- none: false
72
- requirements:
73
- - - ~>
74
- - !ruby/object:Gem::Version
75
- version: '2.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- none: false
80
- requirements:
81
- - - ~>
82
- - !ruby/object:Gem::Version
83
- version: '2.0'
84
- - !ruby/object:Gem::Dependency
85
- name: rake
86
- requirement: !ruby/object:Gem::Requirement
87
- none: false
88
- requirements:
89
- - - ! '>='
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- type: :development
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- none: false
96
- requirements:
97
- - - ! '>='
98
- - !ruby/object:Gem::Version
99
- version: '0'
100
- - !ruby/object:Gem::Dependency
101
- name: simplecov
102
- requirement: !ruby/object:Gem::Requirement
103
- none: false
104
- requirements:
105
- - - ! '>='
106
- - !ruby/object:Gem::Version
107
- version: '0'
108
- type: :development
109
- prerelease: false
110
- version_requirements: !ruby/object:Gem::Requirement
111
- none: false
112
- requirements:
113
- - - ! '>='
114
- - !ruby/object:Gem::Version
115
- version: '0'
116
- description: ! 'Delayed_job (or DJ) encapsulates the common pattern of asynchronously
37
+ description: Delayed_job (or DJ) encapsulates the common pattern of asynchronously
117
38
  executing longer tasks in the background. It is a direct extraction from Shopify
118
39
  where the job table is responsible for a multitude of core tasks.
119
-
120
-
121
- This gem is collectiveidea''s fork (http://github.com/collectiveidea/delayed_job).'
122
40
  email:
123
41
  - brian@collectiveidea.com
124
42
  executables: []
125
43
  extensions: []
126
- extra_rdoc_files:
127
- - README.textile
44
+ extra_rdoc_files: []
128
45
  files:
46
+ - CHANGELOG.md
47
+ - CONTRIBUTING.md
48
+ - LICENSE.md
49
+ - README.md
50
+ - Rakefile
51
+ - delayed_job.gemspec
129
52
  - contrib/delayed_job.monitrc
130
53
  - contrib/delayed_job_multiple.monitrc
131
54
  - lib/delayed/backend/base.rb
132
55
  - lib/delayed/backend/shared_spec.rb
133
56
  - lib/delayed/command.rb
134
57
  - lib/delayed/deserialization_error.rb
58
+ - lib/delayed/exceptions.rb
135
59
  - lib/delayed/lifecycle.rb
136
60
  - lib/delayed/message_sending.rb
137
61
  - lib/delayed/performable_mailer.rb
@@ -165,16 +89,11 @@ files:
165
89
  - spec/test_backend_spec.rb
166
90
  - spec/worker_spec.rb
167
91
  - spec/yaml_ext_spec.rb
168
- - MIT-LICENSE
169
- - README.textile
170
92
  homepage: http://github.com/collectiveidea/delayed_job
171
- licenses: []
93
+ licenses:
94
+ - MIT
172
95
  post_install_message:
173
- rdoc_options:
174
- - --main
175
- - README.textile
176
- - --inline-source
177
- - --line-numbers
96
+ rdoc_options: []
178
97
  require_paths:
179
98
  - lib
180
99
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -182,19 +101,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
101
  requirements:
183
102
  - - ! '>='
184
103
  - !ruby/object:Gem::Version
185
- version: '0'
186
104
  segments:
187
105
  - 0
188
- hash: 1239923890963384547
106
+ hash: -2181840438794321912
107
+ version: '0'
189
108
  required_rubygems_version: !ruby/object:Gem::Requirement
190
109
  none: false
191
110
  requirements:
192
111
  - - ! '>='
193
112
  - !ruby/object:Gem::Version
194
- version: '0'
195
113
  segments:
196
114
  - 0
197
- hash: 1239923890963384547
115
+ hash: -2181840438794321912
116
+ version: '0'
198
117
  requirements: []
199
118
  rubyforge_project:
200
119
  rubygems_version: 1.8.23