backburner 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|