kinetic 0.0.1
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 +7 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +28 -0
- data/Rakefile +1 -0
- data/examples/simple_worker.rb +8 -0
- data/kinetic.gemspec +34 -0
- data/lib/kinetic.rb +3 -0
- data/lib/kinetic/base.rb +87 -0
- data/lib/kinetic/cli.rb +31 -0
- data/lib/kinetic/configuration.rb +17 -0
- data/lib/kinetic/errors.rb +18 -0
- data/lib/kinetic/master.rb +132 -0
- data/lib/kinetic/publisher.rb +6 -0
- data/lib/kinetic/version.rb +3 -0
- data/lib/kinetic/worker.rb +73 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 67a4ff614b5f65c94ff43ae5e18e7a73944c13e3
|
4
|
+
data.tar.gz: 41f13ae0b524573c98a63f853d7be3c458c12a96
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 72ce1e7b862c33785117568f17944f7d40401c158e78e80a3a44e7b865d299ef1c521c24104a81b666397689e069273434be0cbaa553f5fb6f83b7a6411c4625
|
7
|
+
data.tar.gz: 575a3a38d19d22d92125da043f9a065cd18f53d348003f3eda1ac9ef0679476ed636f923bc0a2d722d6c16e3dd08d87df3f18a87f532869463f1f3f50cb8f1be
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jarod Reid
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Kinetic
|
2
|
+
|
3
|
+
Kinetic is an AMQP worker framework designed in vein of microframeworks such as sinatra. Its goal is to provide an
|
4
|
+
easy way to configure and run AMQP consumers in order to reduce developer overhead when working with AMQP. Kinetic
|
5
|
+
follows the master/worker convention used in Unicorn, and its prefork code is mostly based on that of Unicorn's.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem install kinetic
|
11
|
+
```
|
12
|
+
|
13
|
+
### Basic Usage
|
14
|
+
|
15
|
+
Kinetic follows a pattern similar to that of Sinatra, so most of the conventions should be recognizable.
|
16
|
+
|
17
|
+
|
18
|
+
Example: simple_worker.rb
|
19
|
+
|
20
|
+
```
|
21
|
+
set :host, 'localhost'
|
22
|
+
set :port, 5678
|
23
|
+
|
24
|
+
on 'message' do |message|
|
25
|
+
puts "Received #{message}"
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/kinetic.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'kinetic/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'kinetic'
|
8
|
+
spec.version = Kinetic::VERSION
|
9
|
+
spec.authors = ['Jarod Reid']
|
10
|
+
spec.email = ['jreid@voyst.com']
|
11
|
+
spec.description = %q{A powerful yet simple AMQP worker framework}
|
12
|
+
spec.summary = %q{A powerful yet simple AMQP worker framework}
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'confstruct'
|
22
|
+
spec.add_dependency 'amqp'
|
23
|
+
spec.add_dependency 'activesupport'
|
24
|
+
spec.add_dependency 'kgio'
|
25
|
+
spec.add_dependency 'awesome_print'
|
26
|
+
spec.add_dependency 'msgpack'
|
27
|
+
spec.add_dependency 'bunny'
|
28
|
+
|
29
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
30
|
+
spec.add_development_dependency 'rake'
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
end
|
data/lib/kinetic.rb
ADDED
data/lib/kinetic/base.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# ruby dependencies
|
2
|
+
require 'logger'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
# external dependencies
|
6
|
+
require 'amqp'
|
7
|
+
require 'confstruct'
|
8
|
+
require 'kgio'
|
9
|
+
require 'active_support/core_ext/module/delegation'
|
10
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
11
|
+
require 'awesome_print'
|
12
|
+
require 'awesome_print/core_ext/logger'
|
13
|
+
require 'msgpack'
|
14
|
+
|
15
|
+
# kinetic dependencies
|
16
|
+
require_relative '../kinetic/version'
|
17
|
+
require_relative '../kinetic/configuration'
|
18
|
+
require_relative '../kinetic/master'
|
19
|
+
require_relative '../kinetic/worker'
|
20
|
+
|
21
|
+
module Kinetic
|
22
|
+
|
23
|
+
module Delegator
|
24
|
+
|
25
|
+
%w{on config logging set}.each { |m| delegate m.to_sym, to: :application }
|
26
|
+
|
27
|
+
def application
|
28
|
+
Application
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class Base
|
35
|
+
|
36
|
+
class << self
|
37
|
+
|
38
|
+
attr_reader :exchanges
|
39
|
+
|
40
|
+
def set(key, value)
|
41
|
+
config[key] = value
|
42
|
+
end
|
43
|
+
|
44
|
+
def config
|
45
|
+
@config ||= Kinetic::Configuration.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def logger
|
49
|
+
@logger ||= reopen_logger
|
50
|
+
end
|
51
|
+
|
52
|
+
def reopen_logger
|
53
|
+
@logger = Logger.new(STDOUT)
|
54
|
+
end
|
55
|
+
|
56
|
+
def on(key, &block)
|
57
|
+
logger.debug "Setting up '#{key}' on 'direct'"
|
58
|
+
direct[key] = block
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def direct
|
64
|
+
exchanges[:direct] ||= {}
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def exchanges
|
69
|
+
@exchanges ||= {}
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
delegate :logger, to: :class
|
75
|
+
delegate :config, to: :class
|
76
|
+
|
77
|
+
def reopen_logger
|
78
|
+
self.class.reopen_logger
|
79
|
+
end
|
80
|
+
|
81
|
+
def exchanges
|
82
|
+
self.class.send(:exchanges)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
data/lib/kinetic/cli.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'kinetic/base'
|
2
|
+
module Kinetic
|
3
|
+
module CLI
|
4
|
+
|
5
|
+
COMMANDS = %w{run start stop}
|
6
|
+
|
7
|
+
PARSER = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage #{File.basename($0)} (#{COMMANDS.join('|')}) [options]"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.parse
|
12
|
+
if ARGV[0] && COMMANDS.include?(ARGV[0])
|
13
|
+
command = ARGV.shift
|
14
|
+
else
|
15
|
+
puts PARSER.banner
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
command
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
class Application < Base
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
at_exit { Master.new(Application.new).send(CLI.parse) }
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
extend Kinetic::Delegator
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Kinetic
|
2
|
+
class Configuration < Confstruct::Configuration
|
3
|
+
|
4
|
+
DEFAULTS = {
|
5
|
+
name: File.basename($0),
|
6
|
+
root: File.dirname($0),
|
7
|
+
app_file: $0,
|
8
|
+
workers: 1,
|
9
|
+
}
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super
|
13
|
+
self.reverse_merge!(DEFAULTS)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Kinetic
|
2
|
+
module Errors
|
3
|
+
|
4
|
+
class KineticError < StandardError; end
|
5
|
+
|
6
|
+
class ConnectionError < KineticError
|
7
|
+
|
8
|
+
def initialize(error)
|
9
|
+
message = error.message
|
10
|
+
backtrace = error.backtrace
|
11
|
+
super message
|
12
|
+
self.set_backtrace(backtrace)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
module Kinetic
|
3
|
+
class Master
|
4
|
+
|
5
|
+
SELF_PIPE = []
|
6
|
+
QUEUE_SIGS = [ :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
|
7
|
+
WORKERS = {}
|
8
|
+
SIG_QUEUE = []
|
9
|
+
|
10
|
+
delegate :logger, to: :app
|
11
|
+
delegate :config, to: :app
|
12
|
+
|
13
|
+
attr_reader :app
|
14
|
+
|
15
|
+
def initialize(app)
|
16
|
+
@app = app
|
17
|
+
end
|
18
|
+
|
19
|
+
# Starts and initializes the master process.
|
20
|
+
#
|
21
|
+
# @return [Kinetic::Master] the master process
|
22
|
+
def run
|
23
|
+
begin
|
24
|
+
logger.info "Starting Kinetic #{Kinetic::VERSION} with PID #{Process.pid}"
|
25
|
+
logger.debug 'Configuration:'
|
26
|
+
logger.ap config.to_hash
|
27
|
+
write_pidfile!
|
28
|
+
initialize_self_pipe!
|
29
|
+
initialize_signal_traps!
|
30
|
+
spawn_missing_workers
|
31
|
+
join
|
32
|
+
ensure
|
33
|
+
call_on_exit_callbacks
|
34
|
+
exit!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sets or gets the before fork block. This is called just before a worker is forked.
|
39
|
+
#
|
40
|
+
# @return [Proc] the before_block
|
41
|
+
def before_fork(&block)
|
42
|
+
@before_fork = block if block_given?
|
43
|
+
@before_fork || proc {}
|
44
|
+
end
|
45
|
+
|
46
|
+
# Sets or gets the after fork block. This is called immediately after a worker is forked.
|
47
|
+
#
|
48
|
+
# @return [Proc] the after_fork block
|
49
|
+
def after_fork(&block)
|
50
|
+
@after_fork = block if block_given?
|
51
|
+
@after_fork || proc {}
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def join
|
57
|
+
logger.debug "joining thread"
|
58
|
+
loop do
|
59
|
+
sleep 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Based on Unicorn's self-pipe
|
64
|
+
def initialize_self_pipe!
|
65
|
+
logger.debug 'Initializing self pipe'
|
66
|
+
SELF_PIPE.replace Kgio::Pipe.new.each { |io| io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def initialize_signal_traps!
|
70
|
+
logger.debug 'Initializing signal traps'
|
71
|
+
QUEUE_SIGS.each { |sig| trap(sig) {SIG_QUEUE << sig; awaken_master } }
|
72
|
+
trap(:CHLD) { awaken_master }
|
73
|
+
end
|
74
|
+
|
75
|
+
def awaken_master
|
76
|
+
logger.debug 'Awakening master'
|
77
|
+
SELF_PIPE[1].kgio_trywrite('.')
|
78
|
+
end
|
79
|
+
|
80
|
+
def write_pidfile!
|
81
|
+
config.pid ||= File.join(config.root, "#{config.name}.pid")
|
82
|
+
logger.info "Writing PID file to #{config.pid}"
|
83
|
+
File.open(config.pid, 'w') { |f| f.write(Process.pid) }
|
84
|
+
end
|
85
|
+
|
86
|
+
def call_on_exit_callbacks
|
87
|
+
ensure
|
88
|
+
FileUtils.rm(config.pid)
|
89
|
+
end
|
90
|
+
|
91
|
+
def spawn_missing_workers
|
92
|
+
logger.debug 'Spawning missing workers'
|
93
|
+
worker_nr = -1
|
94
|
+
until (worker_nr += 1) == config.workers
|
95
|
+
WORKERS.value?(worker_nr) and next
|
96
|
+
worker = Worker.new(worker_nr, @app)
|
97
|
+
logger.debug 'Calling before_fork block'
|
98
|
+
before_fork.call(self, worker)
|
99
|
+
logger.debug 'Forking worker'
|
100
|
+
pid = fork do
|
101
|
+
app.reopen_logger
|
102
|
+
worker.run
|
103
|
+
end
|
104
|
+
logger.debug "Worker #{worker_nr} started on #{pid}"
|
105
|
+
end
|
106
|
+
rescue => e
|
107
|
+
logger.error(e)
|
108
|
+
end
|
109
|
+
|
110
|
+
EXIT_SIGS = [ :QUIT, :TERM, :INT ]
|
111
|
+
WORKER_QUEUE_SIGS = QUEUE_SIGS - EXIT_SIGS
|
112
|
+
|
113
|
+
# gets rid of stuff the worker has no business keeping track of
|
114
|
+
# to free some resources and drops all sig handlers.
|
115
|
+
# traps for USR1, USR2, and HUP may be set in the after_fork Proc
|
116
|
+
# by the user.
|
117
|
+
def init_worker_process(worker)
|
118
|
+
worker.atfork_child
|
119
|
+
# we'll re-trap :QUIT later for graceful shutdown iff we accept clients
|
120
|
+
EXIT_SIGS.each { |sig| trap(sig) { exit!(0) } }
|
121
|
+
exit!(0) if (SIG_QUEUE & EXIT_SIGS)[0]
|
122
|
+
WORKER_QUEUE_SIGS.each { |sig| trap(sig, nil) }
|
123
|
+
trap(:CHLD, 'DEFAULT')
|
124
|
+
SIG_QUEUE.clear
|
125
|
+
WORKERS.clear
|
126
|
+
|
127
|
+
after_fork.call(self, worker)
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Kinetic
|
2
|
+
class Worker
|
3
|
+
|
4
|
+
delegate :logger, to: :app
|
5
|
+
delegate :config, to: :app
|
6
|
+
|
7
|
+
attr_reader :id, :app, :channel, :exchanges
|
8
|
+
|
9
|
+
def initialize(id, app)
|
10
|
+
@app = app
|
11
|
+
logger.debug "Initializing worker #{id}"
|
12
|
+
@id = id
|
13
|
+
@to_io, @master = Kgio::Pipe.new.each { |io| io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def atfork_parent
|
17
|
+
logger.debug "Worker #{id} closing pipe to child"
|
18
|
+
@to_io = @to_io.close
|
19
|
+
end
|
20
|
+
|
21
|
+
def atfork_child
|
22
|
+
logger.debug "Worker #{id} closing pipe to master"
|
23
|
+
@master = @master.close
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
logger.debug "Establishing connection host: '#{config.host}', port: '#{config.port}'"
|
28
|
+
AMQP.start(host: config.host, port: config.port) do |connection|
|
29
|
+
app.reopen_logger
|
30
|
+
logger.debug "AMQP started with conneciton #{connection}"
|
31
|
+
initialize_channel!(connection)
|
32
|
+
initialize_exchanges!
|
33
|
+
initialize_subscribers!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def initialize_channel!(connection)
|
41
|
+
logger.debug 'Intitializing channel'
|
42
|
+
@channel = AMQP::Channel.new(connection)
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize_exchanges!
|
46
|
+
logger.debug 'Initializing exchanges'
|
47
|
+
@exchanges = {}
|
48
|
+
prefix = config.name
|
49
|
+
app.exchanges.each_key do |name|
|
50
|
+
logger.debug " Initializing #{name} exchange"
|
51
|
+
@exchanges[name] = channel.send(name, "#{prefix}.#{name}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize_subscribers!
|
56
|
+
logger.debug 'Initializing subscribers'
|
57
|
+
app.exchanges.each do |name, value|
|
58
|
+
logger.debug " Building subscribers for '#{name}' exchange"
|
59
|
+
value.each do |queue, block|
|
60
|
+
logger.debug " Initializing queue for '#{queue}'"
|
61
|
+
q = channel.queue(queue)
|
62
|
+
logger.debug " Binding queue to '#{name}' exchange"
|
63
|
+
q.bind(exchanges[name], routing_key: queue)
|
64
|
+
logger.debug " Subscribing to messages for '#{queue}'"
|
65
|
+
q.subscribe do |meta, payload|
|
66
|
+
block.call(MessagePack.unpack(payload))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
metadata
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kinetic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jarod Reid
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: confstruct
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: amqp
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: kgio
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: awesome_print
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: msgpack
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bunny
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: bundler
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.3'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rake
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: A powerful yet simple AMQP worker framework
|
140
|
+
email:
|
141
|
+
- jreid@voyst.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- .gitignore
|
147
|
+
- Gemfile
|
148
|
+
- LICENSE.txt
|
149
|
+
- README.md
|
150
|
+
- Rakefile
|
151
|
+
- examples/simple_worker.rb
|
152
|
+
- kinetic.gemspec
|
153
|
+
- lib/kinetic.rb
|
154
|
+
- lib/kinetic/base.rb
|
155
|
+
- lib/kinetic/cli.rb
|
156
|
+
- lib/kinetic/configuration.rb
|
157
|
+
- lib/kinetic/errors.rb
|
158
|
+
- lib/kinetic/master.rb
|
159
|
+
- lib/kinetic/publisher.rb
|
160
|
+
- lib/kinetic/version.rb
|
161
|
+
- lib/kinetic/worker.rb
|
162
|
+
homepage: ''
|
163
|
+
licenses:
|
164
|
+
- MIT
|
165
|
+
metadata: {}
|
166
|
+
post_install_message:
|
167
|
+
rdoc_options: []
|
168
|
+
require_paths:
|
169
|
+
- lib
|
170
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - '>='
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - '>='
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
requirements: []
|
181
|
+
rubyforge_project:
|
182
|
+
rubygems_version: 2.0.3
|
183
|
+
signing_key:
|
184
|
+
specification_version: 4
|
185
|
+
summary: A powerful yet simple AMQP worker framework
|
186
|
+
test_files: []
|
187
|
+
has_rdoc:
|