backburner 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -1
- data/TODO +7 -3
- data/backburner.gemspec +2 -3
- data/lib/backburner/logger.rb +6 -16
- data/lib/backburner/queue.rb +16 -1
- data/lib/backburner/version.rb +1 -1
- data/lib/backburner/worker.rb +12 -10
- data/test/logger_test.rb +3 -3
- data/test/queue_test.rb +7 -0
- data/test/worker_test.rb +2 -1
- metadata +16 -27
data/README.md
CHANGED
@@ -105,7 +105,8 @@ Here's an example:
|
|
105
105
|
```ruby
|
106
106
|
class NewsletterJob
|
107
107
|
include Backburner::Queue
|
108
|
-
queue "newsletter"
|
108
|
+
queue "newsletter" # defaults to 'newsletter-job'
|
109
|
+
queue_priority 1000 # most urgent priority is 0
|
109
110
|
|
110
111
|
def self.perform(email, body)
|
111
112
|
NewsletterMailer.deliver_text_to_email(email, body)
|
@@ -132,6 +133,8 @@ includes `Backburner::Performable`. Async enqueuing works for both instance and
|
|
132
133
|
```ruby
|
133
134
|
class User
|
134
135
|
include Backburner::Performable
|
136
|
+
queue "newsletter" # defaults to 'newsletter-job'
|
137
|
+
queue_priority 1000 # most urgent priority is 0
|
135
138
|
|
136
139
|
def activate(device_id)
|
137
140
|
@device = Device.find(device_id)
|
data/TODO
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
- Better way to enummerate job names in worker (right now using the tubes that exist but they may not exist even tho they will)
|
2
|
-
- Use a better way to aggregate tube names for different jobs
|
3
1
|
- Front-end in sinatra for viewing beanstalk jobs
|
2
|
+
- https://github.com/denniskuczynski/beanstalkd_view
|
4
3
|
- Better logging
|
5
|
-
-
|
4
|
+
- https://github.com/dpree/stalker/commit/70e94b7b445e08166bf2288dd1b7853396b26a86
|
5
|
+
- Better error handling (failures, retries)
|
6
|
+
- https://github.com/michaeldwan/stalker/commit/afd7e94d20991bcd96b65eda7c979d92d8746c3b
|
7
|
+
- https://github.com/michaeldwan/stalker/blob/master/lib/stalker/worker.rb
|
8
|
+
- Fork jobs to control memory
|
9
|
+
- https://github.com/michaeldwan/stalker/commit/386267690a7c03e11d1a8b7b6f08b7c9c7cd2c0d
|
data/backburner.gemspec
CHANGED
@@ -15,9 +15,8 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.require_paths = ["lib"]
|
16
16
|
s.version = Backburner::VERSION
|
17
17
|
|
18
|
-
s.add_runtime_dependency
|
19
|
-
s.add_runtime_dependency
|
20
|
-
s.add_runtime_dependency(%q<dante>)
|
18
|
+
s.add_runtime_dependency 'beanstalk-client', '~> 1.1'
|
19
|
+
s.add_runtime_dependency 'dante', '~> 0.1.5'
|
21
20
|
|
22
21
|
s.add_development_dependency 'rake'
|
23
22
|
s.add_development_dependency 'minitest'
|
data/lib/backburner/logger.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Backburner
|
2
2
|
module Logger
|
3
|
-
|
4
3
|
# Loads in instance and class levels
|
5
4
|
def self.included(base)
|
6
5
|
base.extend self
|
@@ -8,7 +7,7 @@ module Backburner
|
|
8
7
|
|
9
8
|
# Print out when a job is about to begin
|
10
9
|
def log_job_begin(body)
|
11
|
-
|
10
|
+
log_info [ "Working", body ].join(' ')
|
12
11
|
@job_begun = Time.now
|
13
12
|
end
|
14
13
|
|
@@ -16,25 +15,15 @@ module Backburner
|
|
16
15
|
def log_job_end(name, failed=false)
|
17
16
|
ellapsed = Time.now - @job_begun
|
18
17
|
ms = (ellapsed.to_f * 1000).to_i
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
# Prints message about failure when beastalk cannot be connected
|
23
|
-
#
|
24
|
-
# @example
|
25
|
-
# failed_connection(ex)
|
26
|
-
def failed_connection(e)
|
27
|
-
log_error exception_message(e)
|
28
|
-
log_error "*** Failed connection to #{connection.url}"
|
29
|
-
log_error "*** Check that beanstalkd is running (or set a different beanstalk url)"
|
30
|
-
exit 1
|
18
|
+
log_info "Finished #{name} in #{ms}ms #{failed ? ' (failed)' : ''}"
|
31
19
|
end
|
32
20
|
|
33
21
|
# Print a message to stdout
|
34
22
|
#
|
35
23
|
# @example
|
36
|
-
#
|
37
|
-
|
24
|
+
# log_info("Working on task")
|
25
|
+
#
|
26
|
+
def log_info(msg)
|
38
27
|
puts msg
|
39
28
|
end
|
40
29
|
|
@@ -42,6 +31,7 @@ module Backburner
|
|
42
31
|
#
|
43
32
|
# @example
|
44
33
|
# log_error("Task failed!")
|
34
|
+
#
|
45
35
|
def log_error(msg)
|
46
36
|
$stderr.puts msg
|
47
37
|
end
|
data/lib/backburner/queue.rb
CHANGED
@@ -11,7 +11,8 @@ module Backburner
|
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
# queue "some.task.name"
|
14
|
-
# queue => "some.task.name"
|
14
|
+
# @klass.queue # => "some.task.name"
|
15
|
+
#
|
15
16
|
def queue(name=nil)
|
16
17
|
if name
|
17
18
|
@queue_name = name
|
@@ -19,6 +20,20 @@ module Backburner
|
|
19
20
|
@queue_name || dasherize(self.name)
|
20
21
|
end
|
21
22
|
end
|
23
|
+
|
24
|
+
# Returns or assigns queue priority for this job
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# queue_priority 120
|
28
|
+
# @klass.queue_priority # => 120
|
29
|
+
#
|
30
|
+
def queue_priority(pri=nil)
|
31
|
+
if pri
|
32
|
+
@queue_priority = pri
|
33
|
+
else # accessor
|
34
|
+
@queue_priority
|
35
|
+
end
|
36
|
+
end
|
22
37
|
end # ClassMethods
|
23
38
|
end # Job
|
24
39
|
end # Backburner
|
data/lib/backburner/version.rb
CHANGED
data/lib/backburner/worker.rb
CHANGED
@@ -15,23 +15,24 @@ module Backburner
|
|
15
15
|
# Enqueues a job to be processed later by a worker
|
16
16
|
# Options: `pri` (priority), `delay` (delay in secs), `ttr` (time to respond), `queue` (queue name)
|
17
17
|
#
|
18
|
+
# @raise [Beanstalk::NotConnected] If beanstalk fails to connect.
|
18
19
|
# @example
|
19
20
|
# Backburner::Worker.enqueue NewsletterSender, [self.id, user.id], :ttr => 1000
|
20
21
|
#
|
21
22
|
def self.enqueue(job_class, args=[], opts={})
|
22
|
-
pri = opts[:pri] || Backburner.configuration.default_priority
|
23
|
+
pri = opts[:pri] || job_class.queue_priority || Backburner.configuration.default_priority
|
23
24
|
delay = [0, opts[:delay].to_i].max
|
24
25
|
ttr = opts[:ttr] || Backburner.configuration.respond_timeout
|
25
26
|
connection.use expand_tube_name(opts[:queue] || job_class)
|
26
27
|
data = { :class => job_class.name, :args => args }
|
27
28
|
connection.put data.to_json, pri, delay, ttr
|
28
|
-
rescue Beanstalk::NotConnected => e
|
29
|
-
failed_connection(e)
|
30
29
|
end
|
31
30
|
|
32
31
|
# Starts processing jobs in the specified tube_names
|
32
|
+
#
|
33
33
|
# @example
|
34
34
|
# Backburner::Worker.start(["foo.tube.name"])
|
35
|
+
#
|
35
36
|
def self.start(tube_names=nil)
|
36
37
|
self.new(tube_names).start
|
37
38
|
end
|
@@ -59,8 +60,10 @@ module Backburner
|
|
59
60
|
|
60
61
|
# Starts processing new jobs indefinitely
|
61
62
|
# Primary way to consume and process jobs in specified tubes
|
63
|
+
#
|
62
64
|
# @example
|
63
65
|
# @worker.start
|
66
|
+
#
|
64
67
|
def start
|
65
68
|
prepare
|
66
69
|
loop { work_one_job }
|
@@ -68,35 +71,34 @@ module Backburner
|
|
68
71
|
|
69
72
|
# Setup beanstalk tube_names and watch all specified tubes for jobs.
|
70
73
|
# Used to prepare job queues before processing jobs.
|
74
|
+
#
|
75
|
+
# @raise [Beanstalk::NotConnected] If beanstalk fails to connect.
|
71
76
|
# @example
|
72
77
|
# @worker.prepare
|
78
|
+
#
|
73
79
|
def prepare
|
74
80
|
self.tube_names ||= Backburner.default_queues.any? ? Backburner.default_queues : all_existing_queues
|
75
81
|
self.tube_names = Array(self.tube_names)
|
76
82
|
self.tube_names.map! { |name| expand_tube_name(name) }
|
77
|
-
|
83
|
+
log_info "Working #{tube_names.size} queues: [ #{tube_names.join(', ')} ]"
|
78
84
|
self.tube_names.uniq.each { |name| self.connection.watch(name) }
|
79
85
|
self.connection.list_tubes_watched.each do |server, tubes|
|
80
86
|
tubes.each { |tube| self.connection.ignore(tube) unless self.tube_names.include?(tube) }
|
81
87
|
end
|
82
|
-
rescue Beanstalk::NotConnected => e
|
83
|
-
failed_connection(e)
|
84
88
|
end
|
85
89
|
|
86
90
|
# Reserves one job within the specified queues
|
87
91
|
# Pops the job off and serializes the job to JSON
|
88
92
|
# Each job is performed by invoking `perform` on the job class.
|
93
|
+
#
|
89
94
|
# @example
|
90
95
|
# @worker.work_one_job
|
96
|
+
#
|
91
97
|
def work_one_job
|
92
98
|
job = Backburner::Job.new(self.connection.reserve)
|
93
99
|
self.class.log_job_begin(job.body)
|
94
100
|
job.process
|
95
101
|
self.class.log_job_end(job.name)
|
96
|
-
rescue Beanstalk::NotConnected => e
|
97
|
-
failed_connection(e)
|
98
|
-
rescue SystemExit
|
99
|
-
raise
|
100
102
|
rescue => e
|
101
103
|
job.bury
|
102
104
|
self.class.log_error self.class.exception_message(e)
|
data/test/logger_test.rb
CHANGED
@@ -3,12 +3,12 @@ require File.expand_path('../test_helper', __FILE__)
|
|
3
3
|
describe "Backburner::Logger module" do
|
4
4
|
include Backburner::Logger
|
5
5
|
|
6
|
-
describe "for
|
6
|
+
describe "for log_info method" do
|
7
7
|
it "prints out to std out" do
|
8
|
-
output = capture_stdout {
|
8
|
+
output = capture_stdout { log_info("foo") }
|
9
9
|
assert_equal "foo\n", output
|
10
10
|
end
|
11
|
-
end #
|
11
|
+
end # log_info
|
12
12
|
|
13
13
|
describe "for log_error method" do
|
14
14
|
it "prints out to std err" do
|
data/test/queue_test.rb
CHANGED
@@ -25,4 +25,11 @@ describe "Backburner::Queue module" do
|
|
25
25
|
assert_equal "nested/job", NestedDemo::TestJobB.queue
|
26
26
|
end
|
27
27
|
end # queue
|
28
|
+
|
29
|
+
describe "for queue_priority assignment method" do
|
30
|
+
it "should allow queue priority to be assigned" do
|
31
|
+
NestedDemo::TestJobB.queue_priority(1000)
|
32
|
+
assert_equal 1000, NestedDemo::TestJobB.queue_priority
|
33
|
+
end
|
34
|
+
end # queue
|
28
35
|
end # Backburner::Queue
|
data/test/worker_test.rb
CHANGED
@@ -4,6 +4,7 @@ $worker_test_count = 0
|
|
4
4
|
|
5
5
|
class TestJob
|
6
6
|
include Backburner::Queue
|
7
|
+
queue_priority 1000
|
7
8
|
def self.perform(x, y); $worker_test_count += x + y; end
|
8
9
|
end
|
9
10
|
|
@@ -27,7 +28,7 @@ describe "Backburner::Worker module" do
|
|
27
28
|
assert_equal "TestJob", body["class"]
|
28
29
|
assert_equal [3, 4], body["args"]
|
29
30
|
assert_equal 100, job.ttr
|
30
|
-
assert_equal
|
31
|
+
assert_equal 1000, job.pri
|
31
32
|
end # simple
|
32
33
|
|
33
34
|
it "should support enqueuing job with custom queue" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backburner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,44 +9,33 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: beanstalk-client
|
16
|
-
requirement: &
|
16
|
+
requirement: &2152606520 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *2152606340
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: json_pure
|
27
|
-
requirement: &2152605640 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ! '>='
|
19
|
+
- - ~>
|
31
20
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
21
|
+
version: '1.1'
|
33
22
|
type: :runtime
|
34
23
|
prerelease: false
|
35
|
-
version_requirements: *
|
24
|
+
version_requirements: *2152606520
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: dante
|
38
|
-
requirement: &
|
27
|
+
requirement: &2152605920 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
|
-
- -
|
30
|
+
- - ~>
|
42
31
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
32
|
+
version: 0.1.5
|
44
33
|
type: :runtime
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *2152605920
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: rake
|
49
|
-
requirement: &
|
38
|
+
requirement: &2152605440 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
@@ -54,10 +43,10 @@ dependencies:
|
|
54
43
|
version: '0'
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *2152605440
|
58
47
|
- !ruby/object:Gem::Dependency
|
59
48
|
name: minitest
|
60
|
-
requirement: &
|
49
|
+
requirement: &2152604860 !ruby/object:Gem::Requirement
|
61
50
|
none: false
|
62
51
|
requirements:
|
63
52
|
- - ! '>='
|
@@ -65,10 +54,10 @@ dependencies:
|
|
65
54
|
version: '0'
|
66
55
|
type: :development
|
67
56
|
prerelease: false
|
68
|
-
version_requirements: *
|
57
|
+
version_requirements: *2152604860
|
69
58
|
- !ruby/object:Gem::Dependency
|
70
59
|
name: mocha
|
71
|
-
requirement: &
|
60
|
+
requirement: &2152604240 !ruby/object:Gem::Requirement
|
72
61
|
none: false
|
73
62
|
requirements:
|
74
63
|
- - ! '>='
|
@@ -76,7 +65,7 @@ dependencies:
|
|
76
65
|
version: '0'
|
77
66
|
type: :development
|
78
67
|
prerelease: false
|
79
|
-
version_requirements: *
|
68
|
+
version_requirements: *2152604240
|
80
69
|
description: Beanstalk background job processing made easy
|
81
70
|
email:
|
82
71
|
- nesquena@gmail.com
|