navvy 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +2 -2
- data/VERSION +1 -1
- data/generators/navvy/templates/migration.rb +3 -1
- data/lib/navvy/configuration.rb +15 -0
- data/lib/navvy/job/active_record.rb +81 -10
- data/lib/navvy/job/data_mapper.rb +83 -11
- data/lib/navvy/job/mongo_mapper.rb +87 -13
- data/lib/navvy/job/sequel.rb +81 -10
- data/lib/navvy/log.rb +15 -1
- data/lib/navvy/worker.rb +13 -1
- data/lib/navvy.rb +15 -0
- data/navvy.gemspec +6 -3
- data/spec/configuration_spec.rb +85 -0
- data/spec/job_spec.rb +169 -1
- data/spec/setup/active_record.rb +2 -0
- data/spec/setup/sequel.rb +2 -0
- data/spec/spec_helper.rb +3 -1
- metadata +5 -2
data/README.textile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
h1. Navvy
|
2
2
|
|
3
|
-
Navvy is a simple background job processor inspired by "delayed_job":http://github.com/tobi/delayed_job, but aiming for database agnosticism. Currently Navvy supports ActiveRecord, MongoMapper and
|
3
|
+
Navvy is a simple Ruby background job processor inspired by "delayed_job":http://github.com/tobi/delayed_job, but aiming for database agnosticism. Currently Navvy supports ActiveRecord, MongoMapper, Sequel and DataMapper but it's extremely easy to write an adapter for your favorite ORM. Besides plain Ruby (1.8 & 1.9) it completely supports Rails Edge.
|
4
4
|
|
5
5
|
??“Navvy is a shorter form of navigator (UK) or navigational engineer (USA) and is particularly applied to describe the manual labourers working on major civil engineering projects. The term was coined in the late 18th century in Britain when numerous canals were being built, which were also sometimes known as "navigations". Canal navvies typically worked with shovels, pickaxes and barrows.”?? - "Wikipedia":http://en.wikipedia.org/wiki/Navvy
|
6
6
|
|
7
7
|
h2. Using Navvy
|
8
8
|
|
9
|
-
There
|
9
|
+
There are some "Installation Guide":http://wiki.github.com/jeffkreeftmeijer/navvy/installation (even for "Rails 3":http://wiki.github.com/jeffkreeftmeijer/navvy/installation-on-rails-edge) and a "Getting Started Guide":http://wiki.github.com/jeffkreeftmeijer/navvy/getting-started to put you on the right track. Any questions? Don't hesitate to "ask":http://github.com/inbox/new/jeffkreeftmeijer.
|
10
10
|
|
11
11
|
h2. Contributing
|
12
12
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -4,8 +4,10 @@ class CreateJobs < ActiveRecord::Migration
|
|
4
4
|
t.string :object
|
5
5
|
t.string :method_name
|
6
6
|
t.text :arguments
|
7
|
+
t.integer :priority, :default => 0
|
7
8
|
t.string :return
|
8
9
|
t.string :exception
|
10
|
+
t.integer :parent_id
|
9
11
|
t.datetime :created_at
|
10
12
|
t.datetime :run_at
|
11
13
|
t.datetime :started_at
|
@@ -13,7 +15,7 @@ class CreateJobs < ActiveRecord::Migration
|
|
13
15
|
t.datetime :failed_at
|
14
16
|
end
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
def self.down
|
18
20
|
drop_table :jobs
|
19
21
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Navvy
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :job_limit, :keep_jobs, :logger, :quiet, :sleep_time,
|
4
|
+
:max_attempts
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@job_limit = 100
|
8
|
+
@keep_jobs = false
|
9
|
+
@logger = nil
|
10
|
+
@quiet = false
|
11
|
+
@sleep_time = 5
|
12
|
+
@max_attempts = 25
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -4,17 +4,34 @@ require 'active_record'
|
|
4
4
|
module Navvy
|
5
5
|
class Job < ActiveRecord::Base
|
6
6
|
class << self
|
7
|
-
attr_writer :limit
|
8
|
-
attr_accessor :keep
|
7
|
+
attr_writer :limit, :keep, :max_attempts
|
9
8
|
end
|
10
9
|
|
11
10
|
##
|
12
|
-
# Default limit of jobs to be fetched
|
11
|
+
# Default limit of jobs to be fetched.
|
13
12
|
#
|
14
13
|
# @return [Integer] limit
|
15
14
|
|
16
15
|
def self.limit
|
17
|
-
@limit ||
|
16
|
+
@limit || Navvy.configuration.job_limit
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# If and how long the jobs should be kept.
|
21
|
+
#
|
22
|
+
# @return [Fixnum, true, false] keep
|
23
|
+
|
24
|
+
def self.keep
|
25
|
+
@keep || Navvy.configuration.keep_jobs
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# How often should a job be retried?
|
30
|
+
#
|
31
|
+
# @return [Fixnum] max_attempts
|
32
|
+
|
33
|
+
def self.max_attempts
|
34
|
+
@max_attempts || Navvy.configuration.max_attempts
|
18
35
|
end
|
19
36
|
|
20
37
|
##
|
@@ -23,7 +40,7 @@ module Navvy
|
|
23
40
|
# @return [true, false] keep
|
24
41
|
|
25
42
|
def self.keep?
|
26
|
-
keep = (
|
43
|
+
keep = (self.keep || false)
|
27
44
|
return keep.from_now >= Time.now if keep.is_a? Fixnum
|
28
45
|
keep
|
29
46
|
end
|
@@ -38,11 +55,19 @@ module Navvy
|
|
38
55
|
# @return [true, false]
|
39
56
|
|
40
57
|
def self.enqueue(object, method_name, *args)
|
58
|
+
options = {}
|
59
|
+
if args.last.is_a?(Hash)
|
60
|
+
options = args.last.delete(:job_options) || {}
|
61
|
+
args.pop if args.last.empty?
|
62
|
+
end
|
63
|
+
|
41
64
|
create(
|
42
65
|
:object => object.to_s,
|
43
66
|
:method_name => method_name.to_s,
|
44
67
|
:arguments => args,
|
45
|
-
:
|
68
|
+
:priority => options[:priority] || 0,
|
69
|
+
:parent_id => options[:parent_id],
|
70
|
+
:run_at => options[:run_at] || Time.now,
|
46
71
|
:created_at => Time.now
|
47
72
|
)
|
48
73
|
end
|
@@ -65,7 +90,7 @@ module Navvy
|
|
65
90
|
Time.now
|
66
91
|
],
|
67
92
|
:limit => limit,
|
68
|
-
:order => 'created_at'
|
93
|
+
:order => 'priority desc, created_at'
|
69
94
|
)
|
70
95
|
end
|
71
96
|
|
@@ -135,7 +160,8 @@ module Navvy
|
|
135
160
|
|
136
161
|
##
|
137
162
|
# Mark the job as failed. Will set failed_at to the current time and
|
138
|
-
# optionally add the exception message if provided.
|
163
|
+
# optionally add the exception message if provided. Also, it will retry
|
164
|
+
# the job unless max_attempts has been reached.
|
139
165
|
#
|
140
166
|
# @param [String] exception the exception message you want to store.
|
141
167
|
#
|
@@ -143,10 +169,44 @@ module Navvy
|
|
143
169
|
# update_attributes call
|
144
170
|
|
145
171
|
def failed(message = nil)
|
146
|
-
|
172
|
+
self.retry unless times_failed >= self.class.max_attempts
|
173
|
+
update_attributes(
|
147
174
|
:failed_at => Time.now,
|
148
175
|
:exception => message
|
149
|
-
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
##
|
180
|
+
# Retry the current job. Will add self to the queue again, giving the clone
|
181
|
+
# a parend_id equal to self.id.
|
182
|
+
#
|
183
|
+
# @return [true, false]
|
184
|
+
|
185
|
+
def retry
|
186
|
+
self.class.enqueue(
|
187
|
+
object,
|
188
|
+
method_name,
|
189
|
+
*(args << {
|
190
|
+
:job_options => {
|
191
|
+
:parent_id => parent_id || id,
|
192
|
+
:run_at => Time.now + times_failed ** 4,
|
193
|
+
:priority => priority
|
194
|
+
}
|
195
|
+
})
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
##
|
200
|
+
# Check how many times the job has failed. Will try to find jobs with a
|
201
|
+
# parent_id that's the same as self.id and count them
|
202
|
+
#
|
203
|
+
# @return [Integer] count the amount of times the job has failed
|
204
|
+
|
205
|
+
def times_failed
|
206
|
+
i = parent_id || id
|
207
|
+
self.class.count(
|
208
|
+
:conditions => "(`id` = '#{i}' OR `parent_id` = '#{i}') AND `failed_at` IS NOT NULL"
|
209
|
+
)
|
150
210
|
end
|
151
211
|
|
152
212
|
##
|
@@ -194,6 +254,17 @@ module Navvy
|
|
194
254
|
arguments.is_a?(Array) ? arguments : YAML.load(arguments)
|
195
255
|
end
|
196
256
|
|
257
|
+
##
|
258
|
+
# Get the job status
|
259
|
+
#
|
260
|
+
# @return [:pending, :completed, :failed] status
|
261
|
+
|
262
|
+
def status
|
263
|
+
return :completed if completed?
|
264
|
+
return :failed if failed?
|
265
|
+
:pending
|
266
|
+
end
|
267
|
+
|
197
268
|
alias_method :completed?, :completed_at?
|
198
269
|
alias_method :failed?, :failed_at?
|
199
270
|
end
|
@@ -4,10 +4,8 @@ require 'dm-core'
|
|
4
4
|
module Navvy
|
5
5
|
class Job
|
6
6
|
include DataMapper::Resource
|
7
|
-
|
8
7
|
class << self
|
9
|
-
attr_writer :limit
|
10
|
-
attr_accessor :keep
|
8
|
+
attr_writer :limit, :keep, :max_attempts
|
11
9
|
end
|
12
10
|
|
13
11
|
property :id, Serial
|
@@ -17,6 +15,7 @@ module Navvy
|
|
17
15
|
property :priority, Integer, :default => 0
|
18
16
|
property :return, String
|
19
17
|
property :exception, String
|
18
|
+
property :parent_id, Integer
|
20
19
|
property :created_at, Time
|
21
20
|
property :run_at, Time
|
22
21
|
property :started_at, Time
|
@@ -24,12 +23,30 @@ module Navvy
|
|
24
23
|
property :failed_at, Time
|
25
24
|
|
26
25
|
##
|
27
|
-
# Default limit of jobs to be fetched
|
26
|
+
# Default limit of jobs to be fetched.
|
28
27
|
#
|
29
28
|
# @return [Integer] limit
|
30
29
|
|
31
30
|
def self.limit
|
32
|
-
@limit ||
|
31
|
+
@limit || Navvy.configuration.job_limit
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# If and how long the jobs should be kept.
|
36
|
+
#
|
37
|
+
# @return [Fixnum, true, false] keep
|
38
|
+
|
39
|
+
def self.keep
|
40
|
+
@keep || Navvy.configuration.keep_jobs
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# How often should a job be retried?
|
45
|
+
#
|
46
|
+
# @return [Fixnum] max_attempts
|
47
|
+
|
48
|
+
def self.max_attempts
|
49
|
+
@max_attempts || Navvy.configuration.max_attempts
|
33
50
|
end
|
34
51
|
|
35
52
|
##
|
@@ -38,7 +55,7 @@ module Navvy
|
|
38
55
|
# @return [true, false] keep
|
39
56
|
|
40
57
|
def self.keep?
|
41
|
-
keep = (
|
58
|
+
keep = (self.keep || false)
|
42
59
|
return (Time.now + keep) >= Time.now if keep.is_a? Fixnum
|
43
60
|
keep
|
44
61
|
end
|
@@ -54,12 +71,20 @@ module Navvy
|
|
54
71
|
# @return [true, false]
|
55
72
|
|
56
73
|
def self.enqueue(object, method_name, *args)
|
74
|
+
options = {}
|
75
|
+
if args.last.is_a?(Hash)
|
76
|
+
options = args.last.delete(:job_options) || {}
|
77
|
+
args.pop if args.last.empty?
|
78
|
+
end
|
79
|
+
|
57
80
|
new_job = self.new
|
58
81
|
new_job.attributes = {
|
59
82
|
:object => object.to_s,
|
60
83
|
:method_name => method_name.to_s,
|
61
84
|
:arguments => args.to_yaml,
|
62
|
-
:
|
85
|
+
:priority => options[:priority] || 0,
|
86
|
+
:parent_id => options[:parent_id],
|
87
|
+
:run_at => options[:run_at] || Time.now,
|
63
88
|
:created_at => Time.now
|
64
89
|
}
|
65
90
|
new_job.save
|
@@ -81,13 +106,13 @@ module Navvy
|
|
81
106
|
all(
|
82
107
|
:failed_at => nil,
|
83
108
|
:completed_at => nil,
|
84
|
-
:run_at.lte =>
|
109
|
+
:run_at.lte => Time.now,
|
85
110
|
:order => [ :priority.desc, :created_at.asc ],
|
86
111
|
:limit => limit
|
87
112
|
)
|
88
113
|
end
|
89
114
|
|
90
|
-
##
|
115
|
+
##
|
91
116
|
# Clean up jobs that we don't need to keep anymore. If Navvy::Job.keep is
|
92
117
|
# false it'll delete every completed job, if it's a timestamp it'll only
|
93
118
|
# delete completed jobs that have passed their keeptime.
|
@@ -96,9 +121,9 @@ module Navvy
|
|
96
121
|
|
97
122
|
def self.cleanup
|
98
123
|
if keep.is_a? Fixnum
|
99
|
-
all(
|
124
|
+
all(:completed_at.lte => (Time.now - keep)).destroy
|
100
125
|
else
|
101
|
-
all(
|
126
|
+
all(:completed_at.not => nil ).destroy unless keep?
|
102
127
|
end
|
103
128
|
end
|
104
129
|
|
@@ -149,6 +174,8 @@ module Navvy
|
|
149
174
|
##
|
150
175
|
# Mark the job as failed. Will set failed_at to the current time and
|
151
176
|
# optionally add the exception message if provided.
|
177
|
+
# optionally add the exception message if provided. Also, it will retry
|
178
|
+
# the job unless max_attempts has been reached.
|
152
179
|
#
|
153
180
|
# @param [String] exception the exception message you want to store.
|
154
181
|
#
|
@@ -156,12 +183,46 @@ module Navvy
|
|
156
183
|
# update_attributes call
|
157
184
|
|
158
185
|
def failed(message = nil)
|
186
|
+
self.retry unless times_failed >= self.class.max_attempts
|
159
187
|
update(
|
160
188
|
:failed_at => Time.now,
|
161
189
|
:exception => message
|
162
190
|
)
|
163
191
|
end
|
164
192
|
|
193
|
+
##
|
194
|
+
# Retry the current job. Will add self to the queue again, giving the clone
|
195
|
+
# a parend_id equal to self.id.
|
196
|
+
#
|
197
|
+
# @return [true, false]
|
198
|
+
|
199
|
+
def retry
|
200
|
+
self.class.enqueue(
|
201
|
+
object,
|
202
|
+
method_name,
|
203
|
+
*(args << {
|
204
|
+
:job_options => {
|
205
|
+
:parent_id => parent_id || id,
|
206
|
+
:run_at => Time.now + times_failed ** 4,
|
207
|
+
:priority => priority
|
208
|
+
}
|
209
|
+
})
|
210
|
+
)
|
211
|
+
end
|
212
|
+
|
213
|
+
##
|
214
|
+
# Check how many times the job has failed. Will try to find jobs with a
|
215
|
+
# parent_id that's the same as self.id and count them
|
216
|
+
#
|
217
|
+
# @return [Integer] count the amount of times the job has failed
|
218
|
+
|
219
|
+
def times_failed
|
220
|
+
i = parent_id || id
|
221
|
+
self.class.all(
|
222
|
+
:conditions => ["(`id` = ? OR `parent_id` = ?) AND `failed_at` IS NOT NULL", i, i]
|
223
|
+
).count
|
224
|
+
end
|
225
|
+
|
165
226
|
##
|
166
227
|
# Check if the job has been run.
|
167
228
|
#
|
@@ -207,6 +268,17 @@ module Navvy
|
|
207
268
|
arguments.is_a?(Array) ? arguments : YAML.load(arguments)
|
208
269
|
end
|
209
270
|
|
271
|
+
##
|
272
|
+
# Get the job status
|
273
|
+
#
|
274
|
+
# @return [:pending, :completed, :failed] status
|
275
|
+
|
276
|
+
def status
|
277
|
+
return :completed if completed?
|
278
|
+
return :failed if failed?
|
279
|
+
:pending
|
280
|
+
end
|
281
|
+
|
210
282
|
alias_method :completed?, :completed_at?
|
211
283
|
alias_method :failed?, :failed_at?
|
212
284
|
end
|
@@ -5,15 +5,16 @@ module Navvy
|
|
5
5
|
class Job
|
6
6
|
include MongoMapper::Document
|
7
7
|
class << self
|
8
|
-
attr_writer :limit
|
9
|
-
attr_accessor :keep
|
8
|
+
attr_writer :limit, :keep, :max_attempts
|
10
9
|
end
|
11
10
|
|
12
11
|
key :object, String
|
13
12
|
key :method_name, Symbol
|
14
|
-
key :arguments,
|
13
|
+
key :arguments, String
|
14
|
+
key :priority, Integer, :default => 0
|
15
15
|
key :return, String
|
16
16
|
key :exception, String
|
17
|
+
key :parent_id, ObjectId
|
17
18
|
key :created_at, Time
|
18
19
|
key :run_at, Time
|
19
20
|
key :started_at, Time
|
@@ -21,12 +22,30 @@ module Navvy
|
|
21
22
|
key :failed_at, Time
|
22
23
|
|
23
24
|
##
|
24
|
-
# Default limit of jobs to be fetched
|
25
|
+
# Default limit of jobs to be fetched.
|
25
26
|
#
|
26
27
|
# @return [Integer] limit
|
27
28
|
|
28
29
|
def self.limit
|
29
|
-
@limit ||
|
30
|
+
@limit || Navvy.configuration.job_limit
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# If and how long the jobs should be kept.
|
35
|
+
#
|
36
|
+
# @return [Fixnum, true, false] keep
|
37
|
+
|
38
|
+
def self.keep
|
39
|
+
@keep || Navvy.configuration.keep_jobs
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# How often should a job be retried?
|
44
|
+
#
|
45
|
+
# @return [Fixnum] max_attempts
|
46
|
+
|
47
|
+
def self.max_attempts
|
48
|
+
@max_attempts || Navvy.configuration.max_attempts
|
30
49
|
end
|
31
50
|
|
32
51
|
##
|
@@ -35,7 +54,7 @@ module Navvy
|
|
35
54
|
# @return [true, false] keep
|
36
55
|
|
37
56
|
def self.keep?
|
38
|
-
keep = (
|
57
|
+
keep = (self.keep || false)
|
39
58
|
return keep.from_now >= Time.now if keep.is_a? Fixnum
|
40
59
|
keep
|
41
60
|
end
|
@@ -51,11 +70,19 @@ module Navvy
|
|
51
70
|
# @return [true, false]
|
52
71
|
|
53
72
|
def self.enqueue(object, method_name, *args)
|
73
|
+
options = {}
|
74
|
+
if args.last.is_a?(Hash)
|
75
|
+
options = args.last.delete(:job_options) || {}
|
76
|
+
args.pop if args.last.empty?
|
77
|
+
end
|
78
|
+
|
54
79
|
create(
|
55
80
|
:object => object.to_s,
|
56
81
|
:method_name => method_name.to_sym,
|
57
|
-
:arguments => args,
|
58
|
-
:
|
82
|
+
:arguments => args.to_yaml,
|
83
|
+
:priority => options[:priority] || 0,
|
84
|
+
:parent_id => options[:parent_id],
|
85
|
+
:run_at => options[:run_at] || Time.now,
|
59
86
|
:created_at => Time.now
|
60
87
|
)
|
61
88
|
end
|
@@ -76,8 +103,8 @@ module Navvy
|
|
76
103
|
:failed_at => nil,
|
77
104
|
:completed_at => nil,
|
78
105
|
:run_at => {'$lte' => Time.now},
|
79
|
-
:
|
80
|
-
:
|
106
|
+
:order => 'priority desc, created_at asc',
|
107
|
+
:limit => limit
|
81
108
|
)
|
82
109
|
end
|
83
110
|
|
@@ -146,7 +173,8 @@ module Navvy
|
|
146
173
|
|
147
174
|
##
|
148
175
|
# Mark the job as failed. Will set failed_at to the current time and
|
149
|
-
# optionally add the exception message if provided.
|
176
|
+
# optionally add the exception message if provided. Also, it will retry
|
177
|
+
# the job unless max_attempts has been reached.
|
150
178
|
#
|
151
179
|
# @param [String] exception the exception message you want to store.
|
152
180
|
#
|
@@ -154,10 +182,45 @@ module Navvy
|
|
154
182
|
# update_attributes call
|
155
183
|
|
156
184
|
def failed(message = nil)
|
157
|
-
|
185
|
+
self.retry unless times_failed >= self.class.max_attempts
|
186
|
+
update_attributes(
|
158
187
|
:failed_at => Time.now,
|
159
188
|
:exception => message
|
160
|
-
|
189
|
+
)
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Retry the current job. Will add self to the queue again, giving the clone
|
194
|
+
# a parend_id equal to self.id.
|
195
|
+
#
|
196
|
+
# @return [true, false]
|
197
|
+
|
198
|
+
def retry
|
199
|
+
self.class.enqueue(
|
200
|
+
object,
|
201
|
+
method_name,
|
202
|
+
*(args << {
|
203
|
+
:job_options => {
|
204
|
+
:parent_id => parent_id || id,
|
205
|
+
:run_at => Time.now + times_failed ** 4,
|
206
|
+
:priority => priority
|
207
|
+
}
|
208
|
+
})
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
##
|
213
|
+
# Check how many times the job has failed. Will try to find jobs with a
|
214
|
+
# parent_id that's the same as self.id and count them
|
215
|
+
#
|
216
|
+
# @return [Integer] count the amount of times the job has failed
|
217
|
+
|
218
|
+
def times_failed
|
219
|
+
i = parent_id || id
|
220
|
+
self.class.count(
|
221
|
+
:failed_at => {'$ne' => nil},
|
222
|
+
'$where' => "this._id == '#{i}' || this.parent_id == '#{i}'"
|
223
|
+
)
|
161
224
|
end
|
162
225
|
|
163
226
|
##
|
@@ -187,6 +250,17 @@ module Navvy
|
|
187
250
|
arguments.is_a?(Array) ? arguments : YAML.load(arguments)
|
188
251
|
end
|
189
252
|
|
253
|
+
##
|
254
|
+
# Get the job status
|
255
|
+
#
|
256
|
+
# @return [:pending, :completed, :failed] status
|
257
|
+
|
258
|
+
def status
|
259
|
+
return :completed if completed?
|
260
|
+
return :failed if failed?
|
261
|
+
:pending
|
262
|
+
end
|
263
|
+
|
190
264
|
alias_method :completed?, :completed_at?
|
191
265
|
alias_method :failed?, :failed_at?
|
192
266
|
end
|
data/lib/navvy/job/sequel.rb
CHANGED
@@ -5,17 +5,34 @@ require 'yaml'
|
|
5
5
|
module Navvy
|
6
6
|
class Job < Sequel::Model
|
7
7
|
class << self
|
8
|
-
attr_writer :limit
|
9
|
-
attr_accessor :keep
|
8
|
+
attr_writer :limit, :keep, :max_attempts
|
10
9
|
end
|
11
10
|
|
12
11
|
##
|
13
|
-
# Default limit of jobs to be fetched
|
12
|
+
# Default limit of jobs to be fetched.
|
14
13
|
#
|
15
14
|
# @return [Integer] limit
|
16
15
|
|
17
16
|
def self.limit
|
18
|
-
@limit ||
|
17
|
+
@limit || Navvy.configuration.job_limit
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# If and how long the jobs should be kept.
|
22
|
+
#
|
23
|
+
# @return [Fixnum, true, false] keep
|
24
|
+
|
25
|
+
def self.keep
|
26
|
+
@keep || Navvy.configuration.keep_jobs
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# How often should a job be retried?
|
31
|
+
#
|
32
|
+
# @return [Fixnum] max_attempts
|
33
|
+
|
34
|
+
def self.max_attempts
|
35
|
+
@max_attempts || Navvy.configuration.max_attempts
|
19
36
|
end
|
20
37
|
|
21
38
|
##
|
@@ -24,7 +41,7 @@ module Navvy
|
|
24
41
|
# @return [true, false] keep
|
25
42
|
|
26
43
|
def self.keep?
|
27
|
-
keep = (
|
44
|
+
keep = (self.keep || false)
|
28
45
|
return (Time.now + keep) >= Time.now if keep.is_a? Fixnum
|
29
46
|
keep
|
30
47
|
end
|
@@ -40,11 +57,19 @@ module Navvy
|
|
40
57
|
# @return [true, false]
|
41
58
|
|
42
59
|
def self.enqueue(object, method_name, *args)
|
60
|
+
options = {}
|
61
|
+
if args.last.is_a?(Hash)
|
62
|
+
options = args.last.delete(:job_options) || {}
|
63
|
+
args.pop if args.last.empty?
|
64
|
+
end
|
65
|
+
|
43
66
|
create(
|
44
67
|
:object => object.to_s,
|
45
68
|
:method_name => method_name.to_s,
|
46
69
|
:arguments => args.to_yaml,
|
47
|
-
:
|
70
|
+
:priority => options[:priority] || 0,
|
71
|
+
:parent_id => options[:parent_id],
|
72
|
+
:run_at => options[:run_at] || Time.now,
|
48
73
|
:created_at => Time.now
|
49
74
|
)
|
50
75
|
end
|
@@ -64,7 +89,7 @@ module Navvy
|
|
64
89
|
filter(
|
65
90
|
'`failed_at` IS NULL AND `completed_at` IS NULL AND `run_at` <= ?',
|
66
91
|
Time.now
|
67
|
-
).order(:created_at).first(limit)
|
92
|
+
).order(:priority.desc, :created_at).first(limit)
|
68
93
|
end
|
69
94
|
|
70
95
|
##
|
@@ -124,7 +149,8 @@ module Navvy
|
|
124
149
|
|
125
150
|
##
|
126
151
|
# Mark the job as failed. Will set failed_at to the current time and
|
127
|
-
# optionally add the exception message if provided.
|
152
|
+
# optionally add the exception message if provided. Also, it will retry
|
153
|
+
# the job unless max_attempts has been reached.
|
128
154
|
#
|
129
155
|
# @param [String] exception the exception message you want to store.
|
130
156
|
#
|
@@ -132,10 +158,44 @@ module Navvy
|
|
132
158
|
# update_attributes call
|
133
159
|
|
134
160
|
def failed(message = nil)
|
135
|
-
|
161
|
+
self.retry unless times_failed >= self.class.max_attempts
|
162
|
+
update(
|
136
163
|
:failed_at => Time.now,
|
137
164
|
:exception => message
|
138
|
-
|
165
|
+
)
|
166
|
+
end
|
167
|
+
|
168
|
+
##
|
169
|
+
# Retry the current job. Will add self to the queue again, giving the clone
|
170
|
+
# a parend_id equal to self.id.
|
171
|
+
#
|
172
|
+
# @return [true, false]
|
173
|
+
|
174
|
+
def retry
|
175
|
+
self.class.enqueue(
|
176
|
+
object,
|
177
|
+
method_name,
|
178
|
+
*(args << {
|
179
|
+
:job_options => {
|
180
|
+
:parent_id => parent_id || id,
|
181
|
+
:run_at => Time.now + times_failed ** 4,
|
182
|
+
:priority => priority
|
183
|
+
}
|
184
|
+
})
|
185
|
+
)
|
186
|
+
end
|
187
|
+
|
188
|
+
##
|
189
|
+
# Check how many times the job has failed. Will try to find jobs with a
|
190
|
+
# parent_id that's the same as self.id and count them
|
191
|
+
#
|
192
|
+
# @return [Integer] count the amount of times the job has failed
|
193
|
+
|
194
|
+
def times_failed
|
195
|
+
i = parent_id || id
|
196
|
+
self.class.filter(
|
197
|
+
"(`id` == '#{i}' OR `parent_id` == '#{i}') AND `failed_at` IS NOT NULL"
|
198
|
+
).count
|
139
199
|
end
|
140
200
|
|
141
201
|
##
|
@@ -183,6 +243,17 @@ module Navvy
|
|
183
243
|
arguments.is_a?(Array) ? arguments : YAML.load(arguments)
|
184
244
|
end
|
185
245
|
|
246
|
+
##
|
247
|
+
# Get the job status
|
248
|
+
#
|
249
|
+
# @return [:pending, :completed, :failed] status
|
250
|
+
|
251
|
+
def status
|
252
|
+
return :completed if completed?
|
253
|
+
return :failed if failed?
|
254
|
+
:pending
|
255
|
+
end
|
256
|
+
|
186
257
|
alias_method :completed?, :completed_at?
|
187
258
|
alias_method :failed?, :failed_at?
|
188
259
|
end
|
data/lib/navvy/log.rb
CHANGED
@@ -7,8 +7,22 @@ module Navvy
|
|
7
7
|
|
8
8
|
class LoggerNotFound < StandardError; end
|
9
9
|
|
10
|
+
##
|
11
|
+
# Default logger
|
12
|
+
#
|
13
|
+
# @return [Symbol, nil] logger
|
14
|
+
|
10
15
|
def self.logger
|
11
|
-
@logger
|
16
|
+
@logger || Navvy.configuration.logger
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Be quiet?
|
21
|
+
#
|
22
|
+
# @return [true, false] quiet
|
23
|
+
|
24
|
+
def self.quiet
|
25
|
+
@quiet || Navvy.configuration.quiet
|
12
26
|
end
|
13
27
|
|
14
28
|
##
|
data/lib/navvy/worker.rb
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
module Navvy
|
2
2
|
class Worker
|
3
|
+
class << self
|
4
|
+
attr_writer :sleep_time
|
5
|
+
end
|
6
|
+
|
7
|
+
##
|
8
|
+
# Sleep time of the worker.
|
9
|
+
#
|
10
|
+
# @return [Integer] sleep
|
3
11
|
|
12
|
+
def self.sleep_time
|
13
|
+
@sleep_time || Navvy.configuration.sleep_time
|
14
|
+
end
|
15
|
+
|
4
16
|
##
|
5
17
|
# Start the worker.
|
6
18
|
|
@@ -17,7 +29,7 @@ module Navvy
|
|
17
29
|
Navvy::Job.cleanup
|
18
30
|
break
|
19
31
|
end
|
20
|
-
sleep
|
32
|
+
sleep sleep_time
|
21
33
|
end
|
22
34
|
end
|
23
35
|
|
data/lib/navvy.rb
CHANGED
@@ -1,2 +1,17 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/navvy/worker')
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/navvy/log')
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/navvy/configuration')
|
4
|
+
|
5
|
+
module Navvy
|
6
|
+
class << self
|
7
|
+
attr_writer :configuration
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.configuration
|
11
|
+
@configuration ||= Configuration.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.configure
|
15
|
+
yield(self.configuration)
|
16
|
+
end
|
17
|
+
end
|
data/navvy.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{navvy}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jeff Kreeftmeijer"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-02-08}
|
13
13
|
s.description = %q{Simple background job processor inspired by delayed_job, but aiming for database agnosticism.}
|
14
14
|
s.email = %q{jeff@kreeftmeijer.nl}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
"generators/navvy/templates/migration.rb",
|
28
28
|
"lib/generators/navvy_generator.rb",
|
29
29
|
"lib/navvy.rb",
|
30
|
+
"lib/navvy/configuration.rb",
|
30
31
|
"lib/navvy/job/active_record.rb",
|
31
32
|
"lib/navvy/job/data_mapper.rb",
|
32
33
|
"lib/navvy/job/mongo_mapper.rb",
|
@@ -35,6 +36,7 @@ Gem::Specification.new do |s|
|
|
35
36
|
"lib/navvy/tasks.rb",
|
36
37
|
"lib/navvy/worker.rb",
|
37
38
|
"navvy.gemspec",
|
39
|
+
"spec/configuration_spec.rb",
|
38
40
|
"spec/job_spec.rb",
|
39
41
|
"spec/log_spec.rb",
|
40
42
|
"spec/setup/active_record.rb",
|
@@ -52,7 +54,8 @@ Gem::Specification.new do |s|
|
|
52
54
|
s.rubygems_version = %q{1.3.5}
|
53
55
|
s.summary = %q{Simple background job processor inspired by delayed_job, but aiming for database agnosticism.}
|
54
56
|
s.test_files = [
|
55
|
-
"spec/
|
57
|
+
"spec/configuration_spec.rb",
|
58
|
+
"spec/job_spec.rb",
|
56
59
|
"spec/log_spec.rb",
|
57
60
|
"spec/setup/active_record.rb",
|
58
61
|
"spec/setup/data_mapper.rb",
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Navvy::Configuration do
|
4
|
+
after do
|
5
|
+
Navvy.configure do |config|
|
6
|
+
config.job_limit = 100
|
7
|
+
config.keep_jobs = false
|
8
|
+
config.logger = nil
|
9
|
+
config.quiet = true
|
10
|
+
config.sleep_time = 5
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should have a job limit of 100 by default' do
|
15
|
+
Navvy::Job.limit.should == 100
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should set the job limit' do
|
19
|
+
Navvy.configure do |config|
|
20
|
+
config.job_limit = 10
|
21
|
+
end
|
22
|
+
|
23
|
+
Navvy::Job.limit.should == 10
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have keep_jobs off by default' do
|
27
|
+
Navvy::Job.keep.should == false
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should set keep_jobs' do
|
31
|
+
Navvy.configure do |config|
|
32
|
+
config.keep_jobs = 10
|
33
|
+
end
|
34
|
+
|
35
|
+
Navvy::Job.keep.should == 10
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should not have a logger by default' do
|
39
|
+
Navvy::Log.logger.should == nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should set the keep_jobs' do
|
43
|
+
Navvy.configure do |config|
|
44
|
+
config.logger = :rails
|
45
|
+
end
|
46
|
+
|
47
|
+
Navvy::Log.logger.should == :rails
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should be quiet in the specs' do
|
51
|
+
Navvy::Log.quiet.should == true
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should turn quiet off' do
|
55
|
+
Navvy.configure do |config|
|
56
|
+
config.quiet = false
|
57
|
+
end
|
58
|
+
|
59
|
+
Navvy::Log.quiet.should == false
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should have a default sleep time of 5' do
|
63
|
+
Navvy::Worker.sleep_time.should == 5
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should turn quiet off' do
|
67
|
+
Navvy.configure do |config|
|
68
|
+
config.sleep_time = 10
|
69
|
+
end
|
70
|
+
|
71
|
+
Navvy::Worker.sleep_time.should == 10
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should have a default max_attempts of 25' do
|
75
|
+
Navvy::Job.max_attempts.should == 25
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should set max_attempts to 15' do
|
79
|
+
Navvy.configure do |config|
|
80
|
+
config.max_attempts = 15
|
81
|
+
end
|
82
|
+
|
83
|
+
Navvy::Job.max_attempts.should == 15
|
84
|
+
end
|
85
|
+
end
|
data/spec/job_spec.rb
CHANGED
@@ -1,6 +1,44 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe 'Navvy::Job' do
|
4
|
+
|
5
|
+
describe '.keep?' do
|
6
|
+
after(:each) do
|
7
|
+
Navvy::Job.keep = false
|
8
|
+
Navvy.configure do |config|
|
9
|
+
config.keep_jobs = false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'when configured using Navvy::Job.keep=' do
|
14
|
+
it 'should return false' do
|
15
|
+
Navvy::Job.keep = false
|
16
|
+
Navvy::Job.keep?.should == false
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return true' do
|
20
|
+
Navvy::Job.keep = true
|
21
|
+
Navvy::Job.keep?.should == true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'when configured with Navvy.configure' do
|
26
|
+
it 'should return false' do
|
27
|
+
Navvy.configure do |config|
|
28
|
+
config.keep_jobs = false
|
29
|
+
end
|
30
|
+
Navvy::Job.keep?.should == false
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should return true' do
|
34
|
+
Navvy.configure do |config|
|
35
|
+
config.keep_jobs = true
|
36
|
+
end
|
37
|
+
Navvy::Job.keep?.should == true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
4
42
|
describe '.enqueue' do
|
5
43
|
before(:each) do
|
6
44
|
delete_all_jobs
|
@@ -197,7 +235,6 @@ describe 'Navvy::Job' do
|
|
197
235
|
it 'should store the exception and current time' do
|
198
236
|
jobs = Navvy::Job.next
|
199
237
|
jobs.first.run
|
200
|
-
job_count.should == 1
|
201
238
|
jobs.first.exception.should == 'this method is broken'
|
202
239
|
jobs.first.started_at.should be_instance_of Time
|
203
240
|
jobs.first.failed_at.should be_instance_of Time
|
@@ -241,6 +278,137 @@ describe 'Navvy::Job' do
|
|
241
278
|
jobs.first.failed('broken')
|
242
279
|
jobs.first.exception.should == 'broken'
|
243
280
|
end
|
281
|
+
|
282
|
+
it 'should retry' do
|
283
|
+
jobs = Navvy::Job.next
|
284
|
+
jobs.first.should_receive(:retry)
|
285
|
+
jobs.first.failed('broken')
|
286
|
+
end
|
287
|
+
|
288
|
+
it 'should not retry when the job has failed 25 times already' do
|
289
|
+
jobs = Navvy::Job.next
|
290
|
+
jobs.first.stub!(:times_failed).and_return 25
|
291
|
+
jobs.first.should_not_receive(:retry)
|
292
|
+
jobs.first.failed('broken')
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should not retry when the job has failed 10 times' do
|
296
|
+
Navvy::Job.max_attempts = 10
|
297
|
+
jobs = Navvy::Job.next
|
298
|
+
jobs.first.stub!(:times_failed).and_return 10
|
299
|
+
jobs.first.should_not_receive(:retry)
|
300
|
+
jobs.first.failed('broken')
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe '#retry' do
|
305
|
+
before(:each) do
|
306
|
+
delete_all_jobs
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'should enqueue a child for the failed job' do
|
310
|
+
failed_job = Navvy::Job.enqueue(Cow, :speak, true, false)
|
311
|
+
job = failed_job.retry
|
312
|
+
job.object.should == 'Cow'
|
313
|
+
job.method_name.to_s.should == 'speak'
|
314
|
+
job.args.should == [true, false]
|
315
|
+
job.parent_id.should == failed_job.id
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'should handle hashes correctly' do
|
319
|
+
failed_job = Navvy::Job.enqueue(Cow, :speak, 'name' => 'Betsy')
|
320
|
+
job = failed_job.retry
|
321
|
+
job.args.should == [{'name' => 'Betsy'}]
|
322
|
+
job.parent_id.should == failed_job.id
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'should set the priority' do
|
326
|
+
failed_job = Navvy::Job.enqueue(
|
327
|
+
Cow,
|
328
|
+
:speak,
|
329
|
+
'name' => 'Betsy',
|
330
|
+
:job_options => {
|
331
|
+
:priority => 2
|
332
|
+
}
|
333
|
+
)
|
334
|
+
job = failed_job.retry
|
335
|
+
job.priority.should == 2
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'should set the run_at date to about 16 seconds from now' do
|
339
|
+
failed_job = Navvy::Job.enqueue(Cow, :speak, 'name' => 'Betsy')
|
340
|
+
failed_job.stub!(:times_failed).and_return 2
|
341
|
+
now = Time.now
|
342
|
+
job = failed_job.retry
|
343
|
+
job.run_at.to_i.should == (now + 16).to_i
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'should set the run_at date to about 256 seconds from now' do
|
347
|
+
failed_job = Navvy::Job.enqueue(Cow, :speak, 'name' => 'Betsy')
|
348
|
+
failed_job.stub!(:times_failed).and_return 4
|
349
|
+
now = Time.now
|
350
|
+
job = failed_job.retry
|
351
|
+
job.run_at.to_i.should == (now + 256).to_i
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should set the run_at date to about 4096 seconds from now' do
|
355
|
+
failed_job = Navvy::Job.enqueue(Cow, :speak, 'name' => 'Betsy')
|
356
|
+
failed_job.stub!(:times_failed).and_return 8
|
357
|
+
now = Time.now
|
358
|
+
job = failed_job.retry
|
359
|
+
job.run_at.to_i.should == (now + 4096).to_i
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'should set the parent_id to the master job id' do
|
363
|
+
failed_job = Navvy::Job.enqueue(Cow, :speak, 'name' => 'Betsy')
|
364
|
+
failed_child = failed_job.retry
|
365
|
+
failed_child.retry.parent_id.should == failed_job.id
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
describe '#times_failed' do
|
370
|
+
before(:each) do
|
371
|
+
delete_all_jobs
|
372
|
+
@failed_job = Navvy::Job.create(
|
373
|
+
:failed_at => Time.now
|
374
|
+
)
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'should return 1' do
|
378
|
+
@failed_job.times_failed.should == 1
|
379
|
+
end
|
380
|
+
|
381
|
+
it 'should return 3 when having 2 failed children' do
|
382
|
+
2.times do
|
383
|
+
Navvy::Job.create(
|
384
|
+
:failed_at => Time.now,
|
385
|
+
:parent_id => @failed_job.id
|
386
|
+
)
|
387
|
+
end
|
388
|
+
|
389
|
+
@failed_job.times_failed.should == 3
|
390
|
+
end
|
391
|
+
|
392
|
+
it 'should return 2 when having 1 failed and one pending child' do
|
393
|
+
Navvy::Job.create(
|
394
|
+
:failed_at => Time.now,
|
395
|
+
:parent_id => @failed_job.id
|
396
|
+
)
|
397
|
+
|
398
|
+
Navvy::Job.create(
|
399
|
+
:parent_id => @failed_job.id
|
400
|
+
)
|
401
|
+
|
402
|
+
@failed_job.times_failed.should == 2
|
403
|
+
end
|
404
|
+
|
405
|
+
it 'should return 2 when having failed and having a failed parent' do
|
406
|
+
failed_child = Navvy::Job.create(
|
407
|
+
:failed_at => Time.now,
|
408
|
+
:parent_id => @failed_job.id
|
409
|
+
)
|
410
|
+
failed_child.times_failed.should == 2
|
411
|
+
end
|
244
412
|
end
|
245
413
|
|
246
414
|
describe '#ran?' do
|
data/spec/setup/active_record.rb
CHANGED
@@ -8,8 +8,10 @@ ActiveRecord::Schema.define do
|
|
8
8
|
table.string :object
|
9
9
|
table.string :method_name
|
10
10
|
table.text :arguments
|
11
|
+
table.integer :priority, :default => 0
|
11
12
|
table.string :return
|
12
13
|
table.string :exception
|
14
|
+
table.integer :parent_id
|
13
15
|
table.datetime :created_at
|
14
16
|
table.datetime :run_at
|
15
17
|
table.datetime :started_at
|
data/spec/setup/sequel.rb
CHANGED
@@ -8,8 +8,10 @@ Sequel::DATABASES[0].create_table!(:jobs) do
|
|
8
8
|
String :object
|
9
9
|
String :method_name
|
10
10
|
String :arguments, :text => true
|
11
|
+
Integer :priority, :default => 0
|
11
12
|
String :return
|
12
13
|
String :exception
|
14
|
+
Integer :parent_id
|
13
15
|
DateTime :created_at
|
14
16
|
DateTime :run_at
|
15
17
|
DateTime :started_at
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: navvy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Kreeftmeijer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-02-08 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -82,6 +82,7 @@ files:
|
|
82
82
|
- generators/navvy/templates/migration.rb
|
83
83
|
- lib/generators/navvy_generator.rb
|
84
84
|
- lib/navvy.rb
|
85
|
+
- lib/navvy/configuration.rb
|
85
86
|
- lib/navvy/job/active_record.rb
|
86
87
|
- lib/navvy/job/data_mapper.rb
|
87
88
|
- lib/navvy/job/mongo_mapper.rb
|
@@ -90,6 +91,7 @@ files:
|
|
90
91
|
- lib/navvy/tasks.rb
|
91
92
|
- lib/navvy/worker.rb
|
92
93
|
- navvy.gemspec
|
94
|
+
- spec/configuration_spec.rb
|
93
95
|
- spec/job_spec.rb
|
94
96
|
- spec/log_spec.rb
|
95
97
|
- spec/setup/active_record.rb
|
@@ -129,6 +131,7 @@ signing_key:
|
|
129
131
|
specification_version: 3
|
130
132
|
summary: Simple background job processor inspired by delayed_job, but aiming for database agnosticism.
|
131
133
|
test_files:
|
134
|
+
- spec/configuration_spec.rb
|
132
135
|
- spec/job_spec.rb
|
133
136
|
- spec/log_spec.rb
|
134
137
|
- spec/setup/active_record.rb
|