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.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/build +2 -6
- data/examples/client +1 -2
- data/examples/configuration.rb +3 -3
- data/examples/worker +1 -1
- data/lib/rabbit_jobs.rb +52 -42
- data/lib/rabbit_jobs/amqp_transport.rb +33 -0
- data/lib/rabbit_jobs/configuration.rb +15 -51
- data/lib/rabbit_jobs/consumer/job_consumer.rb +7 -17
- data/lib/rabbit_jobs/job.rb +102 -127
- data/lib/rabbit_jobs/main_loop.rb +25 -24
- data/lib/rabbit_jobs/publisher.rb +19 -17
- data/lib/rabbit_jobs/publisher/amqp.rb +37 -40
- data/lib/rabbit_jobs/publisher/base.rb +26 -8
- data/lib/rabbit_jobs/publisher/sync.rb +11 -4
- data/lib/rabbit_jobs/publisher/test.rb +10 -9
- data/lib/rabbit_jobs/scheduler.rb +25 -39
- data/lib/rabbit_jobs/tasks.rb +8 -8
- data/lib/rabbit_jobs/version.rb +1 -3
- data/lib/rabbit_jobs/worker.rb +26 -45
- data/lib/tasks/rabbit_jobs.rake +1 -1
- data/rabbit_jobs.gemspec +20 -19
- data/spec/fixtures/config.yml +2 -2
- data/spec/fixtures/jobs.rb +1 -3
- data/spec/integration/publisher_spec.rb +30 -9
- data/spec/integration/scheduler_spec.rb +10 -5
- data/spec/integration/worker_spec.rb +10 -3
- data/spec/spec_helper.rb +7 -3
- data/spec/unit/configuration_spec.rb +37 -18
- data/spec/unit/job_consumer_spec.rb +11 -10
- data/spec/unit/job_spec.rb +12 -14
- data/spec/unit/rabbit_jobs_spec.rb +5 -6
- data/spec/unit/worker_spec.rb +6 -7
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41fb778c890aee7f7a0d1a7c7912abbbf58cb1eb
|
4
|
+
data.tar.gz: dbb37f7b51818faa4a1855a16cf2ecdea843d92f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42debf0e98af814b76c6b00782645f771e9cc9fb1de85199521ec7b315305745a4023fec0bcf7ff66a14ff21145d9d9656f2e30a2d39d0b67511bccdfa5dcb58
|
7
|
+
data.tar.gz: 4a8a03c5fbfccfcf31f71ae0668cec20f2ae61a6ac12e8d5d43cf372e959d3bbbebe236cdfb7dc4e029b03d8d31288172acf12bbb055c650840b544fb2b7e184
|
data/Rakefile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
data/build
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
require 'fileutils'
|
4
3
|
|
5
|
-
abort(
|
6
|
-
abort(
|
7
|
-
|
8
|
-
coverage_dir = File.expand_path('../coverage', __FILE__)
|
9
|
-
FileUtils.move(coverage_dir, ENV['CC_BUILD_ARTIFACTS']) if ENV['CC_BUILD_ARTIFACTS']
|
4
|
+
abort('bundle install failed') unless system('bundle install')
|
5
|
+
abort('rspec tests failed.') unless system('bundle exec rspec')
|
data/examples/client
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# -*- encoding : utf-8 -*-
|
3
2
|
|
4
3
|
require 'bundler'
|
5
4
|
Bundler.setup
|
@@ -13,7 +12,7 @@ class MyCurrentJob
|
|
13
12
|
end
|
14
13
|
|
15
14
|
RJ.configure { |c|
|
16
|
-
c.queue "mandarin", durable: true, auto_delete: false,
|
15
|
+
c.queue "mandarin", durable: true, auto_delete: false, manual_ack: true, arguments: {'x-ha-policy' => 'all'}
|
17
16
|
c.server "amqp://localhost/rj"
|
18
17
|
}
|
19
18
|
|
data/examples/configuration.rb
CHANGED
@@ -6,9 +6,9 @@ require 'json'
|
|
6
6
|
RabbitJobs.configure do |c|
|
7
7
|
c.server "amqp://localhost/"
|
8
8
|
|
9
|
-
c.queue 'rabbit_jobs_test1', durable: true, auto_delete: false,
|
10
|
-
c.queue 'rabbit_jobs_test2', durable: true, auto_delete: false,
|
11
|
-
c.queue 'rabbit_jobs_test3', durable: true, auto_delete: false,
|
9
|
+
c.queue 'rabbit_jobs_test1', durable: true, auto_delete: false, manual_ack: true, arguments: {'x-ha-policy' => 'all'}
|
10
|
+
c.queue 'rabbit_jobs_test2', durable: true, auto_delete: false, manual_ack: true, arguments: {'x-ha-policy' => 'all'}
|
11
|
+
c.queue 'rabbit_jobs_test3', durable: true, auto_delete: false, manual_ack: true, arguments: {'x-ha-policy' => 'all'}
|
12
12
|
end
|
13
13
|
|
14
14
|
puts JSON.pretty_generate(RabbitJobs.config.to_hash)
|
data/examples/worker
CHANGED
@@ -14,7 +14,7 @@ class MyCurrentJob
|
|
14
14
|
end
|
15
15
|
|
16
16
|
RJ.configure { |c|
|
17
|
-
c.queue "mandarin", durable: true, auto_delete: false,
|
17
|
+
c.queue "mandarin", durable: true, auto_delete: false, manual_ack: true, arguments: {'x-ha-policy' => 'all'}
|
18
18
|
c.server "amqp://localhost/rj"
|
19
19
|
}
|
20
20
|
|
data/lib/rabbit_jobs.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
require 'logger'
|
3
2
|
require 'json'
|
4
3
|
require 'bunny'
|
@@ -11,6 +10,7 @@ require 'active_support/core_ext/module/delegation'
|
|
11
10
|
|
12
11
|
require 'rabbit_jobs/version'
|
13
12
|
require 'rabbit_jobs/configuration'
|
13
|
+
require 'rabbit_jobs/amqp_transport'
|
14
14
|
require 'rabbit_jobs/consumer/job_consumer'
|
15
15
|
require 'rabbit_jobs/job'
|
16
16
|
require 'rabbit_jobs/publisher'
|
@@ -19,57 +19,67 @@ require 'rabbit_jobs/worker'
|
|
19
19
|
require 'rabbit_jobs/scheduler'
|
20
20
|
require 'rabbit_jobs/tasks'
|
21
21
|
|
22
|
+
# Public gem API.
|
22
23
|
module RabbitJobs
|
23
|
-
|
24
|
+
class << self
|
25
|
+
delegate :publish_to, :direct_publish_to, :purge_queue, :queue_status, to: Publisher
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
attr_writer :logger
|
28
|
+
def logger
|
29
|
+
unless @logger
|
30
|
+
@logger = Logger.new($stdout)
|
31
|
+
@logger.level = Logger::INFO
|
32
|
+
@logger.formatter = nil
|
33
|
+
@logger.progname = 'rj'
|
34
|
+
end
|
35
|
+
@logger
|
36
|
+
end
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
|
38
|
+
def before_process_message(&block)
|
39
|
+
fail unless block_given?
|
40
|
+
@before_process_message_callbacks ||= []
|
41
|
+
@before_process_message_callbacks << block
|
42
|
+
end
|
32
43
|
|
33
|
-
|
34
|
-
|
35
|
-
|
44
|
+
def run_before_process_message_callbacks
|
45
|
+
@before_process_message_callbacks ||= []
|
46
|
+
@before_process_message_callbacks.each do |callback|
|
47
|
+
return false unless callback.call
|
48
|
+
end
|
49
|
+
true
|
50
|
+
rescue
|
51
|
+
false
|
52
|
+
end
|
36
53
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@
|
41
|
-
@logger.level = Logger::INFO
|
42
|
-
@logger.formatter = nil
|
43
|
-
@logger.progname = 'rj'
|
54
|
+
# Configuration
|
55
|
+
def configure
|
56
|
+
@configuration ||= Configuration.new
|
57
|
+
yield @configuration if block_given?
|
44
58
|
end
|
45
|
-
@logger
|
46
|
-
end
|
47
59
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@_after_fork_callbacks << block
|
52
|
-
end
|
60
|
+
def config
|
61
|
+
@configuration ||= load_config
|
62
|
+
end
|
53
63
|
|
54
|
-
|
55
|
-
|
56
|
-
@_after_fork_callbacks.each { |callback|
|
57
|
-
callback.call
|
58
|
-
}
|
59
|
-
end
|
64
|
+
def load_config(config_file = nil)
|
65
|
+
@configuration ||= nil
|
60
66
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
config_file ||= defined?(Rails) && Rails.respond_to?(:root) && Rails.root.join('config/rabbit_jobs.yml')
|
68
|
+
if config_file
|
69
|
+
if File.exist?(config_file)
|
70
|
+
@configuration ||= Configuration.new
|
71
|
+
@configuration.load_file(config_file)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
unless @configuration
|
76
|
+
configure do |c|
|
77
|
+
c.server 'amqp://localhost'
|
78
|
+
end
|
79
|
+
end
|
66
80
|
|
67
|
-
|
68
|
-
|
69
|
-
@before_process_message_callbacks.each { |callback|
|
70
|
-
return false unless callback.call
|
71
|
-
}
|
72
|
-
return true
|
81
|
+
@configuration
|
82
|
+
end
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RabbitJobs
|
2
|
+
# Connection manager.
|
3
|
+
module AmqpTransport
|
4
|
+
class << self
|
5
|
+
def amqp_connection
|
6
|
+
@amqp_connection ||= Bunny.new(
|
7
|
+
RabbitJobs.config.server,
|
8
|
+
automatically_recover: false,
|
9
|
+
properties: Bunny::Session::DEFAULT_CLIENT_PROPERTIES.merge(product: "rabbit_jobs #{Process.pid}")
|
10
|
+
).start
|
11
|
+
end
|
12
|
+
|
13
|
+
def publisher_channel
|
14
|
+
@publisher_channel ||= amqp_connection.create_channel(2)
|
15
|
+
end
|
16
|
+
|
17
|
+
def consumer_channel
|
18
|
+
@consumer_channel ||= amqp_connection.create_channel(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
def amqp_cleanup
|
22
|
+
conn = @amqp_connection
|
23
|
+
@amqp_connection = nil
|
24
|
+
|
25
|
+
conn.stop if conn && conn.status != :not_connected
|
26
|
+
@consumer_channel.work_pool.join if @consumer_channel
|
27
|
+
@publisher_channel = nil
|
28
|
+
@consumer_channel = nil
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,37 +1,5 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module RabbitJobs
|
3
|
-
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def configure
|
7
|
-
@@configuration ||= Configuration.new
|
8
|
-
yield @@configuration if block_given?
|
9
|
-
end
|
10
|
-
|
11
|
-
def config
|
12
|
-
@@configuration ||= load_config
|
13
|
-
end
|
14
|
-
|
15
|
-
def load_config(config_file = nil)
|
16
|
-
@@configuration ||= nil
|
17
|
-
|
18
|
-
config_file ||= defined?(Rails) && Rails.respond_to?(:root) && Rails.root.join('config/rabbit_jobs.yml')
|
19
|
-
if config_file
|
20
|
-
if File.exists?(config_file)
|
21
|
-
@@configuration ||= Configuration.new
|
22
|
-
@@configuration.load_file(config_file)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
unless @@configuration
|
27
|
-
self.configure do |c|
|
28
|
-
c.server "amqp://localhost"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
@@configuration
|
33
|
-
end
|
34
|
-
|
2
|
+
# Configuration DSL.
|
35
3
|
class Configuration
|
36
4
|
DEFAULT_EXCHANGE_PARAMS = {
|
37
5
|
auto_delete: false,
|
@@ -42,7 +10,7 @@ module RabbitJobs
|
|
42
10
|
auto_delete: false,
|
43
11
|
exclusive: false,
|
44
12
|
durable: true,
|
45
|
-
|
13
|
+
manual_ack: true
|
46
14
|
}
|
47
15
|
|
48
16
|
DEFAULT_MESSAGE_PARAMS = {
|
@@ -59,7 +27,9 @@ module RabbitJobs
|
|
59
27
|
@data = {
|
60
28
|
error_log: true,
|
61
29
|
server: 'amqp://localhost',
|
62
|
-
queues: {
|
30
|
+
queues: {
|
31
|
+
jobs: DEFAULT_QUEUE_PARAMS
|
32
|
+
}
|
63
33
|
}
|
64
34
|
end
|
65
35
|
|
@@ -67,14 +37,6 @@ module RabbitJobs
|
|
67
37
|
@data[name]
|
68
38
|
end
|
69
39
|
|
70
|
-
def default_queue(value = nil)
|
71
|
-
if value
|
72
|
-
@default_queue = value.to_sym
|
73
|
-
else
|
74
|
-
@default_queue || RJ.config[:queues].keys.first || :jobs
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
40
|
def error_log
|
79
41
|
@data[:error_log]
|
80
42
|
end
|
@@ -89,8 +51,8 @@ module RabbitJobs
|
|
89
51
|
end
|
90
52
|
|
91
53
|
def queue(name, params = {})
|
92
|
-
|
93
|
-
|
54
|
+
fail ArgumentError, "name is #{name.inspect}" unless name && name.is_a?(String) && name != ''
|
55
|
+
fail ArgumentError, "params is #{params.inspect}" unless params && params.is_a?(Hash)
|
94
56
|
|
95
57
|
name = name.downcase.to_sym
|
96
58
|
|
@@ -105,6 +67,10 @@ module RabbitJobs
|
|
105
67
|
@data[:queues].keys
|
106
68
|
end
|
107
69
|
|
70
|
+
def queue?(routing_key)
|
71
|
+
routing_keys.include?(routing_key.to_sym)
|
72
|
+
end
|
73
|
+
|
108
74
|
def load_file(filename)
|
109
75
|
load_yaml(File.read(filename))
|
110
76
|
end
|
@@ -116,9 +82,9 @@ module RabbitJobs
|
|
116
82
|
def convert_yaml_config(yaml)
|
117
83
|
yaml = parse_environment(yaml)
|
118
84
|
|
119
|
-
@data = {queues: {}}
|
120
|
-
%w(server
|
121
|
-
|
85
|
+
@data = { queues: {} }
|
86
|
+
%w(server).each do |m|
|
87
|
+
send(m, yaml[m])
|
122
88
|
end
|
123
89
|
yaml['queues'].each do |name, params|
|
124
90
|
queue name, params.symbolize_keys || {}
|
@@ -128,9 +94,7 @@ module RabbitJobs
|
|
128
94
|
private
|
129
95
|
|
130
96
|
def parse_environment(yaml)
|
131
|
-
yaml['rabbit_jobs'] ||
|
132
|
-
(defined?(Rails) && yaml[Rails.env.to_s]) ||
|
133
|
-
yaml
|
97
|
+
yaml['rabbit_jobs'] || (defined?(Rails) && yaml[Rails.env.to_s]) || yaml
|
134
98
|
end
|
135
99
|
end
|
136
100
|
end
|
@@ -1,32 +1,22 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module RabbitJobs
|
3
2
|
module Consumer
|
3
|
+
# Default job consumer.
|
4
4
|
class JobConsumer
|
5
|
-
def process_message(
|
6
|
-
job,
|
5
|
+
def process_message(_delivery_info, _properties, payload)
|
6
|
+
job, params = RJ::Job.parse(payload)
|
7
7
|
|
8
8
|
if job.is_a?(Symbol)
|
9
|
-
report_error(job, *
|
9
|
+
report_error(job, *params)
|
10
10
|
else
|
11
11
|
if job.expired?
|
12
|
-
RJ.logger.warn "Job expired: #{job.to_ruby_string}"
|
12
|
+
RJ.logger.warn "Job expired: #{job.to_ruby_string(*params)}"
|
13
13
|
else
|
14
|
-
job.run_perform
|
14
|
+
job.send(:run_perform, *params)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
true
|
18
18
|
end
|
19
19
|
|
20
|
-
def log_airbrake(msg_or_exception, payload)
|
21
|
-
if defined?(Airbrake)
|
22
|
-
if msg_or_exception.is_a?(String)
|
23
|
-
Airbrake.notify(RuntimeError.new(msg_or_exception))
|
24
|
-
else
|
25
|
-
Airbrake.notify(msg_or_exception)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
20
|
def report_error(error_type, *args)
|
31
21
|
case error_type
|
32
22
|
when :not_found
|
@@ -40,4 +30,4 @@ module RabbitJobs
|
|
40
30
|
end
|
41
31
|
end
|
42
32
|
end
|
43
|
-
end
|
33
|
+
end
|
data/lib/rabbit_jobs/job.rb
CHANGED
@@ -1,162 +1,137 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
require 'benchmark'
|
3
2
|
|
4
3
|
module RabbitJobs
|
4
|
+
# Module to include in client jobs.
|
5
5
|
module Job
|
6
|
-
|
6
|
+
attr_accessor :created_at
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def expired?
|
9
|
+
exp_in = self.class.expires_in.to_i
|
10
|
+
return false if exp_in == 0 || created_at.nil?
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
self.opts = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
attr_accessor :params, :opts
|
17
|
-
|
18
|
-
def run_perform
|
19
|
-
begin
|
20
|
-
ret = nil
|
21
|
-
execution_time = Benchmark.measure { ret = perform(*params) }
|
22
|
-
RabbitJobs.logger.info short_message: "Completed: #{self.to_ruby_string}", _execution_time: execution_time.to_s.strip
|
23
|
-
rescue ScriptError, StandardError
|
24
|
-
log_job_error($!)
|
25
|
-
run_on_error_hooks($!)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def run_on_error_hooks(error)
|
30
|
-
if self.class.rj_on_error_hooks
|
31
|
-
self.class.rj_on_error_hooks.each do |proc_or_symbol|
|
32
|
-
proc = proc_or_symbol
|
33
|
-
if proc_or_symbol.is_a?(Symbol)
|
34
|
-
proc = self.method(proc_or_symbol)
|
35
|
-
end
|
12
|
+
Time.now.to_i > created_at + exp_in
|
13
|
+
end
|
36
14
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
proc.call(error)
|
43
|
-
else
|
44
|
-
proc.call(error, *params)
|
45
|
-
end
|
46
|
-
rescue
|
47
|
-
RJ.logger.error($!)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
15
|
+
def to_ruby_string(*params)
|
16
|
+
rs = self.class.name + params_string(*params)
|
17
|
+
rs << ", created_at: #{created_at}" if created_at
|
18
|
+
rs
|
19
|
+
end
|
52
20
|
|
53
|
-
|
54
|
-
{'class' => self.class.to_s, 'opts' => (self.opts || {}), 'params' => params}.to_json
|
55
|
-
end
|
21
|
+
private
|
56
22
|
|
57
|
-
|
58
|
-
|
23
|
+
def params_string(*params)
|
24
|
+
if params.count > 0
|
25
|
+
"(#{params.map(&:to_s).join(', ')})"
|
26
|
+
else
|
27
|
+
''
|
59
28
|
end
|
29
|
+
end
|
60
30
|
|
61
|
-
|
62
|
-
|
63
|
-
|
31
|
+
def log_job_error(error, *params)
|
32
|
+
RabbitJobs.logger.error(
|
33
|
+
short_message: (error.message.presence || 'rj_worker job error'),
|
34
|
+
_job: to_ruby_string,
|
35
|
+
_exception: error.class,
|
36
|
+
full_message: error.backtrace.join("\r\n"))
|
64
37
|
|
65
|
-
|
66
|
-
|
67
|
-
return false if expires_at == 0
|
68
|
-
Time.now.to_i > expires_at
|
69
|
-
end
|
38
|
+
Airbrake.notify(error, session: { args: to_ruby_string(*params) }) if defined?(Airbrake)
|
39
|
+
end
|
70
40
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
41
|
+
def run_perform(*params)
|
42
|
+
ret = nil
|
43
|
+
execution_time = Benchmark.measure { ret = perform(*params) }
|
44
|
+
RabbitJobs.logger.info(
|
45
|
+
short_message: "Completed: #{to_ruby_string(*params)}",
|
46
|
+
_execution_time: execution_time.to_s.strip)
|
47
|
+
rescue ScriptError, StandardError
|
48
|
+
log_job_error($!, *params)
|
49
|
+
run_on_error_hooks($!, *params)
|
50
|
+
end
|
75
51
|
|
76
|
-
|
77
|
-
|
52
|
+
def run_on_error_hooks(error, *params)
|
53
|
+
return unless @@rj_on_error_hooks.try(:present?)
|
78
54
|
|
79
|
-
|
80
|
-
|
81
|
-
|
55
|
+
@@rj_on_error_hooks.each do |proc_or_symbol|
|
56
|
+
proc = if proc_or_symbol.is_a?(Symbol)
|
57
|
+
method(proc_or_symbol)
|
58
|
+
else
|
59
|
+
proc_or_symbol
|
60
|
+
end
|
82
61
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
62
|
+
begin
|
63
|
+
case proc.arity
|
64
|
+
when 0
|
65
|
+
proc.call
|
66
|
+
when 1
|
67
|
+
proc.call(error)
|
68
|
+
else
|
69
|
+
proc.call(error, *params)
|
70
|
+
end
|
71
|
+
rescue
|
72
|
+
RJ.logger.error($!)
|
89
73
|
end
|
90
74
|
end
|
75
|
+
end
|
91
76
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
77
|
+
class << self
|
78
|
+
def parse(payload)
|
79
|
+
encoded = JSON.parse(payload)
|
80
|
+
job_klass = encoded['class'].to_s.constantize
|
81
|
+
job = job_klass.new
|
82
|
+
job.created_at = encoded['created_at']
|
83
|
+
[job, encoded['params']]
|
84
|
+
rescue NameError
|
85
|
+
[:not_found, encoded['class']]
|
86
|
+
rescue JSON::ParserError
|
87
|
+
[:parsing_error, payload]
|
88
|
+
rescue
|
89
|
+
[:error, $!, payload]
|
98
90
|
end
|
99
91
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
92
|
+
def serialize(klass_name, *params)
|
93
|
+
{
|
94
|
+
'class' => klass_name.to_s,
|
95
|
+
'created_at' => Time.now.to_i,
|
96
|
+
'params' => params
|
97
|
+
}.to_json
|
105
98
|
end
|
106
|
-
end
|
107
99
|
|
108
|
-
|
109
|
-
|
100
|
+
def included(base)
|
101
|
+
base.extend(ClassMethods)
|
102
|
+
base.queue(:jobs)
|
103
|
+
end
|
110
104
|
|
111
105
|
# DSL method for jobs
|
112
|
-
|
113
|
-
|
114
|
-
|
106
|
+
module ClassMethods
|
107
|
+
def expires_in(seconds = nil)
|
108
|
+
@expires_in = seconds.to_i if seconds
|
109
|
+
@expires_in
|
110
|
+
end
|
115
111
|
|
116
|
-
|
117
|
-
hooks.each do |proc_or_symbol|
|
118
|
-
raise ArgumentError.new("Pass proc or symbol to on_error hook") unless proc_or_symbol && ( proc_or_symbol.is_a?(Proc) || proc_or_symbol.is_a?(Symbol) )
|
112
|
+
def on_error(*hooks)
|
119
113
|
@rj_on_error_hooks ||= []
|
120
|
-
|
114
|
+
hooks.each do |proc_or_symbol|
|
115
|
+
unless proc_or_symbol.is_a?(Proc) || proc_or_symbol.is_a?(Symbol)
|
116
|
+
fail ArgumentError.new, 'Pass proc or symbol to on_error hook'
|
117
|
+
end
|
118
|
+
@rj_on_error_hooks << proc_or_symbol
|
119
|
+
end
|
121
120
|
end
|
122
|
-
end
|
123
121
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
def perform_async(*args)
|
130
|
-
RJ::Publisher.publish_to(@rj_queue || RJ.config.default_queue, self, *args)
|
131
|
-
end
|
122
|
+
def queue(routing_key)
|
123
|
+
fail ArgumentError, 'routing_key is blank' if routing_key.blank?
|
124
|
+
@rj_queue = routing_key.to_sym
|
125
|
+
end
|
132
126
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end
|
127
|
+
def perform_async(*args)
|
128
|
+
RJ::Publisher.publish_to(@rj_queue, self, *args)
|
129
|
+
end
|
137
130
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
job_klass = encoded['class'].to_s.constantize
|
142
|
-
job = job_klass.new(*encoded['params'])
|
143
|
-
job.opts = encoded['opts']
|
144
|
-
job
|
145
|
-
rescue NameError
|
146
|
-
[:not_found, encoded['class']]
|
147
|
-
rescue JSON::ParserError
|
148
|
-
[:parsing_error, payload]
|
149
|
-
rescue
|
150
|
-
[:error, $!, payload]
|
131
|
+
def perform(*params)
|
132
|
+
new.perform(*params)
|
133
|
+
end
|
151
134
|
end
|
152
135
|
end
|
153
|
-
|
154
|
-
def self.serialize(klass_name, *params)
|
155
|
-
{
|
156
|
-
'class' => klass_name.to_s,
|
157
|
-
'opts' => {'created_at' => Time.now.to_i},
|
158
|
-
'params' => params
|
159
|
-
}.to_json
|
160
|
-
end
|
161
136
|
end
|
162
137
|
end
|