zmq_jobs 0.0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/README +0 -0
- data/Rakefile +12 -0
- data/bin/broker +6 -0
- data/bin/worker +6 -0
- data/config/zmq_jobs.yml +14 -0
- data/examples/config/zmq_jobs.yml +18 -0
- data/examples/publisher.rb +20 -0
- data/examples/workers/default.rb +11 -0
- data/examples/workers/test_worker.rb +11 -0
- data/lib/command.rb +172 -0
- data/lib/zmq_jobs/devices/balancer.rb +5 -0
- data/lib/zmq_jobs/devices/broker.rb +20 -0
- data/lib/zmq_jobs/devices/device.rb +65 -0
- data/lib/zmq_jobs/socket/base.rb +93 -0
- data/lib/zmq_jobs/socket/pub.rb +33 -0
- data/lib/zmq_jobs/socket/sub.rb +28 -0
- data/lib/zmq_jobs/version.rb +3 -0
- data/lib/zmq_jobs/worker/base.rb +59 -0
- data/lib/zmq_jobs.rb +52 -0
- data/spec/lib/command_spec.rb +45 -0
- data/spec/spec_helper.rb +7 -0
- data/zmq_jobs.gemspec +32 -0
- metadata +181 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
require 'rdoc/task'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
+
spec.pattern = "spec/**/*_spec.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => ["spec"]
|
data/bin/broker
ADDED
data/bin/worker
ADDED
data/config/zmq_jobs.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
workers_dir: ./examples/workers
|
2
|
+
workers:
|
3
|
+
test_worker:
|
4
|
+
iothreads: 1
|
5
|
+
hosts: ['127.0.0.1']
|
6
|
+
ports: [2203]
|
7
|
+
broker:
|
8
|
+
iothreads: 1
|
9
|
+
frontend:
|
10
|
+
hosts: ['127.0.0.1']
|
11
|
+
ports: [<%= (2200..2202).to_a.join(', ') %>]
|
12
|
+
backend:
|
13
|
+
host: '127.0.0.1'
|
14
|
+
port: 2203
|
@@ -0,0 +1,18 @@
|
|
1
|
+
workers_dir: ./workers
|
2
|
+
workers:
|
3
|
+
default:
|
4
|
+
iothreads: 1
|
5
|
+
hosts: ['127.0.0.1']
|
6
|
+
ports: [2203]
|
7
|
+
test_worker:
|
8
|
+
iothreads: 1
|
9
|
+
hosts: ['127.0.0.1']
|
10
|
+
ports: [2203]
|
11
|
+
broker:
|
12
|
+
iothreads: 1
|
13
|
+
frontend:
|
14
|
+
hosts: ['127.0.0.1']
|
15
|
+
ports: [<%= (2200..2202).to_a.join(', ') %>]
|
16
|
+
backend:
|
17
|
+
host: '127.0.0.1'
|
18
|
+
port: 2203
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
2
|
+
require 'zmq_jobs'
|
3
|
+
message = lambda{|num|"Message ##{num}"}
|
4
|
+
index = 0
|
5
|
+
|
6
|
+
Signal.trap('INT') do
|
7
|
+
publisher.stop
|
8
|
+
end
|
9
|
+
|
10
|
+
publisher = ZmqJobs::Socket::Pub.new(
|
11
|
+
'host' => '127.0.0.1',
|
12
|
+
'port' => 2200
|
13
|
+
)
|
14
|
+
publisher.run do |socket|
|
15
|
+
msg = message.call(index)
|
16
|
+
socket.send_string(msg)
|
17
|
+
puts "Send message: #{msg}"
|
18
|
+
index += 1
|
19
|
+
sleep 2
|
20
|
+
end.terminate
|
data/lib/command.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'daemons'
|
3
|
+
require 'yaml'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
module ZmqJobs
|
7
|
+
class Command
|
8
|
+
attr_reader :daemonize, :monitor, :config_file, :execute_dir, :options
|
9
|
+
DEVICES = {'broker' => Broker, 'balancer' => Balancer}
|
10
|
+
|
11
|
+
def self.define_properties options
|
12
|
+
options.each do |property, value|
|
13
|
+
define_method(property.to_sym) do |*args|
|
14
|
+
value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(args)
|
20
|
+
raise 'You can not create instance of abstract class' if self.class == Command
|
21
|
+
@daemonize = false
|
22
|
+
@monitor = false
|
23
|
+
@execute_dir = Dir.pwd
|
24
|
+
@pid_dir = './tmp'
|
25
|
+
@config_file = './config/zmq_jobs.yml'
|
26
|
+
@options = read_config_file
|
27
|
+
|
28
|
+
if args.empty?
|
29
|
+
puts opts_parser
|
30
|
+
exit 1
|
31
|
+
else
|
32
|
+
@args = opts_parser.parse!(args)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def start
|
37
|
+
start_daemon(type, daemon_config(type))
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
def opts_parser
|
42
|
+
opts_parser_builder
|
43
|
+
end
|
44
|
+
|
45
|
+
def opts_parser_builder
|
46
|
+
OptionParser.new do |opts|
|
47
|
+
opts.banner = opts_banner
|
48
|
+
opts.separator ''
|
49
|
+
opts.on('-h', '--help', 'Show this message') do
|
50
|
+
puts opts
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
opts.on('-m', '--monitor', 'Start monitor process.') do
|
54
|
+
@monitor = true
|
55
|
+
end
|
56
|
+
opts.on('-d', '--daemonize', "Daemonize the #{type} process") do
|
57
|
+
@daemonize = true
|
58
|
+
end
|
59
|
+
opts.on('-c CONFIG', '--config CONFIG', "Use config file, default: #{config_file}") do |config|
|
60
|
+
@config_file = config
|
61
|
+
end
|
62
|
+
yield opts if block_given?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def opts_banner
|
67
|
+
"Usage: #{type} <start|stop|restart> [options]"
|
68
|
+
end
|
69
|
+
|
70
|
+
def start_daemon daemon_name, config
|
71
|
+
return false unless config
|
72
|
+
Daemons.run_proc(
|
73
|
+
daemon_name,
|
74
|
+
{
|
75
|
+
:multiple => false,
|
76
|
+
:dir_mode => :normal,
|
77
|
+
:monitor => monitor,
|
78
|
+
:ARGV => @args,
|
79
|
+
:ontop => !daemonize
|
80
|
+
}
|
81
|
+
) do
|
82
|
+
daemon_class(daemon_name).new(config).start
|
83
|
+
end
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
def read_config_file
|
88
|
+
YAML.load(ERB.new(File.new(File.expand_path(config_file, execute_dir)).read).result)
|
89
|
+
end
|
90
|
+
|
91
|
+
def daemon_config name
|
92
|
+
options[name] || (
|
93
|
+
::ZmqJobs.logger.info("#{type.capitalize} '#{name}' not found in config file") and
|
94
|
+
return false
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class BrokerCommand < Command
|
100
|
+
define_properties :type => 'broker', :daemon_class => Broker
|
101
|
+
end
|
102
|
+
|
103
|
+
class BalancerCommand < Command
|
104
|
+
define_properties :type => 'balancer', :daemon_class => Balancer
|
105
|
+
end
|
106
|
+
|
107
|
+
class WorkerCommand < Command
|
108
|
+
define_properties :type => 'worker'
|
109
|
+
|
110
|
+
def start
|
111
|
+
::ZmqJobs.logger.info('You do not have any workers to start') if workers_to_start.size < 1
|
112
|
+
|
113
|
+
raise ArgumentError.new(
|
114
|
+
'You can not start more then one worker without -d option'
|
115
|
+
) if workers_to_start.size > 1 && !daemonize
|
116
|
+
|
117
|
+
success = workers_to_start.map{|worker|
|
118
|
+
preload_worker_class(daemon_classname(worker))
|
119
|
+
start_daemon(worker, daemon_config(worker))
|
120
|
+
}.inject(&:'&&')
|
121
|
+
|
122
|
+
::ZmqJobs.logger.info('One or more workers do not started') unless success
|
123
|
+
end
|
124
|
+
|
125
|
+
protected
|
126
|
+
def preload_worker_class classname
|
127
|
+
worker_class_dir = File.expand_path(options['workers_dir'], execute_dir)
|
128
|
+
Kernel.require(
|
129
|
+
"#{worker_class_dir}/#{ActiveSupport::Inflector.underscore(classname)}"
|
130
|
+
) unless Kernel.const_defined?(classname)
|
131
|
+
end
|
132
|
+
|
133
|
+
def opts_parser
|
134
|
+
opts_parser_builder do |opts|
|
135
|
+
opts.on('-w', '--workers LIST', 'Workers which have to run.') do |workers|
|
136
|
+
@workers = workers.split(',')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def daemon_config name
|
142
|
+
options['workers'][name] || (
|
143
|
+
::ZmqJobs.logger.info("#{type.capitalize} '#{name}' not found in config file") and
|
144
|
+
return nil
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
def daemon_class name=nil
|
149
|
+
ActiveSupport::Inflector.constantize(daemon_classname(name))
|
150
|
+
end
|
151
|
+
|
152
|
+
def daemon_classname name
|
153
|
+
ActiveSupport::Inflector.camelize(name, true)
|
154
|
+
end
|
155
|
+
|
156
|
+
def all_workers
|
157
|
+
options['workers'].keys
|
158
|
+
end
|
159
|
+
|
160
|
+
def input_workers
|
161
|
+
@workers
|
162
|
+
end
|
163
|
+
|
164
|
+
def workers_to_start
|
165
|
+
@workers_to_start ||= if !input_workers || input_workers.empty?
|
166
|
+
all_workers
|
167
|
+
else
|
168
|
+
input_workers.select{|w|all_workers.include?(w)}
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ZmqJobs
|
2
|
+
class Broker < Device
|
3
|
+
protected
|
4
|
+
def start_device
|
5
|
+
@device = ZMQ::Device.new(ZMQ::FORWARDER, frontend.socket, backend.socket)
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_frontend
|
9
|
+
config = frontend_options
|
10
|
+
config['context'] = context
|
11
|
+
Socket::Sub.new(config).connect
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_backend
|
15
|
+
config = backend_options
|
16
|
+
config['context'] = context
|
17
|
+
Socket::Pub.new(config).connect
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ZmqJobs
|
2
|
+
class Device
|
3
|
+
class << self
|
4
|
+
def start options
|
5
|
+
new(options).start
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :options, :device
|
10
|
+
|
11
|
+
def initialize options
|
12
|
+
@options = options.assert_valid_keys('iothreads', 'frontend', 'backend')
|
13
|
+
end
|
14
|
+
|
15
|
+
def context
|
16
|
+
@context ||= ZMQ::Context.create(options['iothreads'])
|
17
|
+
end
|
18
|
+
|
19
|
+
def start
|
20
|
+
trap('TERM'){stop;Process.exit}
|
21
|
+
trap('INT'){stop;Process.exit}
|
22
|
+
logger.info "#{self.class} is starting ..."
|
23
|
+
start_device
|
24
|
+
end
|
25
|
+
|
26
|
+
def stop
|
27
|
+
frontend.disconnect
|
28
|
+
backend.disconnect
|
29
|
+
#context.terminate
|
30
|
+
logger.info 'Exiting...'
|
31
|
+
end
|
32
|
+
|
33
|
+
def frontend
|
34
|
+
@frontent ||= create_frontend
|
35
|
+
end
|
36
|
+
|
37
|
+
def backend
|
38
|
+
@backend ||= create_backend
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_frontend
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_backend
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
def start_device
|
49
|
+
end
|
50
|
+
|
51
|
+
def frontend_options
|
52
|
+
options['frontend'].
|
53
|
+
assert_valid_keys('hosts', 'ports', 'subscribe', 'linger')
|
54
|
+
end
|
55
|
+
|
56
|
+
def backend_options
|
57
|
+
options['backend'].
|
58
|
+
assert_valid_keys('host', 'port')
|
59
|
+
end
|
60
|
+
|
61
|
+
def logger
|
62
|
+
::ZmqJobs.logger
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module ZmqJobs
|
2
|
+
module Socket
|
3
|
+
class Error < RuntimeError;end
|
4
|
+
class Base
|
5
|
+
attr_reader :socket, :options
|
6
|
+
|
7
|
+
def initialize options={}
|
8
|
+
iothreads = options['iothreads'] ? options['iothreads'].to_i : 1
|
9
|
+
@context = options.delete('context') || ZMQ::Context.create(iothreads)
|
10
|
+
raise Error.new('Can not create context') unless @context
|
11
|
+
@options = default_options.merge(options)
|
12
|
+
@socket = @context.socket(ZMQ::PUB)
|
13
|
+
@running = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_link url
|
17
|
+
end
|
18
|
+
|
19
|
+
def connect
|
20
|
+
urls.each{|url|assert(create_link(url))}
|
21
|
+
@connected = true
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def disconnect
|
26
|
+
socket.close if connected?
|
27
|
+
@connected = false
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def run
|
32
|
+
@running = true
|
33
|
+
connect
|
34
|
+
|
35
|
+
loop do
|
36
|
+
yield socket
|
37
|
+
break unless running?
|
38
|
+
end
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def stop
|
44
|
+
@running = false
|
45
|
+
disconnect
|
46
|
+
end
|
47
|
+
|
48
|
+
def terminate
|
49
|
+
@context.terminate if @context && @context.respond_to?(:terminate)
|
50
|
+
end
|
51
|
+
|
52
|
+
def running?
|
53
|
+
!!@running
|
54
|
+
end
|
55
|
+
|
56
|
+
def connected?
|
57
|
+
!!@connected
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
def assert(rc)
|
62
|
+
raise Error.new(
|
63
|
+
"Operation failed, errno [#{ZMQ::Util.errno}] description [#{ZMQ::Util.error_string}]"
|
64
|
+
) unless ZMQ::Util.resultcode_ok?(rc)
|
65
|
+
end
|
66
|
+
|
67
|
+
def urls
|
68
|
+
u = []
|
69
|
+
hosts.each do |host|
|
70
|
+
ports.each do |port|
|
71
|
+
u << "tcp://#{host}:#{port}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
u
|
75
|
+
end
|
76
|
+
|
77
|
+
def hosts
|
78
|
+
options['hosts'].is_a?(Array) ? options['hosts'] : [options['hosts']]
|
79
|
+
end
|
80
|
+
|
81
|
+
def ports
|
82
|
+
options['ports'].is_a?(Array) ? options['ports'] : [options['ports']]
|
83
|
+
end
|
84
|
+
|
85
|
+
def default_options
|
86
|
+
{
|
87
|
+
'hosts' => '*',
|
88
|
+
'ports' => 2200
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ZmqJobs
|
2
|
+
module Socket
|
3
|
+
class Pub < Base
|
4
|
+
def initialize options={}
|
5
|
+
super(options)
|
6
|
+
@socket = @context.socket(ZMQ::PUB)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_link url
|
10
|
+
socket.bind(url).tap do
|
11
|
+
sleep 1
|
12
|
+
::ZmqJobs.logger.info "Publisher have started at #{url}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def hosts
|
18
|
+
options['host'].is_a?(Array) ? [options['host'].first] : [options['host']]
|
19
|
+
end
|
20
|
+
|
21
|
+
def ports
|
22
|
+
options['port'].is_a?(Array) ? [options['port'].first] : [options['port']]
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_options
|
26
|
+
{
|
27
|
+
'host' => '*',
|
28
|
+
'port' => 2200
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ZmqJobs
|
2
|
+
module Socket
|
3
|
+
class Sub < Base
|
4
|
+
def initialize options={}
|
5
|
+
super(options)
|
6
|
+
@socket = @context.socket(ZMQ::SUB)
|
7
|
+
assert(socket.setsockopt(ZMQ::LINGER, self.options['linger'])) if self.options['linger']
|
8
|
+
assert(socket.setsockopt(ZMQ::SUBSCRIBE, self.options['subscribe'])) if self.options['subscribe']
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_link url
|
12
|
+
socket.connect(url).tap do
|
13
|
+
::ZmqJobs.logger.info "Subscriber have started at #{url}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def default_options
|
19
|
+
{
|
20
|
+
'linger' => 0,
|
21
|
+
'subscribe' => '',
|
22
|
+
'hosts' => ['127.0.0.1'],
|
23
|
+
'ports' => [2200]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ZmqJobs
|
2
|
+
module Worker
|
3
|
+
class Base
|
4
|
+
attr_reader :options
|
5
|
+
class << self
|
6
|
+
def cmd args
|
7
|
+
count = args[2].to_i || 0
|
8
|
+
options = {
|
9
|
+
'hosts' => [args[0]],
|
10
|
+
'ports' => (args[1].to_i..(args[1].to_i + count)).to_a
|
11
|
+
}
|
12
|
+
options['iothreads'] = args[3] if args[3]
|
13
|
+
start(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def start options
|
17
|
+
new(options).start
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize options={}
|
22
|
+
@options = options
|
23
|
+
end
|
24
|
+
|
25
|
+
def start
|
26
|
+
trap('TERM'){stop}
|
27
|
+
trap('INT'){stop}
|
28
|
+
logger.info "#{self.class} is starting ..."
|
29
|
+
|
30
|
+
subscriber.run do |socket|
|
31
|
+
message = ''
|
32
|
+
rc = socket.recv_string(message, ZMQ::NOBLOCK)
|
33
|
+
if ZMQ::Util.resultcode_ok?(rc)
|
34
|
+
#message = BSON.deserialize(bson)
|
35
|
+
execute_job message
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def stop
|
41
|
+
logger.info "Exiting..."
|
42
|
+
subscriber.stop
|
43
|
+
#subscriber.terminate
|
44
|
+
end
|
45
|
+
|
46
|
+
def execute_job message
|
47
|
+
execute(message)
|
48
|
+
end
|
49
|
+
|
50
|
+
def subscriber
|
51
|
+
@subscriber ||= Socket::Sub.new(options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def logger
|
55
|
+
::ZmqJobs.logger
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/zmq_jobs.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup :default, (ENV['RACK_ENV'] || 'development')
|
4
|
+
require 'yaml'
|
5
|
+
require 'active_support'
|
6
|
+
require 'active_support/core_ext/hash/keys'
|
7
|
+
require 'ffi-rzmq'
|
8
|
+
require 'logger'
|
9
|
+
|
10
|
+
module ZmqJobs
|
11
|
+
extend self
|
12
|
+
extend ActiveSupport::Autoload
|
13
|
+
|
14
|
+
autoload_under 'devices' do
|
15
|
+
autoload :Device
|
16
|
+
autoload :Balancer
|
17
|
+
autoload :Broker
|
18
|
+
end
|
19
|
+
|
20
|
+
module Worker
|
21
|
+
extend ActiveSupport::Autoload
|
22
|
+
|
23
|
+
autoload :Base
|
24
|
+
end
|
25
|
+
|
26
|
+
module Socket
|
27
|
+
extend ActiveSupport::Autoload
|
28
|
+
|
29
|
+
autoload :Base
|
30
|
+
autoload :Pub
|
31
|
+
autoload :Sub
|
32
|
+
end
|
33
|
+
|
34
|
+
def logger
|
35
|
+
@logger = default_logger unless defined?(@logger)
|
36
|
+
@logger
|
37
|
+
end
|
38
|
+
|
39
|
+
def logger=(logger)
|
40
|
+
case logger
|
41
|
+
when Logger then @logger = logger
|
42
|
+
when false, nil then @logger = nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
def default_logger
|
48
|
+
defined?(Rails) && Rails.respond_to?(:logger) ? Rails.logger : ::Logger.new($stdout)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'command'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe ZmqJobs::BrokerCommand do
|
4
|
+
let(:command) do
|
5
|
+
ZmqJobs::BrokerCommand.any_instance.stub(:read_config_file => options, :start => true)
|
6
|
+
ZmqJobs::BrokerCommand.new(args)
|
7
|
+
end
|
8
|
+
let(:options){{:key1 => :value1, :key2 => :value2}}
|
9
|
+
|
10
|
+
context 'without option' do
|
11
|
+
let(:args){['start']}
|
12
|
+
|
13
|
+
specify{command.daemonize.should be_false}
|
14
|
+
specify{command.monitor.should be_false}
|
15
|
+
specify{command.config_file.should == './config/zmq_jobs.yml'}
|
16
|
+
specify{command.execute_dir.should == Dir.pwd}
|
17
|
+
specify{command.options.should == options}
|
18
|
+
specify{command.type.should == 'broker'}
|
19
|
+
specify{command.daemon_class.should == ZmqJobs::Broker}
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with option -d' do
|
23
|
+
let(:args){['start', '-d']}
|
24
|
+
|
25
|
+
specify{command.daemonize.should be_true}
|
26
|
+
specify{command.monitor.should be_false}
|
27
|
+
specify{command.config_file.should == './config/zmq_jobs.yml'}
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with option -m' do
|
31
|
+
let(:args){['start', '-m']}
|
32
|
+
|
33
|
+
specify{command.daemonize.should be_false}
|
34
|
+
specify{command.monitor.should be_true}
|
35
|
+
specify{command.config_file.should == './config/zmq_jobs.yml'}
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with option -c' do
|
39
|
+
let(:args){['start', '-c', 'bla-bla-bla']}
|
40
|
+
|
41
|
+
specify{command.daemonize.should be_false}
|
42
|
+
specify{command.monitor.should be_false}
|
43
|
+
specify{command.config_file.should == 'bla-bla-bla'}
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/zmq_jobs.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "zmq_jobs/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "zmq_jobs"
|
7
|
+
s.version = ZmqJobs::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Undr"]
|
10
|
+
s.email = ["undr@yandex.ru"]
|
11
|
+
s.homepage = "http://github.com/undr/zmq_jobs"
|
12
|
+
s.summary = %q{ZeroMQ-based queue system for background job}
|
13
|
+
s.description = %q{ZeroMQ-based queue system for background job}
|
14
|
+
|
15
|
+
s.rubyforge_project = "zmq_jobs"
|
16
|
+
|
17
|
+
s.add_development_dependency "rspec", ">= 2"
|
18
|
+
s.add_development_dependency "yard", "~> 0.6.0"
|
19
|
+
s.add_development_dependency "ruby-debug19"
|
20
|
+
|
21
|
+
s.add_dependency "bundler", "~> 1.0.0"
|
22
|
+
s.add_dependency "rake"
|
23
|
+
s.add_dependency "ffi"
|
24
|
+
s.add_dependency "ffi-rzmq"
|
25
|
+
s.add_dependency "activesupport"
|
26
|
+
s.add_dependency "daemons"
|
27
|
+
|
28
|
+
s.files = `git ls-files`.split("\n")
|
29
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
30
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zmq_jobs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: 6
|
5
|
+
version: 0.0.1.alpha
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Undr
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-11-10 00:00:00 +07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "2"
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.6.0
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: ruby-debug19
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: bundler
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 1.0.0
|
58
|
+
type: :runtime
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: rake
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
type: :runtime
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: ffi
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
type: :runtime
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: ffi-rzmq
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
type: :runtime
|
92
|
+
version_requirements: *id007
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: activesupport
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0"
|
102
|
+
type: :runtime
|
103
|
+
version_requirements: *id008
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: daemons
|
106
|
+
prerelease: false
|
107
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: "0"
|
113
|
+
type: :runtime
|
114
|
+
version_requirements: *id009
|
115
|
+
description: ZeroMQ-based queue system for background job
|
116
|
+
email:
|
117
|
+
- undr@yandex.ru
|
118
|
+
executables:
|
119
|
+
- broker
|
120
|
+
- worker
|
121
|
+
extensions: []
|
122
|
+
|
123
|
+
extra_rdoc_files: []
|
124
|
+
|
125
|
+
files:
|
126
|
+
- .gitignore
|
127
|
+
- .rspec
|
128
|
+
- Gemfile
|
129
|
+
- README
|
130
|
+
- Rakefile
|
131
|
+
- bin/broker
|
132
|
+
- bin/worker
|
133
|
+
- config/zmq_jobs.yml
|
134
|
+
- examples/config/zmq_jobs.yml
|
135
|
+
- examples/publisher.rb
|
136
|
+
- examples/workers/default.rb
|
137
|
+
- examples/workers/test_worker.rb
|
138
|
+
- lib/command.rb
|
139
|
+
- lib/zmq_jobs.rb
|
140
|
+
- lib/zmq_jobs/devices/balancer.rb
|
141
|
+
- lib/zmq_jobs/devices/broker.rb
|
142
|
+
- lib/zmq_jobs/devices/device.rb
|
143
|
+
- lib/zmq_jobs/socket/base.rb
|
144
|
+
- lib/zmq_jobs/socket/pub.rb
|
145
|
+
- lib/zmq_jobs/socket/sub.rb
|
146
|
+
- lib/zmq_jobs/version.rb
|
147
|
+
- lib/zmq_jobs/worker/base.rb
|
148
|
+
- spec/lib/command_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
- zmq_jobs.gemspec
|
151
|
+
has_rdoc: true
|
152
|
+
homepage: http://github.com/undr/zmq_jobs
|
153
|
+
licenses: []
|
154
|
+
|
155
|
+
post_install_message:
|
156
|
+
rdoc_options: []
|
157
|
+
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: "0"
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ">"
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 1.3.1
|
172
|
+
requirements: []
|
173
|
+
|
174
|
+
rubyforge_project: zmq_jobs
|
175
|
+
rubygems_version: 1.6.2
|
176
|
+
signing_key:
|
177
|
+
specification_version: 3
|
178
|
+
summary: ZeroMQ-based queue system for background job
|
179
|
+
test_files:
|
180
|
+
- spec/lib/command_spec.rb
|
181
|
+
- spec/spec_helper.rb
|