rabbit_jobs 0.0.5 → 0.0.6
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/Gemfile +4 -3
- data/lib/rabbit_jobs.rb +1 -0
- data/lib/rabbit_jobs/configuration.rb +22 -0
- data/lib/rabbit_jobs/error_mailer.rb +37 -0
- data/lib/rabbit_jobs/job.rb +36 -6
- data/lib/rabbit_jobs/publisher.rb +2 -3
- data/lib/rabbit_jobs/scheduler.rb +2 -3
- data/lib/rabbit_jobs/version.rb +1 -1
- data/lib/rabbit_jobs/worker.rb +5 -3
- data/spec/fixtures/jobs.rb +17 -0
- data/spec/integration/worker_spec.rb +1 -0
- data/spec/unit/configuration_spec.rb +5 -0
- data/spec/unit/job_spec.rb +8 -2
- data/spec/unit/mailer_spec.rb +26 -0
- metadata +10 -7
data/Gemfile
CHANGED
@@ -2,12 +2,13 @@ source :rubygems
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem 'rabbit_jobs', :path => './'
|
6
|
-
|
7
5
|
group :development do
|
6
|
+
gem 'actionmailer', '>= 3.0'
|
7
|
+
|
8
8
|
gem 'rspec', '~> 2.8'
|
9
9
|
gem 'rr'
|
10
10
|
gem 'autotest'
|
11
|
-
|
11
|
+
gem 'autotest-fsevent'
|
12
|
+
gem 'autotest-growl'
|
12
13
|
gem 'simplecov', require: false
|
13
14
|
end
|
data/lib/rabbit_jobs.rb
CHANGED
@@ -49,6 +49,7 @@ module RabbitJobs
|
|
49
49
|
|
50
50
|
def initialize
|
51
51
|
@data = {
|
52
|
+
error_log: true,
|
52
53
|
host: 'localhost',
|
53
54
|
exchange: 'rabbit_jobs',
|
54
55
|
exchange_params: DEFAULT_EXCHANGE_PARAMS,
|
@@ -60,6 +61,27 @@ module RabbitJobs
|
|
60
61
|
@data[name]
|
61
62
|
end
|
62
63
|
|
64
|
+
def mail_errors_to(email = nil, from_email = nil)
|
65
|
+
if email && from_email
|
66
|
+
@data[:mail_errors_to] = email
|
67
|
+
@data[:mail_errors_form] = from_email
|
68
|
+
else
|
69
|
+
@data[:mail_errors_to]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def mail_errors_from
|
74
|
+
@data[:mail_errors_form]
|
75
|
+
end
|
76
|
+
|
77
|
+
def error_log
|
78
|
+
@data[:error_log]
|
79
|
+
end
|
80
|
+
|
81
|
+
def disable_error_log
|
82
|
+
@data[:error_log] = false
|
83
|
+
end
|
84
|
+
|
63
85
|
def host(value = nil)
|
64
86
|
if value
|
65
87
|
raise ArgumentError unless value.is_a?(String) && value != ""
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module RabbitJobs
|
4
|
+
class ErrorMailer
|
5
|
+
include RabbitJobs::Logger
|
6
|
+
|
7
|
+
def self.enabled?
|
8
|
+
!!RabbitJobs.config.mail_errors_from && !RabbitJobs.config.mail_errors_from.empty?
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.send(job, error = $!)
|
12
|
+
return unless enabled?
|
13
|
+
|
14
|
+
raise "You must require action_mailer or turn of error reporting in config." unless defined?(ActionMailer)
|
15
|
+
|
16
|
+
params ||= []
|
17
|
+
|
18
|
+
params_str = job.params == [] ? '' : job.params.map { |p| p.inspect }.join(', ')
|
19
|
+
subject = "RJ:Worker: #{error.class} on #{job.class}.perform(#{params_str}) "
|
20
|
+
text = "\n#{job.class}.perform(#{params_str})\n"
|
21
|
+
text += "\n#{error.inspect}\n"
|
22
|
+
text += "\nBacktrace:\n#{error.backtrace.join("\n")}" if error.backtrace
|
23
|
+
|
24
|
+
letter = ActionMailer::Base.mail
|
25
|
+
letter.from = RabbitJobs.config.mail_errors_from
|
26
|
+
letter.to = RabbitJobs.config.mail_errors_to
|
27
|
+
letter.subject = subject
|
28
|
+
letter.body = text
|
29
|
+
|
30
|
+
begin
|
31
|
+
letter.deliver
|
32
|
+
rescue
|
33
|
+
log $!.inspect
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/rabbit_jobs/job.rb
CHANGED
@@ -30,12 +30,34 @@ module RabbitJobs::Job
|
|
30
30
|
self.class.perform(*params)
|
31
31
|
# log 'after perform'
|
32
32
|
rescue
|
33
|
-
|
33
|
+
RabbitJobs::Logger.log($!.inspect) if RabbitJobs.config.error_log
|
34
|
+
RabbitJobs::ErrorMailer.send(self, $!)
|
35
|
+
|
36
|
+
run_on_error_hooks($!)
|
34
37
|
end
|
35
38
|
exit!
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
42
|
+
def run_on_error_hooks(error)
|
43
|
+
if self.class.rj_on_error_hooks
|
44
|
+
self.class.rj_on_error_hooks.each do |proc_or_symbol|
|
45
|
+
if proc_or_symbol.is_a?(Symbol)
|
46
|
+
self.send(proc_or_symbol, error, *params)
|
47
|
+
else
|
48
|
+
case proc_or_symbol.arity
|
49
|
+
when 0
|
50
|
+
proc_or_symbol.call()
|
51
|
+
when 1
|
52
|
+
proc_or_symbol.call(error)
|
53
|
+
else
|
54
|
+
proc_or_symbol.call(error, *params)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
39
61
|
def payload
|
40
62
|
{'class' => self.class.to_s, 'opts' => (self.opts || {}), 'params' => params}.to_json
|
41
63
|
# ([self.class.to_s] + params).to_json
|
@@ -46,14 +68,14 @@ module RabbitJobs::Job
|
|
46
68
|
end
|
47
69
|
|
48
70
|
def expires?
|
49
|
-
|
71
|
+
self.expires_in && self.expires_in > 0
|
50
72
|
end
|
51
73
|
|
52
74
|
def expired?
|
53
75
|
if self.opts['expires_at']
|
54
|
-
Time.now >
|
76
|
+
Time.now.to_i > opts['expires_at'].to_i
|
55
77
|
elsif expires? && opts['created_at']
|
56
|
-
Time.now > (
|
78
|
+
Time.now.to_i > (opts['created_at'].to_i + expires_in.to_i)
|
57
79
|
else
|
58
80
|
false
|
59
81
|
end
|
@@ -61,11 +83,19 @@ module RabbitJobs::Job
|
|
61
83
|
end
|
62
84
|
|
63
85
|
module ClassMethods
|
64
|
-
attr_accessor :rj_expires_in
|
86
|
+
attr_accessor :rj_expires_in, :rj_on_error_hooks
|
65
87
|
|
66
88
|
# DSL method for jobs
|
67
89
|
def expires_in(seconds)
|
68
|
-
@rj_expires_in = seconds
|
90
|
+
@rj_expires_in = seconds.to_i
|
91
|
+
end
|
92
|
+
|
93
|
+
def on_error(*hooks)
|
94
|
+
hooks.each do |proc_or_symbol|
|
95
|
+
raise ArgumentError unless proc_or_symbol && ( proc_or_symbol.is_a?(Proc) || proc_or_symbol.is_a?(Symbol) )
|
96
|
+
@rj_on_error_hooks ||= []
|
97
|
+
@rj_on_error_hooks << proc_or_symbol
|
98
|
+
end
|
69
99
|
end
|
70
100
|
end
|
71
101
|
|
@@ -33,7 +33,7 @@ module RabbitJobs
|
|
33
33
|
|
34
34
|
queue = make_queue(exchange, routing_key)
|
35
35
|
|
36
|
-
job.opts['created_at'] = Time.now.
|
36
|
+
job.opts['created_at'] = Time.now.to_i
|
37
37
|
|
38
38
|
payload = job.payload
|
39
39
|
exchange.publish(job.payload, Configuration::DEFAULT_MESSAGE_PARAMS.merge({routing_key: routing_key})) {
|
@@ -46,10 +46,9 @@ module RabbitJobs
|
|
46
46
|
|
47
47
|
def em_publish_job_to(routing_key, job)
|
48
48
|
em_amqp_with_exchange do |connection, exchange|
|
49
|
-
|
50
49
|
queue = make_queue(exchange, routing_key)
|
51
50
|
|
52
|
-
job.opts['created_at'] = Time.now.
|
51
|
+
job.opts['created_at'] = Time.now.to_i
|
53
52
|
|
54
53
|
payload = job.payload
|
55
54
|
exchange.publish(job.payload, Configuration::DEFAULT_MESSAGE_PARAMS.merge({routing_key: routing_key})) {
|
@@ -38,8 +38,8 @@ module RabbitJobs
|
|
38
38
|
interval_types = %w{cron every}
|
39
39
|
interval_types.each do |interval_type|
|
40
40
|
if !config[interval_type].nil? && config[interval_type].length > 0
|
41
|
+
log "queueing #{config['class']} (#{name})"
|
41
42
|
rufus_scheduler.send(interval_type, config[interval_type]) do
|
42
|
-
log! "queueing #{config['class']} (#{name})"
|
43
43
|
publish_from_config(config)
|
44
44
|
end
|
45
45
|
interval_defined = true
|
@@ -68,7 +68,7 @@ module RabbitJobs
|
|
68
68
|
log "publishing #{config}"
|
69
69
|
RabbitJobs.publish_to(queue, klass_name.constantize, nil, *params)
|
70
70
|
rescue
|
71
|
-
log! "Failed to
|
71
|
+
log! "Failed to publish #{klass_name}:\n #{$!}\n params = #{params.inspect}"
|
72
72
|
end
|
73
73
|
|
74
74
|
def rufus_scheduler
|
@@ -103,7 +103,6 @@ module RabbitJobs
|
|
103
103
|
if time > 0
|
104
104
|
# for debugging
|
105
105
|
EM.add_timer(time) do
|
106
|
-
log "Stopping scheduler..."
|
107
106
|
self.shutdown
|
108
107
|
end
|
109
108
|
end
|
data/lib/rabbit_jobs/version.rb
CHANGED
data/lib/rabbit_jobs/worker.rb
CHANGED
@@ -56,9 +56,11 @@ module RabbitJobs
|
|
56
56
|
|
57
57
|
queue.subscribe(ack: true) do |metadata, payload|
|
58
58
|
@job = RabbitJobs::Job.parse(payload)
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
unless @job.expired?
|
60
|
+
@job.run_perform
|
61
|
+
metadata.ack
|
62
|
+
processed_count += 1
|
63
|
+
end
|
62
64
|
check_shutdown.call
|
63
65
|
end
|
64
66
|
end
|
data/spec/fixtures/jobs.rb
CHANGED
@@ -26,4 +26,21 @@ class ExpiredJob
|
|
26
26
|
def self.perform
|
27
27
|
|
28
28
|
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class JobWithErrorHook
|
32
|
+
include RabbitJobs::Job
|
33
|
+
on_error :first_hook, lambda { puts "second hook" }, :last_hook
|
34
|
+
|
35
|
+
def first_hook(error)
|
36
|
+
puts 'first hook'
|
37
|
+
end
|
38
|
+
|
39
|
+
def last_hook(error)
|
40
|
+
puts 'last hook'
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.perform
|
44
|
+
raise "Job raised an error at #{Time.now}"
|
45
|
+
end
|
29
46
|
end
|
@@ -11,6 +11,7 @@ describe RabbitJobs::Worker do
|
|
11
11
|
|
12
12
|
5.times { RabbitJobs.publish(PrintTimeJob, nil, Time.now) }
|
13
13
|
5.times { RabbitJobs.publish(ExpiredJob, { :expires_at => Time.now - 10 }) }
|
14
|
+
1.times { RabbitJobs.publish(JobWithErrorHook) }
|
14
15
|
worker = RabbitJobs::Worker.new
|
15
16
|
|
16
17
|
worker.work(1) # work for 1 second
|
@@ -4,6 +4,8 @@ require 'spec_helper'
|
|
4
4
|
describe RabbitJobs::Configuration do
|
5
5
|
it 'builds configuration from configure block' do
|
6
6
|
RabbitJobs.configure do |c|
|
7
|
+
c.disable_error_log
|
8
|
+
|
7
9
|
c.host "somehost.lan"
|
8
10
|
|
9
11
|
c.exchange 'my_exchange', durable: true, auto_delete: false
|
@@ -13,6 +15,7 @@ describe RabbitJobs::Configuration do
|
|
13
15
|
end
|
14
16
|
|
15
17
|
RabbitJobs.config.to_hash.should == {
|
18
|
+
error_log: false,
|
16
19
|
host: "somehost.lan",
|
17
20
|
exchange: "my_exchange",
|
18
21
|
exchange_params: {
|
@@ -63,6 +66,7 @@ describe RabbitJobs::Configuration do
|
|
63
66
|
|
64
67
|
it 'use default config' do
|
65
68
|
RabbitJobs.config.to_hash.should == {
|
69
|
+
error_log: true,
|
66
70
|
host: "localhost",
|
67
71
|
exchange: "rabbit_jobs",
|
68
72
|
exchange_params: {
|
@@ -80,6 +84,7 @@ describe RabbitJobs::Configuration do
|
|
80
84
|
end
|
81
85
|
|
82
86
|
it 'returns settings on some methods' do
|
87
|
+
RabbitJobs.config.error_log == true
|
83
88
|
RabbitJobs.config.host.should == 'localhost'
|
84
89
|
RabbitJobs.config[:host].should == 'localhost'
|
85
90
|
RabbitJobs.config.routing_keys.should == ['default']
|
data/spec/unit/job_spec.rb
CHANGED
@@ -16,14 +16,20 @@ describe RabbitJobs::Job do
|
|
16
16
|
context 'job expiration' do
|
17
17
|
it 'should expire job by expires_in option' do
|
18
18
|
job = TestJob.new
|
19
|
-
job.opts['expires_at'] = (Time.now - 10).
|
19
|
+
job.opts['expires_at'] = (Time.now - 10).to_i
|
20
20
|
job.expired?.should == true
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should expire job by expires_in option in job class and current_time' do
|
24
24
|
job = JobWithExpire.new(1, 2, 3)
|
25
|
-
job.opts['created_at'] = (Time.now - job.expires_in - 10).
|
25
|
+
job.opts['created_at'] = (Time.now - job.expires_in - 10).to_i
|
26
26
|
job.expired?.should == true
|
27
27
|
end
|
28
|
+
|
29
|
+
it 'should not be expired with default params' do
|
30
|
+
job = TestJob.new(1, 2, 3)
|
31
|
+
job.opts['created_at'] = (Time.now).to_i
|
32
|
+
job.expired?.should == false
|
33
|
+
end
|
28
34
|
end
|
29
35
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'action_mailer'
|
4
|
+
|
5
|
+
describe RabbitJobs::ErrorMailer do
|
6
|
+
describe '#enabled?' do
|
7
|
+
it 'should be enabled when use setup email' do
|
8
|
+
RabbitJobs::ErrorMailer.enabled?.should == false
|
9
|
+
RabbitJobs.configure do |c|
|
10
|
+
c.mail_errors_to 'dev@exampe.com', 'app@example.com'
|
11
|
+
end
|
12
|
+
RabbitJobs::ErrorMailer.enabled?.should == true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#send' do
|
17
|
+
it 'should send email with error' do
|
18
|
+
email = ActionMailer::Base.mail
|
19
|
+
mock(ActionMailer::Base).mail { email }
|
20
|
+
mock(email).deliver { }
|
21
|
+
mock(RabbitJobs::ErrorMailer).enabled? { true }
|
22
|
+
|
23
|
+
RabbitJobs::ErrorMailer.send(TestJob.new, RuntimeError.new('error text'))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabbit_jobs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-02-01 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: amqp
|
16
|
-
requirement: &
|
16
|
+
requirement: &70238047574860 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0.9'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70238047574860
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70238047573560 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70238047573560
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rufus-scheduler
|
38
|
-
requirement: &
|
38
|
+
requirement: &70238047572140 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '2.0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70238047572140
|
47
47
|
description: Background jobs on RabbitMQ
|
48
48
|
email:
|
49
49
|
- lazureykis@gmail.com
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- lib/rabbit_jobs.rb
|
62
62
|
- lib/rabbit_jobs/amqp_helpers.rb
|
63
63
|
- lib/rabbit_jobs/configuration.rb
|
64
|
+
- lib/rabbit_jobs/error_mailer.rb
|
64
65
|
- lib/rabbit_jobs/helpers.rb
|
65
66
|
- lib/rabbit_jobs/job.rb
|
66
67
|
- lib/rabbit_jobs/logger.rb
|
@@ -81,6 +82,7 @@ files:
|
|
81
82
|
- spec/unit/configuration_spec.rb
|
82
83
|
- spec/unit/job_spec.rb
|
83
84
|
- spec/unit/logger_spec.rb
|
85
|
+
- spec/unit/mailer_spec.rb
|
84
86
|
- spec/unit/rabbit_jobs_spec.rb
|
85
87
|
- spec/unit/worker_spec.rb
|
86
88
|
homepage: ''
|
@@ -118,5 +120,6 @@ test_files:
|
|
118
120
|
- spec/unit/configuration_spec.rb
|
119
121
|
- spec/unit/job_spec.rb
|
120
122
|
- spec/unit/logger_spec.rb
|
123
|
+
- spec/unit/mailer_spec.rb
|
121
124
|
- spec/unit/rabbit_jobs_spec.rb
|
122
125
|
- spec/unit/worker_spec.rb
|