rabbit_jobs 0.11.5 → 0.12.0

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.
@@ -2,15 +2,15 @@ require 'rabbit_jobs'
2
2
  require 'rake'
3
3
 
4
4
  def rails_env
5
- $my_rails_env ||= defined?(Rails) ? Rails.env : (ENV['RAILS_ENV'] || 'development')
5
+ defined?(Rails) ? Rails.env : (ENV['RAILS_ENV'] || 'development')
6
6
  end
7
7
 
8
8
  def app_root
9
- $my_rails_root ||= Pathname.new(ENV['RAILS_ROOT'] || Rails.root)
9
+ Pathname.new(ENV['RAILS_ROOT'] || Rails.root)
10
10
  end
11
11
 
12
12
  def make_dirs
13
- ["log", "tmp", "tmp/pids"].each do |subdir|
13
+ %w(log tmp tmp/pids).each do |subdir|
14
14
  dir = app_root.join(subdir)
15
15
  Dir.mkdir(dir) unless File.directory?(dir)
16
16
  end
@@ -21,9 +21,9 @@ namespace :rj do
21
21
  Rails.application.require_environment! if defined?(Rails)
22
22
  end
23
23
 
24
- desc "Start a Rabbit Jobs worker"
25
- task :worker => :environment do
26
- queues = (ENV['QUEUES'] || ENV['QUEUE'] || "").split(',')
24
+ desc 'Starts a Rabbit Jobs worker'
25
+ task worker: :environment do
26
+ queues = (ENV['QUEUES'] || ENV['QUEUE'] || '').split(',')
27
27
  make_dirs
28
28
  worker = RJ::Worker.new(*queues)
29
29
  worker.consumer = RJ::Consumer.const_get(ENV['CONSUMER'].classify).new if ENV['CONSUMER']
@@ -31,11 +31,11 @@ namespace :rj do
31
31
  exit(worker.work)
32
32
  end
33
33
 
34
- desc "Start a Rabbit Jobs scheduler"
34
+ desc 'Starts a Rabbit Jobs scheduler'
35
35
  task :scheduler do
36
36
  make_dirs
37
37
  scheduler = RabbitJobs::Scheduler.new
38
38
  scheduler.process_name = "rj_scheduler #{rails_env}"
39
39
  exit(scheduler.work)
40
40
  end
41
- end
41
+ end
@@ -1,5 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
-
3
1
  module RabbitJobs
4
- VERSION = "0.11.5"
2
+ VERSION = '0.12.0'
5
3
  end
@@ -1,32 +1,22 @@
1
- # -*- encoding : utf-8 -*-
1
+ require 'rabbit_jobs/amqp_transport'
2
2
 
3
3
  module RabbitJobs
4
+ # Worker daemon.
4
5
  class Worker
5
6
  include MainLoop
6
7
 
8
+ delegate :amqp_connection, :consumer_channel, :amqp_cleanup, to: RabbitJobs::AmqpTransport
9
+
7
10
  attr_accessor :process_name
8
11
  attr_reader :consumer
9
12
 
10
13
  def consumer=(value)
11
- raise ArgumentError.new("value=#{value.inspect}") unless value.respond_to?(:process_message)
14
+ unless value.respond_to?(:process_message)
15
+ fail ArgumentError, 'value must implement #process_message'
16
+ end
12
17
  @consumer = value
13
18
  end
14
19
 
15
- def amqp_connection
16
- Thread.current[:rj_worker_connection] ||= Bunny.new(RabbitJobs.config.server, automatically_recover: false,
17
- properties: Bunny::Session::DEFAULT_CLIENT_PROPERTIES.merge(product: "rj_worker #{Process.pid}")).start
18
- end
19
-
20
- def amqp_channel
21
- @amqp_channel ||= amqp_connection.create_channel
22
- end
23
-
24
- def self.cleanup
25
- conn = Thread.current[:rj_worker_connection]
26
- conn.close if conn && conn.status != :not_connected
27
- Thread.current[:rj_worker_connection] = nil
28
- end
29
-
30
20
  def queue_params(routing_key)
31
21
  RJ.config[:queues][routing_key.to_sym]
32
22
  end
@@ -47,7 +37,8 @@ module RabbitJobs
47
37
  if @queues == ['*'] || @queues.empty?
48
38
  @queues = RabbitJobs.config.routing_keys
49
39
  end
50
- raise "Cannot initialize worker without queues." if @queues.empty?
40
+
41
+ fail 'Cannot initialize worker without queues.' if @queues.empty?
51
42
  end
52
43
 
53
44
  def queues
@@ -55,26 +46,26 @@ module RabbitJobs
55
46
  end
56
47
 
57
48
  # Subscribes to queue and working on jobs
58
- def work(time = -1)
49
+ def work
59
50
  return false unless startup
60
51
  @consumer ||= RJ::Consumer::JobConsumer.new
61
52
 
62
- $0 = self.process_name || "rj_worker (#{queues.join(', ')})"
53
+ $0 = process_name || "rj_worker (#{queues.join(', ')})"
63
54
 
64
55
  @processed_count = 0
65
56
 
66
57
  begin
67
- amqp_channel.prefetch(1)
58
+ consumer_channel.prefetch(1)
68
59
 
69
60
  queues.each do |routing_key|
70
61
  consume_queue(routing_key)
71
62
  end
72
63
 
73
- RJ.logger.info "Started."
64
+ RJ.logger.info 'Started.'
74
65
 
75
- return main_loop(time) {
66
+ return main_loop do
76
67
  RJ.logger.info "Processed jobs: #{@processed_count}."
77
- }
68
+ end
78
69
  rescue
79
70
  log_daemon_error($!)
80
71
  end
@@ -82,29 +73,19 @@ module RabbitJobs
82
73
  true
83
74
  end
84
75
 
85
- def startup
86
- count = RJ._run_after_fork_callbacks
87
-
88
- $stdout.sync = true
89
-
90
- @shutdown = false
91
-
92
- Signal.trap('TERM') { shutdown }
93
- Signal.trap('INT') { shutdown! }
94
-
95
- true
96
- end
97
-
98
76
  private
99
77
 
100
78
  def consume_message(delivery_info, properties, payload)
101
- if (RJ.run_before_process_message_callbacks rescue nil)
79
+ if RJ.run_before_process_message_callbacks
102
80
  begin
103
81
  @consumer.process_message(delivery_info, properties, payload)
104
82
  @processed_count += 1
105
83
  rescue ScriptError, StandardError
106
- RabbitJobs.logger.error(short_message: $!.message,
107
- _payload: payload, _exception: $!.class, full_message: $!.backtrace.join("\r\n"))
84
+ RabbitJobs.logger.error(
85
+ short_message: $!.message,
86
+ _payload: payload,
87
+ _exception: $!.class,
88
+ full_message: $!.backtrace.join("\r\n"))
108
89
  end
109
90
  true
110
91
  else
@@ -117,16 +98,16 @@ module RabbitJobs
117
98
  RJ.logger.info "Subscribing to #{routing_key}"
118
99
  routing_key = routing_key.to_sym
119
100
 
120
- queue = amqp_channel.queue(routing_key, queue_params(routing_key))
101
+ queue = consumer_channel.queue(routing_key, queue_params(routing_key))
121
102
 
122
- explicit_ack = !!queue_params(routing_key)[:ack]
103
+ explicit_ack = queue_params(routing_key)[:manual_ack].present?
123
104
 
124
- queue.subscribe(ack: explicit_ack) do |delivery_info, properties, payload|
105
+ queue.subscribe(manual_ack: explicit_ack) do |delivery_info, properties, payload|
125
106
  if consume_message(delivery_info, properties, payload)
126
- amqp_channel.ack(delivery_info.delivery_tag) if explicit_ack
107
+ consumer_channel.ack(delivery_info.delivery_tag) if explicit_ack
127
108
  else
128
109
  requeue = false
129
- amqp_channel.nack(delivery_info.delivery_tag, requeue) if explicit_ack
110
+ consumer_channel.nack(delivery_info.delivery_tag, requeue) if explicit_ack
130
111
  end
131
112
  end
132
113
  end
@@ -1,2 +1,2 @@
1
1
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
2
- require 'rabbit_jobs/tasks'
2
+ require 'rabbit_jobs/tasks'
data/rabbit_jobs.gemspec CHANGED
@@ -1,33 +1,34 @@
1
- $:.push File.expand_path("../lib", __FILE__)
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  require 'rabbit_jobs/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.authors = ["Pavel Lazureykis"]
9
- spec.email = ["lazureykis@gmail.com"]
10
- spec.description = %q{Background jobs on RabbitMQ}
11
- spec.summary = %q{Background jobs on RabbitMQ}
12
- spec.homepage = ""
8
+ spec.authors = ['Pavel Lazureykis']
9
+ spec.email = ['lazureykis@gmail.com']
10
+ spec.description = 'Background jobs on RabbitMQ'
11
+ spec.summary = 'Background jobs on RabbitMQ'
12
+ spec.homepage = ''
13
13
  spec.date = Time.now.strftime('%Y-%m-%d')
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
16
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
- spec.name = "rabbit_jobs"
18
- spec.require_paths = ["lib"]
16
+ spec.test_files = spec.files.grep(/^spec/)
17
+ spec.name = 'rabbit_jobs'
18
+ spec.require_paths = ['lib']
19
19
  spec.version = RabbitJobs::VERSION
20
- spec.license = "MIT"
20
+ spec.license = 'MIT'
21
21
 
22
- spec.add_dependency "bunny", "~> 1.0"
23
- spec.add_dependency "rake"
24
- spec.add_dependency "rufus-scheduler", "~> 3.0"
25
- spec.add_dependency "activesupport", "~> 4.0"
22
+ spec.add_dependency 'bunny', '~> 1.6.0'
23
+ spec.add_dependency 'rake'
24
+ spec.add_dependency 'rufus-scheduler', '~> 3.0'
25
+ spec.add_dependency 'activesupport', '~> 4.0'
26
26
 
27
- spec.add_development_dependency "bundler"
27
+ spec.add_development_dependency 'bundler'
28
28
  # spec.add_development_dependency "rake"
29
- spec.add_development_dependency "timecop"
30
- spec.add_development_dependency "rspec"
31
- spec.add_development_dependency "rr"
32
- spec.add_development_dependency "simplecov"
29
+ spec.add_development_dependency 'timecop'
30
+ spec.add_development_dependency 'rspec'
31
+ spec.add_development_dependency 'rr'
32
+ spec.add_development_dependency 'simplecov'
33
+ spec.add_development_dependency 'codeclimate-test-reporter'
33
34
  end
@@ -4,10 +4,10 @@ rabbit_jobs:
4
4
  durable_queue:
5
5
  durable: true
6
6
  auto_delete: false
7
- ack: true
7
+ manual_ack: true
8
8
  arguments:
9
9
  x-ha-policy: all
10
10
  fast_queue:
11
11
  durable: false
12
12
  auto_delete: true
13
- ack: false
13
+ manual_ack: false
@@ -1,5 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
-
3
1
  class TestJob
4
2
  include RJ::Job
5
3
  def perform
@@ -16,7 +14,7 @@ end
16
14
 
17
15
  class JobWithExpire
18
16
  include RJ::Job
19
- expires_in 60*60 # expires in 1 hour
17
+ expires_in 1.hour
20
18
  def perform
21
19
 
22
20
  end
@@ -17,33 +17,54 @@ describe RabbitJobs::Publisher do
17
17
 
18
18
  it 'should publish message to queue' do
19
19
  RJ.publish_to(:rspec_queue, TestJob, 'some', 'other', 'params')
20
- RJ.purge_queue('rspec_queue').should == 1
20
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 1
21
+ RJ.purge_queue('rspec_queue')
22
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 0
21
23
  end
22
24
 
23
25
  it 'should accept symbol as queue name' do
24
26
  RJ.publish_to(:rspec_queue, TestJob)
25
- RJ.purge_queue('rspec_queue').should == 1
27
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 1
28
+ RJ.purge_queue('rspec_queue')
29
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 0
26
30
  end
27
31
 
28
32
  it 'purge_queue should accept many queues' do
29
33
  RJ.publish_to(:rspec_queue, TestJob)
30
34
  RJ.publish_to(:rspec_queue2, TestJob)
31
35
  RJ.publish_to(:rspec_queue3, TestJob)
32
- RJ.purge_queue(:rspec_queue, :rspec_queue2, :rspec_queue3).should == 3
36
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 1
37
+ RJ.queue_status('rspec_queue2')[:message_count].to_i.should == 1
38
+ RJ.queue_status('rspec_queue3')[:message_count].to_i.should == 1
39
+ RJ.purge_queue(:rspec_queue, :rspec_queue2, :rspec_queue3)
40
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 0
41
+ RJ.queue_status('rspec_queue2')[:message_count].to_i.should == 0
42
+ RJ.queue_status('rspec_queue3')[:message_count].to_i.should == 0
33
43
  end
34
44
 
35
45
  it 'should publish job with *params' do
36
46
  RJ.publish_to(:rspec_queue, JobWithArgsArray, 'first value', :some_symbol, 123, 'and string')
37
- RJ.purge_queue(:rspec_queue).should == 1
47
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 1
48
+ RJ.purge_queue(:rspec_queue)
49
+ RJ.queue_status('rspec_queue')[:message_count].to_i.should == 0
38
50
  end
39
51
 
40
52
  it 'should publish 1000 messages in one second' do
41
53
  count = 1000
42
- time = Benchmark.measure {
54
+ time = Benchmark.measure do
43
55
  count.times { RJ.publish_to(:rspec_queue, TestJob) }
44
- removed = RJ.purge_queue(:rspec_queue, :rspec_queue2, :rspec_queue3)
45
- removed.should == count
46
- }
56
+ to_remove = RJ.queue_status('rspec_queue')[:message_count].to_i
57
+ to_remove += RJ.queue_status('rspec_queue2')[:message_count].to_i
58
+ to_remove += RJ.queue_status('rspec_queue3')[:message_count].to_i
59
+ to_remove.should == count
60
+
61
+ RJ.purge_queue(:rspec_queue, :rspec_queue2, :rspec_queue3)
62
+
63
+ remains = RJ.queue_status('rspec_queue')[:message_count].to_i
64
+ remains += RJ.queue_status('rspec_queue2')[:message_count].to_i
65
+ remains += RJ.queue_status('rspec_queue3')[:message_count].to_i
66
+ remains.should == 0
67
+ end
47
68
  puts time
48
69
  end
49
- end
70
+ end
@@ -1,4 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
1
  require 'spec_helper'
3
2
 
4
3
  describe RabbitJobs::Scheduler do
@@ -6,10 +5,16 @@ describe RabbitJobs::Scheduler do
6
5
  scheduler = RabbitJobs::Scheduler.new
7
6
  scheduler.schedule = YAML.load_file(File.expand_path('../../fixtures/schedule.yml', __FILE__))
8
7
 
9
- scheduler.work(10) # work for 1 second
8
+ # stop scheduler after 3 seconds
9
+ Thread.start do
10
+ sleep 3
11
+ scheduler.shutdown
12
+ end
13
+ scheduler.work
10
14
 
11
15
  RJ.config.queue 'default', RJ::Configuration::DEFAULT_QUEUE_PARAMS
12
- puts "messages queued: " + RJ.purge_queue('default').to_s
13
- RJ.purge_queue('default').should == 0
16
+ puts "messages queued: #{RJ.purge_queue('default')}"
17
+ RJ.queue_status('default')[:message_count].to_i.should == 0
18
+ RJ.purge_queue('default')
14
19
  end
15
- end
20
+ end
@@ -5,7 +5,7 @@ describe RabbitJobs::Worker do
5
5
  it 'should allow to publish jobs from worker' do
6
6
  RabbitJobs.configure do |c|
7
7
  c.server 'amqp://localhost/rj'
8
- c.queue 'rspec_durable_queue', auto_delete: false, durable: true, ack: true
8
+ c.queue 'rspec_durable_queue', auto_delete: false, durable: true, manual_ack: true
9
9
  end
10
10
 
11
11
  RJ::Publisher.purge_queue('rspec_durable_queue')
@@ -13,6 +13,13 @@ describe RabbitJobs::Worker do
13
13
 
14
14
  worker = RabbitJobs::Worker.new
15
15
  # mock(RJ).publish_to(:rspec_durable_queue, JobWithPublish, 5)
16
- worker.work(3) # work for 1 second
16
+
17
+ # stop worker after 3 seconds
18
+ Thread.start do
19
+ sleep 3
20
+ worker.shutdown
21
+ end
22
+
23
+ worker.work
17
24
  end
18
- end
25
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,11 @@
1
- # -*- encoding : utf-8 -*-
2
1
  require 'simplecov'
3
2
  SimpleCov.start do
4
- add_filter "spec" # ignore spec files
3
+ add_filter 'spec' # ignore spec files
4
+ end
5
+
6
+ if ENV['CC']
7
+ require 'codeclimate-test-reporter'
8
+ CodeClimate::TestReporter.start
5
9
  end
6
10
 
7
11
  require 'rr'
@@ -27,4 +31,4 @@ RSpec.configure do |config|
27
31
  # config.formatter = :progress
28
32
  config.formatter = :html
29
33
  end
30
- end
34
+ end
@@ -1,33 +1,45 @@
1
- # -*- encoding : utf-8 -*-
2
1
  require 'spec_helper'
3
2
 
4
3
  describe RabbitJobs::Configuration do
4
+ around(:each) do |example|
5
+ old_config = RJ.instance_variable_get '@configuration'
6
+ RJ.instance_variable_set '@configuration', nil
7
+ example.run
8
+ RJ.instance_variable_set '@configuration', old_config
9
+ end
10
+
5
11
  it 'builds configuration from configure block' do
6
12
  RabbitJobs.configure do |c|
7
13
  c.disable_error_log
8
14
 
9
- c.server "amqp://somehost.lan"
15
+ c.server 'amqp://somehost.lan'
10
16
 
11
- c.queue 'durable_queue', durable: true, auto_delete: false, ack: true, arguments: {'x-ha-policy' => 'all'}
12
- c.queue 'fast_queue', durable: false, auto_delete: true, ack: false
17
+ c.queue 'durable_queue', durable: true, auto_delete: false, manual_ack: true, arguments: { 'x-ha-policy' => 'all' }
18
+ c.queue 'fast_queue', durable: false, auto_delete: true, manual_ack: false
13
19
  end
14
20
 
15
21
  RabbitJobs.config.to_hash.should == {
16
22
  error_log: false,
17
- server: "amqp://somehost.lan",
23
+ server: 'amqp://somehost.lan',
18
24
  queues: {
25
+ jobs: {
26
+ auto_delete: false,
27
+ exclusive: false,
28
+ durable: true,
29
+ manual_ack: true
30
+ },
19
31
  durable_queue: {
20
32
  auto_delete: false,
21
33
  exclusive: false,
22
34
  durable: true,
23
- ack: true,
24
- arguments: {"x-ha-policy"=>"all"}
35
+ manual_ack: true,
36
+ arguments: { 'x-ha-policy' => 'all' }
25
37
  },
26
38
  fast_queue: {
27
39
  auto_delete: true,
28
40
  exclusive: false,
29
41
  durable: false,
30
- ack: false
42
+ manual_ack: false
31
43
  }
32
44
  }
33
45
  }
@@ -37,20 +49,20 @@ describe RabbitJobs::Configuration do
37
49
  RabbitJobs.config.load_file(File.expand_path('../../fixtures/config.yml', __FILE__))
38
50
 
39
51
  RabbitJobs.config.to_hash.should == {
40
- server: "amqp://example.com/vhost",
52
+ server: 'amqp://example.com/vhost',
41
53
  queues: {
42
54
  durable_queue: {
43
55
  durable: true,
44
56
  exclusive: false,
45
57
  auto_delete: false,
46
- ack: true,
47
- arguments: {"x-ha-policy"=>"all"}
58
+ manual_ack: true,
59
+ arguments: { 'x-ha-policy' => 'all' }
48
60
  },
49
61
  fast_queue: {
50
62
  durable: false,
51
63
  exclusive: false,
52
64
  auto_delete: true,
53
- ack: false
65
+ manual_ack: false
54
66
  }
55
67
  }
56
68
  }
@@ -59,14 +71,21 @@ describe RabbitJobs::Configuration do
59
71
  it 'use default value for #server' do
60
72
  RabbitJobs.config.to_hash.should == {
61
73
  error_log: true,
62
- server: "amqp://localhost",
63
- queues: {}
74
+ server: 'amqp://localhost',
75
+ queues: {
76
+ jobs: {
77
+ auto_delete: false,
78
+ exclusive: false,
79
+ durable: true,
80
+ manual_ack: true
81
+ }
82
+ }
64
83
  }
65
84
  end
66
85
 
67
86
  it 'returns settings on some methods' do
68
- RabbitJobs.config.error_log == true
69
- RabbitJobs.config.server.should == 'amqp://localhost'
70
- RabbitJobs.config.routing_keys.should == []
87
+ RabbitJobs.config.error_log.should eq true
88
+ RabbitJobs.config.server.should eq 'amqp://localhost'
89
+ RabbitJobs.config.routing_keys.should eq [:jobs]
71
90
  end
72
- end
91
+ end