rabbit_jobs 0.7.9 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/client +5 -3
- data/examples/configuration.rb +1 -1
- data/examples/worker +2 -2
- data/lib/rabbit_jobs/consumer/job_consumer.rb +19 -24
- data/lib/rabbit_jobs/job.rb +18 -1
- data/lib/rabbit_jobs/publisher.rb +3 -19
- data/lib/rabbit_jobs/version.rb +1 -1
- data/spec/fixtures/jobs.rb +7 -5
- data/spec/integration/worker_spec.rb +0 -28
- data/spec/unit/error_mailer_spec.rb +14 -0
- data/spec/unit/job_consumer_spec.rb +63 -0
- metadata +14 -12
data/examples/client
CHANGED
@@ -7,20 +7,22 @@ require File.expand_path('../../lib/rabbit_jobs', __FILE__)
|
|
7
7
|
|
8
8
|
class MyCurrentJob
|
9
9
|
include RJ::Job
|
10
|
-
|
10
|
+
queue :failover_test
|
11
|
+
def perform(count)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
15
|
RJ.configure { |c|
|
15
16
|
c.queue "failover_test"
|
16
|
-
c.server "amqp://localhost/
|
17
|
+
c.server "amqp://localhost/rj"
|
17
18
|
}
|
18
19
|
|
19
20
|
i = 0
|
20
21
|
loop do
|
21
22
|
puts "publishing job #{i}"
|
22
23
|
begin
|
23
|
-
RJ.publish_to(:failover_test, MyCurrentJob, i)
|
24
|
+
# RJ.publish_to(:failover_test, MyCurrentJob, i)
|
25
|
+
MyCurrentJob.perform_async(i)
|
24
26
|
rescue Exception => e
|
25
27
|
# RJ::Publisher.amqp_connection.stop
|
26
28
|
puts e.message
|
data/examples/configuration.rb
CHANGED
data/examples/worker
CHANGED
@@ -7,7 +7,7 @@ require File.expand_path('../../lib/rabbit_jobs', __FILE__)
|
|
7
7
|
|
8
8
|
class MyCurrentJob
|
9
9
|
include RJ::Job
|
10
|
-
def
|
10
|
+
def perform(count = 0)
|
11
11
|
puts count
|
12
12
|
# RJ.publish_to(:default, MyCurrentJob, count - 1) if count > 0
|
13
13
|
end
|
@@ -15,7 +15,7 @@ end
|
|
15
15
|
|
16
16
|
RJ.configure { |c|
|
17
17
|
c.queue "failover_test"
|
18
|
-
c.server "amqp://localhost/
|
18
|
+
c.server "amqp://localhost/rj"
|
19
19
|
}
|
20
20
|
|
21
21
|
worker = RJ::Worker.new
|
@@ -2,46 +2,41 @@
|
|
2
2
|
module RabbitJobs
|
3
3
|
module Consumer
|
4
4
|
class JobConsumer
|
5
|
+
include RabbitJobs::Helpers
|
6
|
+
|
5
7
|
def process_message(delivery_info, properties, payload)
|
6
8
|
job, *error_args = RJ::Job.parse(payload)
|
7
9
|
|
8
10
|
if job.is_a?(Symbol)
|
9
11
|
report_error(job, *error_args)
|
10
|
-
# case @job
|
11
|
-
# when :not_found
|
12
|
-
# when :parsing_error
|
13
|
-
# when :error
|
14
|
-
# end
|
15
12
|
else
|
16
13
|
if job.expired?
|
17
14
|
RJ.logger.warn "Job expired: #{job.to_ruby_string}"
|
18
|
-
false
|
19
15
|
else
|
20
16
|
job.run_perform
|
21
17
|
end
|
22
18
|
end
|
23
|
-
|
24
19
|
true
|
25
20
|
end
|
26
|
-
end
|
27
21
|
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
def log_error(msg)
|
23
|
+
RJ.logger.error msg
|
24
|
+
end
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
26
|
+
def report_error(error_type, *args)
|
27
|
+
case error_type
|
28
|
+
when :not_found
|
29
|
+
log_error "Cannot find job class '#{args.first}'"
|
30
|
+
when :parsing_error
|
31
|
+
log_error "Cannot initialize job. Json parsing error."
|
32
|
+
log_error "Data received: #{args.first.inspect}"
|
33
|
+
when :error
|
34
|
+
ex, payload = args
|
35
|
+
log_error "Cannot initialize job."
|
36
|
+
log_error ex.message
|
37
|
+
log_error _cleanup_backtrace(ex.backtrace).join("\n")
|
38
|
+
log_error "Data received: #{payload.inspect}"
|
39
|
+
end
|
45
40
|
end
|
46
41
|
end
|
47
42
|
end
|
data/lib/rabbit_jobs/job.rb
CHANGED
@@ -18,7 +18,7 @@ module RabbitJobs
|
|
18
18
|
begin
|
19
19
|
start_time = Time.now
|
20
20
|
RabbitJobs.logger.info "Started to perform #{self.to_ruby_string}"
|
21
|
-
self.
|
21
|
+
self.perform(*params)
|
22
22
|
execution_time = Time.now - start_time
|
23
23
|
RabbitJobs.logger.info " Job completed #{self.to_ruby_string} in #{execution_time} seconds."
|
24
24
|
rescue
|
@@ -117,6 +117,23 @@ module RabbitJobs
|
|
117
117
|
@rj_on_error_hooks << proc_or_symbol
|
118
118
|
end
|
119
119
|
end
|
120
|
+
|
121
|
+
def queue(routing_key)
|
122
|
+
raise ArgumentError unless routing_key.present?
|
123
|
+
@rj_queue = routing_key.to_sym
|
124
|
+
end
|
125
|
+
|
126
|
+
def perform_async(*args)
|
127
|
+
RJ::Publisher.publish_to(@rj_queue || :jobs, self, *args)
|
128
|
+
end
|
129
|
+
|
130
|
+
def serialize_job(*params)
|
131
|
+
{
|
132
|
+
'class' => self.to_s,
|
133
|
+
'opts' => {'created_at' => Time.now.to_i},
|
134
|
+
'params' => params
|
135
|
+
}.to_json
|
136
|
+
end
|
120
137
|
end
|
121
138
|
|
122
139
|
def self.parse(payload)
|
@@ -15,12 +15,7 @@ module RabbitJobs
|
|
15
15
|
routing_key = routing_key.to_sym unless routing_key.is_a?(Symbol)
|
16
16
|
raise ArgumentError.new("routing_key=#{routing_key}") unless RabbitJobs.config[:queues][routing_key]
|
17
17
|
|
18
|
-
payload =
|
19
|
-
'class' => klass.to_s,
|
20
|
-
'opts' => {'created_at' => Time.now.to_i},
|
21
|
-
'params' => params
|
22
|
-
}.to_json
|
23
|
-
|
18
|
+
payload = klass.serialize_job(*params)
|
24
19
|
direct_publish_to(routing_key, payload)
|
25
20
|
end
|
26
21
|
|
@@ -39,24 +34,13 @@ module RabbitJobs
|
|
39
34
|
true
|
40
35
|
end
|
41
36
|
|
42
|
-
def queue_status(routing_key)
|
43
|
-
raise ArgumentError unless routing_key.present?
|
44
|
-
|
45
|
-
routing_key = routing_key.to_sym
|
46
|
-
queue_declare_ok = connection.default_channel.queue_declare(routing_key, RabbitJobs.config[:queues][routing_key].merge(passive: true))
|
47
|
-
{
|
48
|
-
message_count: queue_declare_ok.message_count,
|
49
|
-
consumer_count: queue_declare_ok.consumer_count
|
50
|
-
}
|
51
|
-
end
|
52
|
-
|
53
37
|
def purge_queue(*routing_keys)
|
54
38
|
raise ArgumentError unless routing_keys.present?
|
55
39
|
|
56
40
|
messages_count = 0
|
57
|
-
|
58
41
|
routing_keys.map(&:to_sym).each do |routing_key|
|
59
|
-
|
42
|
+
queue = connection.default_channel.queue(routing_key, RabbitJobs.config[:queues][routing_key])
|
43
|
+
messages_count += queue.status[:message_count].to_i
|
60
44
|
connection.default_channel.queue_purge(routing_key)
|
61
45
|
end
|
62
46
|
|
data/lib/rabbit_jobs/version.rb
CHANGED
data/spec/fixtures/jobs.rb
CHANGED
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
class TestJob
|
4
4
|
include RJ::Job
|
5
|
+
def perform
|
6
|
+
end
|
5
7
|
end
|
6
8
|
|
7
9
|
class PrintTimeJob
|
8
10
|
include RJ::Job
|
9
11
|
|
10
|
-
def
|
12
|
+
def perform(time)
|
11
13
|
puts "Running job queued at #{time}"
|
12
14
|
end
|
13
15
|
end
|
@@ -15,7 +17,7 @@ end
|
|
15
17
|
class JobWithExpire
|
16
18
|
include RJ::Job
|
17
19
|
expires_in 60*60 # expires in 1 hour
|
18
|
-
def
|
20
|
+
def perform
|
19
21
|
|
20
22
|
end
|
21
23
|
end
|
@@ -23,7 +25,7 @@ end
|
|
23
25
|
class ExpiredJob
|
24
26
|
include RJ::Job
|
25
27
|
|
26
|
-
def
|
28
|
+
def perform
|
27
29
|
|
28
30
|
end
|
29
31
|
end
|
@@ -31,7 +33,7 @@ end
|
|
31
33
|
class JobWithPublish
|
32
34
|
include RJ::Job
|
33
35
|
|
34
|
-
def
|
36
|
+
def perform(param = 0)
|
35
37
|
if param < 5
|
36
38
|
puts "publishing job #{param}"
|
37
39
|
RJ.publish_to :rspec_durable_queue, JobWithPublish, param + 1
|
@@ -53,7 +55,7 @@ class JobWithErrorHook
|
|
53
55
|
puts 'last hook'
|
54
56
|
end
|
55
57
|
|
56
|
-
def
|
58
|
+
def perform
|
57
59
|
raise "Job raised an error at #{Time.now}"
|
58
60
|
end
|
59
61
|
end
|
@@ -2,34 +2,6 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe RabbitJobs::Worker do
|
5
|
-
it 'should listen for messages' do
|
6
|
-
RabbitJobs.configure do |c|
|
7
|
-
c.server 'amqp://localhost/rj'
|
8
|
-
c.queue 'rspec_durable_queue', auto_delete: false, durable: true, ack: true
|
9
|
-
end
|
10
|
-
|
11
|
-
RJ::Publisher.purge_queue('rspec_durable_queue')
|
12
|
-
count = 5
|
13
|
-
5.times {
|
14
|
-
RabbitJobs.publish_to(:rspec_durable_queue, PrintTimeJob, Time.now)
|
15
|
-
}
|
16
|
-
|
17
|
-
Timecop.freeze(Time.now - 4600) {
|
18
|
-
5.times { RabbitJobs.publish_to(:rspec_durable_queue, JobWithExpire) }
|
19
|
-
}
|
20
|
-
|
21
|
-
RabbitJobs.publish_to(:rspec_durable_queue, JobWithErrorHook)
|
22
|
-
|
23
|
-
worker = RabbitJobs::Worker.new
|
24
|
-
RJ.logger.level = Logger::FATAL
|
25
|
-
|
26
|
-
mock(PrintTimeJob).perform(anything).times(5)
|
27
|
-
mock(JobWithErrorHook).perform
|
28
|
-
dont_allow(JobWithExpire).perform
|
29
|
-
worker.work(1) # work for 1 second
|
30
|
-
RJ::Publisher.purge_queue('rspec_durable_queue')
|
31
|
-
end
|
32
|
-
|
33
5
|
it 'should allow to publish jobs from worker' do
|
34
6
|
RabbitJobs.configure do |c|
|
35
7
|
c.server 'amqp://localhost/rj'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe RabbitJobs::ErrorMailer do
|
5
|
+
describe '#report_error' do
|
6
|
+
it 'logs error raised in #send_letter' do
|
7
|
+
mock(RabbitJobs::ErrorMailer).enabled? { true }
|
8
|
+
mock(RabbitJobs::ErrorMailer).send_letter(anything, anything) { raise 'hello' }
|
9
|
+
|
10
|
+
mock(RabbitJobs.logger).error(anything)
|
11
|
+
RabbitJobs::ErrorMailer.report_error(TestJob.new, StandardError.new)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe RabbitJobs::Consumer::JobConsumer do
|
5
|
+
let(:consumer) { RabbitJobs::Consumer::JobConsumer.new }
|
6
|
+
let(:job) { TestJob.new }
|
7
|
+
|
8
|
+
describe '#process_message' do
|
9
|
+
it 'parses job' do
|
10
|
+
payload = TestJob.serialize_job
|
11
|
+
mock(RJ::Job).parse(payload) { job }
|
12
|
+
consumer.process_message(:delivery_info, :properties, payload)
|
13
|
+
end
|
14
|
+
it 'reports parsing errors' do
|
15
|
+
payload = "some bad json data"
|
16
|
+
mock(consumer).report_error(:parsing_error, payload)
|
17
|
+
consumer.process_message(:delivery_info, :properties, payload).should == true
|
18
|
+
end
|
19
|
+
it 'skips expired jobs' do
|
20
|
+
payload = TestJob.serialize_job
|
21
|
+
job
|
22
|
+
mock(TestJob).new { job }
|
23
|
+
mock(job).expired? { true }
|
24
|
+
dont_allow(job).run_perform
|
25
|
+
consumer.process_message(:delivery_info, :properties, payload)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'executes job.perform' do
|
29
|
+
payload = TestJob.serialize_job
|
30
|
+
job
|
31
|
+
mock(TestJob).new { job }
|
32
|
+
mock(job).run_perform
|
33
|
+
consumer.process_message(:delivery_info, :properties, payload)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#log_error' do
|
38
|
+
it 'logs error with RJ.logger' do
|
39
|
+
mock(RJ.logger).error("hello")
|
40
|
+
consumer.log_error 'hello'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#report_error' do
|
45
|
+
it "accepts error type :not_found" do
|
46
|
+
lambda { consumer.report_error(:not_found, 'klass_name') }.should_not raise_error
|
47
|
+
end
|
48
|
+
|
49
|
+
it "accepts error type :parsing_error" do
|
50
|
+
lambda { consumer.report_error(:parsing_error, 'payload data') }.should_not raise_error
|
51
|
+
end
|
52
|
+
|
53
|
+
it "accepts error type :error" do
|
54
|
+
exception = nil
|
55
|
+
begin
|
56
|
+
raise 'testing'
|
57
|
+
rescue Exception => e
|
58
|
+
exception = e
|
59
|
+
end
|
60
|
+
lambda { consumer.report_error(:error, exception, 'payload data') }.should_not raise_error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
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.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bunny
|
16
|
-
requirement: &
|
16
|
+
requirement: &4081060 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - =
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.9.0.pre8
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *4081060
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &4074840 !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: *4074840
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rufus-scheduler
|
38
|
-
requirement: &
|
38
|
+
requirement: &4466480 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '2.0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *4466480
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rails
|
49
|
-
requirement: &
|
49
|
+
requirement: &4465120 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '3.0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *4465120
|
58
58
|
description: Background jobs on RabbitMQ
|
59
59
|
email:
|
60
60
|
- lazureykis@gmail.com
|
@@ -97,6 +97,8 @@ files:
|
|
97
97
|
- spec/integration/worker_spec.rb
|
98
98
|
- spec/spec_helper.rb
|
99
99
|
- spec/unit/configuration_spec.rb
|
100
|
+
- spec/unit/error_mailer_spec.rb
|
101
|
+
- spec/unit/job_consumer_spec.rb
|
100
102
|
- spec/unit/job_spec.rb
|
101
103
|
- spec/unit/mailer_spec.rb
|
102
104
|
- spec/unit/rabbit_jobs_spec.rb
|
@@ -115,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
115
117
|
version: '0'
|
116
118
|
segments:
|
117
119
|
- 0
|
118
|
-
hash:
|
120
|
+
hash: 3460661242446233476
|
119
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
122
|
none: false
|
121
123
|
requirements:
|
@@ -124,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
126
|
version: '0'
|
125
127
|
segments:
|
126
128
|
- 0
|
127
|
-
hash:
|
129
|
+
hash: 3460661242446233476
|
128
130
|
requirements: []
|
129
131
|
rubyforge_project:
|
130
132
|
rubygems_version: 1.8.11
|