rabbit_jobs 0.0.1 → 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/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .DS_Store
6
7
  Gemfile.lock
7
8
  InstalledFiles
8
9
  _yardoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format documentation
data/Gemfile CHANGED
@@ -1,4 +1,13 @@
1
- source 'https://rubygems.org'
1
+ source :rubygems
2
2
 
3
- # Specify your gem's dependencies in rabbit_jobs.gemspec
4
3
  gemspec
4
+
5
+ gem 'rabbit_jobs', :path => './'
6
+
7
+ group :development do
8
+ gem 'rspec', '~> 2.8'
9
+ gem 'rr'
10
+ gem 'autotest'
11
+ # gem 'fs-event'
12
+ gem 'simplecov', require: false
13
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'bundler/setup'
3
+ require 'rabbit_jobs'
4
+ require 'json'
5
+
6
+ RabbitJobs.configure do |c|
7
+ c.host "127.0.0.1"
8
+
9
+ c.exchange 'test_exchange', durable: true, auto_delete: false
10
+
11
+ c.queue 'rabbit_jobs_test1', durable: true, auto_delete: false, ack: true, arguments: {'x-ha-policy' => 'all'}
12
+ c.queue 'rabbit_jobs_test2', durable: true, auto_delete: false, ack: true, arguments: {'x-ha-policy' => 'all'}
13
+ c.queue 'rabbit_jobs_test3', durable: true, auto_delete: false, ack: true, arguments: {'x-ha-policy' => 'all'}
14
+ end
15
+
16
+ puts JSON.pretty_generate(RabbitJobs.config.to_hash)
17
+
18
+ puts JSON.pretty_generate(RabbitJobs.config.queues)
19
+
20
+ # 10.times {
21
+ RabbitJobs.enqueue_to('rabbit_jobs_test1', Integer, 'to_s')
22
+ # }
@@ -0,0 +1,45 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module RabbitJobs
4
+ module AmqpHelpers
5
+
6
+ # Calls given block with initialized amqp
7
+
8
+ def amqp_with_exchange(&block)
9
+ raise ArgumentError unless block
10
+
11
+ AMQP.start(host: RabbitJobs.config.host) do |connection|
12
+ channel = AMQP::Channel.new(connection)
13
+
14
+ channel.on_error do |ch, channel_close|
15
+ puts "Channel-level error: #{channel_close.reply_text}, shutting down..."
16
+ connection.close { EM.stop }
17
+ end
18
+
19
+ exchange = channel.direct(RabbitJobs.config[:exchange], RabbitJobs.config[:exchange_params])
20
+
21
+ # go work
22
+ block.call(connection, exchange)
23
+ end
24
+ end
25
+
26
+ def amqp_with_queue(routing_key, &block)
27
+
28
+ raise ArgumentError unless routing_key && block
29
+
30
+ amqp_with_exchange do |connection, exchange|
31
+ queue = exchange.channel.queue(RabbitJobs.config.queue_name(routing_key), RabbitJobs.config[:queues][routing_key])
32
+ queue.bind(exchange, :routing_key => routing_key)
33
+
34
+ # go work
35
+ block.call(connection, queue)
36
+ end
37
+ end
38
+
39
+ def make_queue(exchange, routing_key)
40
+ queue = exchange.channel.queue(RabbitJobs.config.queue_name(routing_key), RabbitJobs.config[:queues][routing_key])
41
+ queue.bind(exchange, :routing_key => routing_key)
42
+ queue
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,122 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'yaml'
3
+
4
+ module RabbitJobs
5
+
6
+ extend self
7
+
8
+ def configure(&block)
9
+ @@configuration ||= Configuration.new
10
+ block.call(@@configuration)
11
+ end
12
+
13
+ def config
14
+ @@configuration ||= load_config
15
+ end
16
+
17
+ def load_config
18
+ self.configure do |c|
19
+ c.host 'localhost'
20
+ c.exchange 'rabbit_jobs', auto_delete: false, durable: true
21
+ c.queue 'default', auto_delete: false, ack: true, durable: true
22
+ end
23
+ @@configuration
24
+ end
25
+
26
+ class Configuration
27
+ include Helpers
28
+
29
+ DEFAULT_QUEUE_PARAMS = {
30
+ auto_delete: false,
31
+ durable: true,
32
+ ack: true
33
+ }
34
+
35
+ DEFAULT_EXCHANGE_PARAMS = {
36
+ auto_delete: false,
37
+ durable: true
38
+ }
39
+
40
+ DEFAULT_MESSAGE_PARAMS = {
41
+ persistent: true,
42
+ nowait: false,
43
+ immediate: false
44
+ }
45
+
46
+ def to_hash
47
+ @data.dup
48
+ end
49
+
50
+ def initialize
51
+ @data = {
52
+ host: 'localhost',
53
+ exchange: 'rabbit_jobs',
54
+ exchange_params: DEFAULT_EXCHANGE_PARAMS,
55
+ queues: {}
56
+ }
57
+ end
58
+
59
+ def [](name)
60
+ @data[name]
61
+ end
62
+
63
+ def host(value = nil)
64
+ if value
65
+ raise ArgumentError unless value.is_a?(String) && value != ""
66
+ @data[:host] = value.to_s
67
+ else
68
+ @data[:host]
69
+ end
70
+ end
71
+
72
+ def exchange(value = nil, params = {})
73
+ if value
74
+ raise ArgumentError unless value.is_a?(String) && value != ""
75
+ @data[:exchange] = value
76
+ @data[:exchange_params] = DEFAULT_EXCHANGE_PARAMS.merge(params)
77
+ else
78
+ @data[:exchange]
79
+ end
80
+ end
81
+
82
+ def queue(name, params = {})
83
+ raise ArgumentError.new("name is #{name.inspect}") unless name && name.is_a?(String) && name != ""
84
+ raise ArgumentError.new("params is #{params.inspect}") unless params && params.is_a?(Hash)
85
+
86
+ if @data[:queues][name]
87
+ @data[:queues][name].merge!(params)
88
+ else
89
+ @data[:queues][name] = DEFAULT_QUEUE_PARAMS.merge(params)
90
+ end
91
+ end
92
+
93
+ def routing_keys
94
+ @data[:queues].keys
95
+ end
96
+
97
+ def queue_name(routing_key)
98
+ [@data[:exchange], routing_key].join('#')
99
+ end
100
+
101
+ def load_file(filename)
102
+ load_yaml(File.read(filename))
103
+ end
104
+
105
+ def load_yaml(text)
106
+ convert_yaml_config(YAML.load(text))
107
+ end
108
+
109
+ def convert_yaml_config(yaml)
110
+ if yaml['rabbit_jobs']
111
+ convert_yaml_config(yaml['rabbit_jobs'])
112
+ else
113
+ @data = {host: nil, exchange: nil, queues: {}}
114
+ host yaml['host']
115
+ exchange yaml['exchange'], symbolize_keys!(yaml['exchange_params'])
116
+ yaml['queues'].each do |name, params|
117
+ queue name, symbolize_keys!(params) || {}
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,53 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module RabbitJobs
4
+ module Helpers
5
+ def symbolize_keys!(hash)
6
+ hash.inject({}) do |options, (key, value)|
7
+ options[(key.to_sym rescue key) || key] = value
8
+ options
9
+ end
10
+ end
11
+
12
+
13
+ # Tries to find a constant with the name specified in the argument string:
14
+ #
15
+ # constantize("Module") # => Module
16
+ # constantize("Test::Unit") # => Test::Unit
17
+ #
18
+ # The name is assumed to be the one of a top-level constant, no matter
19
+ # whether it starts with "::" or not. No lexical context is taken into
20
+ # account:
21
+ #
22
+ # C = 'outside'
23
+ # module M
24
+ # C = 'inside'
25
+ # C # => 'inside'
26
+ # constantize("C") # => 'outside', same as ::C
27
+ # end
28
+ #
29
+ # NameError is raised when the constant is unknown.
30
+ def constantize(camel_cased_word)
31
+ camel_cased_word = camel_cased_word.to_s
32
+
33
+ if camel_cased_word.include?('-')
34
+ camel_cased_word = classify(camel_cased_word)
35
+ end
36
+
37
+ names = camel_cased_word.split('::')
38
+ names.shift if names.empty? || names.first.empty?
39
+
40
+ constant = Object
41
+ names.each do |name|
42
+ args = Module.method(:const_get).arity != 1 ? [false] : []
43
+
44
+ if constant.const_defined?(name, *args)
45
+ constant = constant.const_get(name)
46
+ else
47
+ constant = constant.const_missing(name)
48
+ end
49
+ end
50
+ constant
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,43 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'json'
3
+
4
+ module RabbitJobs
5
+ class Job
6
+ include RabbitJobs::Helpers
7
+ include Logger
8
+
9
+ attr_accessor :params, :klass, :child
10
+
11
+ def initialize(payload)
12
+ begin
13
+ self.params = JSON.parse(payload)
14
+ klass_name = params.delete_at(0)
15
+ self.klass = constantize(klass_name)
16
+ rescue
17
+ log "JOB INIT ERROR at #{Time.now.to_s}:"
18
+ log $!.inspect
19
+ log $!.backtrace
20
+ log "message: #{payload.inspect}"
21
+ # Mailer.send(klass_name, params, $!)
22
+ end
23
+ end
24
+
25
+ def perform
26
+ if @child = fork
27
+ srand # Reseeding
28
+ log! "Forked #{@child} at #{Time.now} to process #{klass}.perform(#{ params.map(&:inspect).join(', ') })"
29
+ Process.wait(@child)
30
+ yield if block_given?
31
+ else
32
+ begin
33
+ # log 'before perform'
34
+ klass.perform(*params)
35
+ # log 'after perform'
36
+ rescue
37
+ puts $!.inspect
38
+ end
39
+ exit!
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ module RabbitJobs
2
+ module Logger
3
+ extend self
4
+
5
+ def log(string)
6
+ puts string
7
+ end
8
+
9
+ def log!(string)
10
+ @@verbose ||= false
11
+ log(string) if RabbitJobs::Logger.verbose
12
+ end
13
+
14
+ class << self
15
+ attr_accessor :verbose
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,58 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require 'json'
4
+ require 'amqp'
5
+ require 'eventmachine'
6
+
7
+ module RabbitJobs
8
+ module Publisher
9
+ extend self
10
+ extend AmqpHelpers
11
+
12
+ def enqueue(klass, *params)
13
+ key = RabbitJobs.config.routing_keys.first
14
+ enqueue_to(key, klass, *params)
15
+ end
16
+
17
+ def enqueue_to(routing_key, klass, *params)
18
+ raise ArgumentError unless klass && routing_key
19
+
20
+ payload = ([klass.to_s] + params).to_json
21
+
22
+ amqp_with_exchange do |connection, exchange|
23
+
24
+ queue = make_queue(exchange, routing_key)
25
+
26
+ exchange.publish(payload, Configuration::DEFAULT_MESSAGE_PARAMS.merge({routing_key: routing_key})) {
27
+ connection.close { EM.stop }
28
+ }
29
+ end
30
+ end
31
+
32
+ # def spam
33
+ # payload = ([klass.to_s] + params).to_json
34
+
35
+ # amqp_with_exchange do |connection, exchange|
36
+ # 10000.times { |i| RabbitJobs.enqueue(RabbitJobs::TestJob, i) }
37
+ # exchange.publish(payload, RabbitJobs.config.publish_params.merge({routing_key: routing_key})) {
38
+ # connection.close { EM.stop }
39
+ # }
40
+ # end
41
+ # end
42
+
43
+ def purge_queue(routing_key)
44
+ raise ArgumentError unless routing_key
45
+
46
+ amqp_with_queue(routing_key) do |connection, queue|
47
+ queue.status do |number_of_messages, number_of_consumers|
48
+ queue.purge {
49
+ connection.close {
50
+ EM.stop
51
+ return number_of_messages
52
+ }
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,57 @@
1
+ # require 'resque/tasks'
2
+ # will give you the resque tasks
3
+
4
+ namespace :rj do
5
+ task :setup
6
+
7
+ desc "Start a Rabbit Jobs worker"
8
+ task :work => [ :preload, :setup ] do
9
+ require 'rabbit_jobs'
10
+
11
+ queues = (ENV['QUEUES'] || ENV['QUEUE']).to_s.split(',')
12
+
13
+ begin
14
+ worker = RabbitJobs::Worker.new(*queues)
15
+ RabbitJobs::Logger.verbose = true if ENV['VERBOSE']
16
+ # worker.very_verbose = ENV['VVERBOSE']
17
+ end
18
+
19
+ if ENV['BACKGROUND']
20
+ Process.daemon(true)
21
+ end
22
+
23
+ if ENV['PIDFILE']
24
+ File.open(ENV['PIDFILE'], 'w') { |f| f << worker.pid }
25
+ end
26
+
27
+ # worker.log "Starting worker #{worker.pid}"
28
+ # worker.verbose = true
29
+ worker.work 1
30
+ # worker.work(ENV['INTERVAL'] || 5) # interval, will block
31
+ end
32
+
33
+ desc "Start multiple Resque workers. Should only be used in dev mode."
34
+ task :workers do
35
+ threads = []
36
+
37
+ ENV['COUNT'].to_i.times do
38
+ threads << Thread.new do
39
+ system "rake resque:work"
40
+ end
41
+ end
42
+
43
+ threads.each { |thread| thread.join }
44
+ end
45
+
46
+ # Preload app files if this is Rails
47
+ task :preload => :setup do
48
+ if defined?(Rails) && Rails.respond_to?(:application)
49
+ # Rails 3
50
+ Rails.application.eager_load!
51
+ elsif defined?(Rails::Initializer)
52
+ # Rails 2.3
53
+ $rails_rake_task = false
54
+ Rails::Initializer.run :load_application_classes
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module RabbitJobs
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,104 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module RabbitJobs
4
+ class Worker
5
+ include AmqpHelpers
6
+ include Logger
7
+
8
+ # Workers should be initialized with an array of string queue
9
+ # names. The order is important: a Worker will check the first
10
+ # queue given for a job. If none is found, it will check the
11
+ # second queue name given. If a job is found, it will be
12
+ # processed. Upon completion, the Worker will again check the
13
+ # first queue given, and so forth. In this way the queue list
14
+ # passed to a Worker on startup defines the priorities of queues.
15
+ #
16
+ # If passed a single "*", this Worker will operate on all queues
17
+ # in alphabetical order. Queues can be dynamically added or
18
+ # removed without needing to restart workers using this method.
19
+ def initialize(*queues)
20
+ @queues = queues.map { |queue| queue.to_s.strip }.flatten.uniq
21
+ if @queues == ['*'] || @queues.empty?
22
+ @queues = RabbitJobs.config.routing_keys
23
+ end
24
+ end
25
+
26
+ def queues
27
+ @queues || ['default']
28
+ end
29
+
30
+ # Subscribes to channel and working on jobs
31
+ def work(time = 10)
32
+ startup
33
+
34
+ processed_count = 0
35
+ amqp_with_exchange do |connection, exchange|
36
+ exchange.channel.prefetch(1)
37
+
38
+ check_shutdown = Proc.new {
39
+ if @shutdown
40
+ log "Processed jobs: #{processed_count}"
41
+ log "Stopping worker..."
42
+ connection.close { EM.stop { exit! } }
43
+ end
44
+ }
45
+
46
+ queues.each do |routing_key|
47
+ queue = make_queue(exchange, routing_key)
48
+
49
+ log "Worker ##{Process.pid} <= #{exchange.name}##{routing_key}"
50
+
51
+ queue.subscribe(ack: true) do |metadata, payload|
52
+ @job = Job.new(payload)
53
+ @job.perform
54
+ metadata.ack
55
+ processed_count += 1
56
+ check_shutdown.call
57
+ end
58
+ end
59
+
60
+ EM.add_timer(time) do
61
+ self.shutdown
62
+ end
63
+
64
+ EM.add_periodic_timer(1) do
65
+ check_shutdown.call
66
+ end
67
+ end
68
+ end
69
+
70
+ def shutdown
71
+ @shutdown = true
72
+ end
73
+
74
+ def startup
75
+ # prune_dead_workers
76
+
77
+ # Fix buffering so we can `rake rj:work > resque.log` and
78
+ # get output from the child in there.
79
+ $stdout.sync = true
80
+
81
+ @shutdown = false
82
+
83
+ Signal.trap('TERM') { shutdown }
84
+ Signal.trap('INT') { shutdown! }
85
+ end
86
+
87
+ def shutdown!
88
+ shutdown
89
+ kill_child
90
+ end
91
+
92
+ def kill_child
93
+ if @job && @job.child
94
+ # log! "Killing child at #{@child}"
95
+ if Kernel.system("ps -o pid,state -p #{@job.child}")
96
+ Process.kill("KILL", @job.child) rescue nil
97
+ else
98
+ # log! "Child #{@child} not found, restarting."
99
+ # shutdown
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
data/lib/rabbit_jobs.rb CHANGED
@@ -1,5 +1,36 @@
1
- require "rabbit_jobs/version"
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require 'rabbit_jobs/version'
4
+
5
+ require 'rabbit_jobs/helpers'
6
+ require 'rabbit_jobs/amqp_helpers'
7
+ require 'rabbit_jobs/configuration'
8
+ require 'rabbit_jobs/logger'
9
+
10
+ require 'rabbit_jobs/job'
11
+ require 'rabbit_jobs/publisher'
12
+ require 'rabbit_jobs/worker'
2
13
 
3
14
  module RabbitJobs
4
- # Your code goes here...
5
- end
15
+ extend self
16
+
17
+ def enqueue(klass, *params)
18
+ RabbitJobs::Publisher.enqueue(klass, *params)
19
+ end
20
+
21
+ def enqueue_to(routing_key, klass, *params)
22
+ RabbitJobs::Publisher.enqueue_to(routing_key, klass, *params)
23
+ end
24
+
25
+ class TestJob < RabbitJobs::Job
26
+ def self.perform(*params)
27
+ # puts "processing in job: " + params.inspect
28
+ # sleep 0.1
29
+
30
+ # if rand(3) == 0
31
+ # puts "ERROR TEXT"
32
+ # raise "ERROR TEXT"
33
+ # end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
3
+ require 'rabbit_jobs/tasks'
data/rabbit_jobs.gemspec CHANGED
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/rabbit_jobs/version', __FILE__)
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'rabbit_jobs/version'
3
4
 
4
5
  Gem::Specification.new do |gem|
5
6
  gem.authors = ["Pavel Lazureykis"]
@@ -7,6 +8,7 @@ Gem::Specification.new do |gem|
7
8
  gem.description = %q{Background jobs on RabbitMQ}
8
9
  gem.summary = %q{Background jobs on RabbitMQ}
9
10
  gem.homepage = ""
11
+ gem.date = Time.now.strftime('%Y-%m-%d')
10
12
 
11
13
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
14
  gem.files = `git ls-files`.split("\n")
@@ -15,7 +17,5 @@ Gem::Specification.new do |gem|
15
17
  gem.require_paths = ["lib"]
16
18
  gem.version = RabbitJobs::VERSION
17
19
 
18
- gem.add_development_dependency "rspec", "~> 2.8"
19
-
20
20
  gem.add_dependency "amqp", "~> 0.9"
21
21
  end
@@ -0,0 +1,17 @@
1
+ rabbit_jobs:
2
+ host: example.com
3
+ exchange: 'my_exchange'
4
+ exchange_params:
5
+ durable: true
6
+ auto_delete: false
7
+ queues:
8
+ durable_queue:
9
+ durable: true
10
+ auto_delete: false
11
+ ack: true
12
+ arguments:
13
+ x-ha-policy: all
14
+ fast_queue:
15
+ durable: false
16
+ auto_delete: true
17
+ ack: false
@@ -0,0 +1,17 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'json'
4
+
5
+ describe RabbitJobs::Publisher do
6
+ it 'should publish message to queue' do
7
+
8
+ RabbitJobs.configure do |c|
9
+ # c.host "somehost.lan"
10
+ c.exchange 'test', auto_delete: true
11
+ c.queue 'rspec_queue', auto_delete: true
12
+ end
13
+
14
+ RabbitJobs.enqueue(Integer, 'some', 'other', 'params')
15
+ RabbitJobs::Publisher.purge_queue('rspec_queue').should == 1
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'simplecov'
3
+ SimpleCov.start {
4
+ add_filter "spec" # ignore gems
5
+ }
6
+
7
+ require 'rr'
8
+
9
+ require 'rabbit_jobs'
10
+
11
+ RSpec.configure do |config|
12
+ config.mock_with :rr
13
+ # or if that doesn't work due to a version incompatibility
14
+ # config.mock_with RR::Adapters::Rspec
15
+
16
+ config.before(:each) do
17
+ # clear config options
18
+ RabbitJobs.class_variable_set '@@configuration', nil
19
+ end
20
+ end
@@ -0,0 +1,89 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe RabbitJobs::Configuration do
5
+ it 'builds configuration from configure block' do
6
+ RabbitJobs.configure do |c|
7
+ c.host "somehost.lan"
8
+
9
+ c.exchange 'my_exchange', durable: true, auto_delete: false
10
+
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
13
+ end
14
+
15
+ RabbitJobs.config.to_hash.should == {
16
+ host: "somehost.lan",
17
+ exchange: "my_exchange",
18
+ exchange_params: {
19
+ durable: true,
20
+ auto_delete: false
21
+ },
22
+ queues: {
23
+ "durable_queue" => {
24
+ durable: true,
25
+ auto_delete: false,
26
+ ack: true,
27
+ arguments: {"x-ha-policy"=>"all"}
28
+ },
29
+ "fast_queue" => {
30
+ durable: false,
31
+ auto_delete: true,
32
+ ack: false
33
+ },
34
+ }
35
+ }
36
+ end
37
+
38
+ it 'builds configuration from yaml' do
39
+ RabbitJobs.config.load_file(File.expand_path('../../fixtures/config.yml', __FILE__))
40
+
41
+ RabbitJobs.config.to_hash.should == {
42
+ host: "example.com",
43
+ exchange: "my_exchange",
44
+ exchange_params: {
45
+ durable: true,
46
+ auto_delete: false
47
+ },
48
+ queues: {
49
+ "durable_queue" => {
50
+ durable: true,
51
+ auto_delete: false,
52
+ ack: true,
53
+ arguments: {"x-ha-policy"=>"all"}
54
+ },
55
+ "fast_queue" => {
56
+ durable: false,
57
+ auto_delete: true,
58
+ ack: false
59
+ }
60
+ }
61
+ }
62
+ end
63
+
64
+ it 'use default config' do
65
+ RabbitJobs.config.to_hash.should == {
66
+ host: "localhost",
67
+ exchange: "rabbit_jobs",
68
+ exchange_params: {
69
+ auto_delete: false,
70
+ durable: true
71
+ },
72
+ queues: {
73
+ "default" => {
74
+ auto_delete: false,
75
+ ack: true,
76
+ durable: true
77
+ }
78
+ }
79
+ }
80
+ end
81
+
82
+ it 'returns settings on some methods' do
83
+ RabbitJobs.config.host.should == 'localhost'
84
+ RabbitJobs.config[:host].should == 'localhost'
85
+ RabbitJobs.config.routing_keys.should == ['default']
86
+ RabbitJobs.config.exchange.should == 'rabbit_jobs'
87
+ RabbitJobs.config.queue_name('default').should == 'rabbit_jobs#default'
88
+ end
89
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe RabbitJobs::Logger do
5
+ it '#log should write messages to stdout' do
6
+ mock($stdout).puts "hello"
7
+ RabbitJobs::Logger.log("hello")
8
+ end
9
+
10
+ it '#log! should not write messages to stdout in normal mode' do
11
+ RabbitJobs::Logger.verbose = false
12
+
13
+ dont_allow(RabbitJobs::Logger).log("hello")
14
+ RabbitJobs::Logger.log!("hello")
15
+ end
16
+
17
+ it '#log! should write messages to stdout in verbose mode' do
18
+ RabbitJobs::Logger.verbose = true
19
+
20
+ mock(RabbitJobs::Logger).log("hello")
21
+ RabbitJobs::Logger.log!("hello")
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ describe RabbitJobs do
4
+ it 'should pass enqueue methods to publisher' do
5
+ mock(RabbitJobs::Publisher).enqueue(Integer, 1, 2, "string")
6
+ RabbitJobs.enqueue(Integer, 1, 2, "string")
7
+
8
+ mock(RabbitJobs::Publisher).enqueue_to('default_queue', Integer, 1, 2, "string")
9
+ RabbitJobs.enqueue_to('default_queue', Integer, 1, 2, "string")
10
+ end
11
+ end
@@ -0,0 +1,49 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe RabbitJobs::Worker do
5
+ describe 'methods' do
6
+ before :each do
7
+ @worker = RabbitJobs::Worker.new
8
+ end
9
+
10
+ it '#initialize with default options' do
11
+ @worker.queues.should == ['default']
12
+ end
13
+
14
+ it '#startup' do
15
+ @worker.instance_variable_get('@shutdown').should_not == true
16
+
17
+ mock(Signal).trap('TERM')
18
+ mock(Signal).trap('INT')
19
+
20
+ @worker.startup
21
+
22
+ @worker.instance_variable_get('@shutdown').should_not == true
23
+ end
24
+
25
+ it '#shutdown should set @shutdown to true' do
26
+ @worker.instance_variable_get('@shutdown').should_not == true
27
+ @worker.shutdown
28
+ @worker.instance_variable_get('@shutdown').should == true
29
+ end
30
+
31
+ it '#shutdown! should kill child process' do
32
+ mock(@worker.kill_child)
33
+ mock(@worker.shutdown)
34
+
35
+ @worker.shutdown!
36
+ end
37
+
38
+ it '#kill_child' do
39
+ job = RabbitJobs::Job.new(['RabbitJobs'].to_json)
40
+ job.instance_variable_set '@child', 123123
41
+ @worker.instance_variable_set('@job', job)
42
+
43
+ mock(Kernel).system("ps -o pid,state -p #{123123}") { true }
44
+ mock(Process).kill("KILL", 123123)
45
+
46
+ @worker.kill_child
47
+ end
48
+ end
49
+ 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.1
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-24 00:00:00.000000000 Z
12
+ date: 2012-01-27 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rspec
16
- requirement: &70100539559980 !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: '2.8'
22
- type: :development
23
- prerelease: false
24
- version_requirements: *70100539559980
25
14
  - !ruby/object:Gem::Dependency
26
15
  name: amqp
27
- requirement: &70100539559360 !ruby/object:Gem::Requirement
16
+ requirement: &70147046160300 !ruby/object:Gem::Requirement
28
17
  none: false
29
18
  requirements:
30
19
  - - ~>
@@ -32,7 +21,7 @@ dependencies:
32
21
  version: '0.9'
33
22
  type: :runtime
34
23
  prerelease: false
35
- version_requirements: *70100539559360
24
+ version_requirements: *70147046160300
36
25
  description: Background jobs on RabbitMQ
37
26
  email:
38
27
  - lazureykis@gmail.com
@@ -41,13 +30,31 @@ extensions: []
41
30
  extra_rdoc_files: []
42
31
  files:
43
32
  - .gitignore
33
+ - .rspec
44
34
  - Gemfile
45
35
  - LICENSE
46
36
  - README.md
47
37
  - Rakefile
38
+ - examples/configuration.rb
48
39
  - lib/rabbit_jobs.rb
40
+ - lib/rabbit_jobs/amqp_helpers.rb
41
+ - lib/rabbit_jobs/configuration.rb
42
+ - lib/rabbit_jobs/helpers.rb
43
+ - lib/rabbit_jobs/job.rb
44
+ - lib/rabbit_jobs/logger.rb
45
+ - lib/rabbit_jobs/publisher.rb
46
+ - lib/rabbit_jobs/tasks.rb
49
47
  - lib/rabbit_jobs/version.rb
48
+ - lib/rabbit_jobs/worker.rb
49
+ - lib/tasks/rabbit_jobs.rake
50
50
  - rabbit_jobs.gemspec
51
+ - spec/fixtures/config.yml
52
+ - spec/integration/publisher_spec.rb
53
+ - spec/spec_helper.rb
54
+ - spec/unit/configuration_spec.rb
55
+ - spec/unit/logger_spec.rb
56
+ - spec/unit/rabbit_jobs_spec.rb
57
+ - spec/unit/worker_spec.rb
51
58
  homepage: ''
52
59
  licenses: []
53
60
  post_install_message:
@@ -72,4 +79,11 @@ rubygems_version: 1.8.15
72
79
  signing_key:
73
80
  specification_version: 3
74
81
  summary: Background jobs on RabbitMQ
75
- test_files: []
82
+ test_files:
83
+ - spec/fixtures/config.yml
84
+ - spec/integration/publisher_spec.rb
85
+ - spec/spec_helper.rb
86
+ - spec/unit/configuration_spec.rb
87
+ - spec/unit/logger_spec.rb
88
+ - spec/unit/rabbit_jobs_spec.rb
89
+ - spec/unit/worker_spec.rb