zmq_jobs 0.0.1.alpha

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 ADDED
@@ -0,0 +1,15 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ log/*.log
6
+ tmp/*
7
+ tmp/**/*
8
+ nbproject/*
9
+ nbproject/**/*
10
+ .idea/*
11
+ .idea/**/*
12
+ .DS_Store
13
+ *.tmproj
14
+ .rvmrc
15
+ Icon*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --drb
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in zmq_jobs.gemspec
4
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
4
+ require 'zmq_jobs'
5
+
6
+ ZmqJobs::BrokerCommand.new(ARGV).start
data/bin/worker ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
4
+ require 'zmq_jobs'
5
+
6
+ ZmqJobs::WorkerCommand.new(ARGV).start
@@ -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
@@ -0,0 +1,11 @@
1
+ require 'zmq_jobs'
2
+ class Default < ZmqJobs::Worker::Base
3
+ def execute message
4
+ logger.info 'Start execute job'
5
+ logger.info message
6
+ sleep 4
7
+ logger.info 'Finished execute job'
8
+ end
9
+ end
10
+
11
+ Default.cmd(ARGV) if $0 == __FILE__
@@ -0,0 +1,11 @@
1
+ require 'zmq_jobs'
2
+ class TestWorker < ZmqJobs::Worker::Base
3
+ def execute message
4
+ logger.info 'Start execute job'
5
+ logger.info message
6
+ sleep 4
7
+ logger.info 'Finished execute job'
8
+ end
9
+ end
10
+
11
+ TestWorker.cmd(ARGV) if $0 == __FILE__
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,5 @@
1
+ module ZmqJobs
2
+ class Balancer < Device
3
+
4
+ end
5
+ 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,3 @@
1
+ module ZmqJobs
2
+ VERSION = "0.0.1.alpha"
3
+ 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
@@ -0,0 +1,7 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require "rspec"
3
+ require 'zmq_jobs'
4
+
5
+ RSpec.configure do |config|
6
+ config.mock_with :rspec
7
+ end
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