skein 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +69 -0
- data/README.md +57 -0
- data/RELEASES.md +4 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/bin/skein +186 -0
- data/config/.gitignore +3 -0
- data/config/skein.yml.example +11 -0
- data/lib/skein.rb +24 -0
- data/lib/skein/client.rb +51 -0
- data/lib/skein/client/publisher.rb +14 -0
- data/lib/skein/client/rpc.rb +96 -0
- data/lib/skein/client/subscriber.rb +25 -0
- data/lib/skein/client/worker.rb +51 -0
- data/lib/skein/config.rb +87 -0
- data/lib/skein/connected.rb +52 -0
- data/lib/skein/context.rb +38 -0
- data/lib/skein/handler.rb +86 -0
- data/lib/skein/handler/async.rb +9 -0
- data/lib/skein/handler/threaded.rb +7 -0
- data/lib/skein/rabbitmq.rb +44 -0
- data/lib/skein/reporter.rb +11 -0
- data/lib/skein/rpc.rb +24 -0
- data/lib/skein/rpc/base.rb +23 -0
- data/lib/skein/rpc/error.rb +34 -0
- data/lib/skein/rpc/notification.rb +2 -0
- data/lib/skein/rpc/request.rb +62 -0
- data/lib/skein/rpc/response.rb +38 -0
- data/lib/skein/support.rb +67 -0
- data/skein.gemspec +95 -0
- data/test/data/sample_config.yml +13 -0
- data/test/helper.rb +42 -0
- data/test/script/em_example +28 -0
- data/test/unit/test_skein_client.rb +18 -0
- data/test/unit/test_skein_client_publisher.rb +10 -0
- data/test/unit/test_skein_client_subscriber.rb +41 -0
- data/test/unit/test_skein_client_worker.rb +61 -0
- data/test/unit/test_skein_config.rb +33 -0
- data/test/unit/test_skein_context.rb +44 -0
- data/test/unit/test_skein_rabbitmq.rb +14 -0
- data/test/unit/test_skein_reporter.rb +4 -0
- data/test/unit/test_skein_rpc_error.rb +10 -0
- data/test/unit/test_skein_rpc_request.rb +93 -0
- data/test/unit/test_skein_support.rb +95 -0
- metadata +148 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
module Skein::RabbitMQ
|
2
|
+
# == Exceptions ===========================================================
|
3
|
+
|
4
|
+
class MissingDriver < RuntimeError
|
5
|
+
end
|
6
|
+
|
7
|
+
# == Module Methods =======================================================
|
8
|
+
|
9
|
+
def self.force_require!(config = nil)
|
10
|
+
config ||= Skein.config
|
11
|
+
|
12
|
+
case (config.driver.to_s)
|
13
|
+
when 'bunny', 'rubybunny'
|
14
|
+
unless (defined?(Bunny))
|
15
|
+
require 'bunny'
|
16
|
+
end
|
17
|
+
when 'march_hare', 'marchhare'
|
18
|
+
unless (defined?(MarchHare))
|
19
|
+
require 'march_hare'
|
20
|
+
end
|
21
|
+
else
|
22
|
+
raise MissingDriver, 'Missing or invalid configuration for: driver'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.connect(config = nil)
|
27
|
+
config ||= Skein.config
|
28
|
+
|
29
|
+
self.force_require!(config)
|
30
|
+
|
31
|
+
case (config.driver.to_s)
|
32
|
+
when 'bunny', 'rubybunny'
|
33
|
+
bunny = Bunny.new(config.to_h)
|
34
|
+
|
35
|
+
bunny.start
|
36
|
+
|
37
|
+
bunny
|
38
|
+
when 'march_hare', 'marchhare'
|
39
|
+
MarchHare.connect(config.to_h)
|
40
|
+
else
|
41
|
+
raise MissingDriver, 'Missing or invalid configuration for: driver'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/skein/rpc.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class Skein::RPC
|
2
|
+
class Exception < ::RuntimeError
|
3
|
+
attr_accessor :request
|
4
|
+
|
5
|
+
def to_error
|
6
|
+
Skein::RPC::Error.new(
|
7
|
+
error: '[%s] %s' % [ self.class, self.to_s ],
|
8
|
+
id: self.request ? self.request.id : nil
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class InvalidPayload < Exception
|
14
|
+
end
|
15
|
+
|
16
|
+
class InvalidMethod < Exception
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require_relative './rpc/base'
|
21
|
+
require_relative './rpc/error'
|
22
|
+
require_relative './rpc/request'
|
23
|
+
require_relative './rpc/response'
|
24
|
+
require_relative './rpc/notification'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Skein::RPC::Base
|
4
|
+
# == Exceptions ===========================================================
|
5
|
+
|
6
|
+
# == Properties ===========================================================
|
7
|
+
|
8
|
+
attr_accessor :id
|
9
|
+
|
10
|
+
# == Instance Methods =====================================================
|
11
|
+
|
12
|
+
def to_h
|
13
|
+
{
|
14
|
+
id: self.id
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json
|
19
|
+
JSON.dump(
|
20
|
+
self.to_h
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Skein::RPC::Error < Skein::RPC::Base
|
2
|
+
# == Properties ===========================================================
|
3
|
+
|
4
|
+
attr_accessor :error
|
5
|
+
|
6
|
+
# == Instance Methods =====================================================
|
7
|
+
|
8
|
+
def initialize(content = nil)
|
9
|
+
case (content)
|
10
|
+
when String
|
11
|
+
self.error = content
|
12
|
+
when Hash
|
13
|
+
self.assign_from_hash!(content)
|
14
|
+
when nil
|
15
|
+
# Defaults
|
16
|
+
else
|
17
|
+
raise Skein::RPC::Exception, 'Invalid type: %s' % content.class
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.to_h
|
22
|
+
{
|
23
|
+
result: nil,
|
24
|
+
error: self.error,
|
25
|
+
id: self.id
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
def assign_from_hash!(hash)
|
31
|
+
self.error = hash[:error]
|
32
|
+
self.id = hash[:id]
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class Skein::RPC::Request < Skein::RPC::Base
|
2
|
+
# == Properties ===========================================================
|
3
|
+
|
4
|
+
attr_accessor :method
|
5
|
+
attr_accessor :params
|
6
|
+
|
7
|
+
# == Instance Methods =====================================================
|
8
|
+
|
9
|
+
def initialize(content = nil)
|
10
|
+
case (content)
|
11
|
+
when String
|
12
|
+
data = Skein::Support.symbolize_keys(JSON.load(content))
|
13
|
+
|
14
|
+
assign_from_hash!(data)
|
15
|
+
when Hash
|
16
|
+
assign_from_hash!(content)
|
17
|
+
when nil
|
18
|
+
self.id = SecureRandom.uuid
|
19
|
+
else
|
20
|
+
raise Skein::RPC::InvalidPayload, 'Invalid payload type: %s' % content.class
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
{
|
26
|
+
method: self.method,
|
27
|
+
params: self.params,
|
28
|
+
id: self.id
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def response(result: nil, error: nil)
|
33
|
+
if (result)
|
34
|
+
Skein::RPC::Response.new(
|
35
|
+
result: result,
|
36
|
+
id: self.id
|
37
|
+
)
|
38
|
+
elsif (error)
|
39
|
+
Skein::RPC::Error.new(
|
40
|
+
error: error,
|
41
|
+
id: self.id
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
def assign_from_hash!(hash)
|
48
|
+
self.method = hash[:method]
|
49
|
+
self.params = Skein::Support.arrayify(hash[:params])
|
50
|
+
self.id = hash[:id]
|
51
|
+
|
52
|
+
case (self.method)
|
53
|
+
when String
|
54
|
+
unless (self.method.match(/\A\w+\z/))
|
55
|
+
e = Skein::RPC::InvalidMethod.new('%s is not a valid RPC method name.' % self.method.inspect)
|
56
|
+
e.request = self
|
57
|
+
|
58
|
+
raise e
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Skein::RPC::Response < Skein::RPC::Base
|
2
|
+
# == Properties ===========================================================
|
3
|
+
|
4
|
+
attr_accessor :result
|
5
|
+
attr_accessor :error
|
6
|
+
|
7
|
+
# == Instance Methods =====================================================
|
8
|
+
|
9
|
+
def initialize(content = nil)
|
10
|
+
case (content)
|
11
|
+
when String
|
12
|
+
data = Skein::Support.symbolize_keys(JSON.load(content))
|
13
|
+
|
14
|
+
assign_from_hash!(data)
|
15
|
+
when Hash
|
16
|
+
assign_from_hash!(content)
|
17
|
+
when nil
|
18
|
+
self.id = SecureRandom.uuid
|
19
|
+
else
|
20
|
+
raise Skein::RPC::InvalidPayload, 'Invalid payload type: %s' % content.class
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
{
|
26
|
+
method: self.method,
|
27
|
+
params: self.params,
|
28
|
+
id: self.id
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
def assign_from_hash!(hash)
|
34
|
+
self.result = hash[:result]
|
35
|
+
self.error = hash[:error]
|
36
|
+
self.id = hash[:id]
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Skein::Support
|
4
|
+
# == Module Methods =======================================================
|
5
|
+
|
6
|
+
def self.hostname
|
7
|
+
Socket.gethostname
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.process_name
|
11
|
+
$0.split(/\s/).first.split('/').last.sub(/\.rb\z/, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.process_id
|
15
|
+
Process.pid
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.arrayify(value)
|
19
|
+
case (value)
|
20
|
+
when nil
|
21
|
+
nil
|
22
|
+
when Array
|
23
|
+
value
|
24
|
+
else
|
25
|
+
[ value ]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.hash_format(hash, width: nil)
|
30
|
+
hash = hash.to_h
|
31
|
+
|
32
|
+
width ||= hash.keys.map(&:length).sort[-1].to_i + 1
|
33
|
+
|
34
|
+
template = "%%-%ds %%s" % [ width ]
|
35
|
+
|
36
|
+
hash.map do |pair|
|
37
|
+
template % pair
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.symbolize_keys(hash)
|
42
|
+
case (hash)
|
43
|
+
when Hash
|
44
|
+
Hash[
|
45
|
+
hash.map do |k,v|
|
46
|
+
[
|
47
|
+
k.to_s.to_sym,
|
48
|
+
case (v)
|
49
|
+
when Hash
|
50
|
+
symbolize_keys(v)
|
51
|
+
when Array
|
52
|
+
v.map { |e| symbolize_keys(e) }
|
53
|
+
else
|
54
|
+
v
|
55
|
+
end
|
56
|
+
]
|
57
|
+
end
|
58
|
+
]
|
59
|
+
when Array
|
60
|
+
hash.map do |h|
|
61
|
+
symbolize_keys(h)
|
62
|
+
end
|
63
|
+
else
|
64
|
+
hash
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/skein.gemspec
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: skein 0.3.0 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "skein".freeze
|
9
|
+
s.version = "0.3.0"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["Scott Tadman".freeze]
|
14
|
+
s.date = "2016-12-07"
|
15
|
+
s.description = "Wrapper for RabbitMQ that makes blocking RPC calls and handles pub-sub broadcasts.".freeze
|
16
|
+
s.email = "tadman@postageapp.com".freeze
|
17
|
+
s.executables = ["skein".freeze]
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"README.md",
|
25
|
+
"RELEASES.md",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/skein",
|
29
|
+
"config/.gitignore",
|
30
|
+
"config/skein.yml.example",
|
31
|
+
"lib/skein.rb",
|
32
|
+
"lib/skein/client.rb",
|
33
|
+
"lib/skein/client/publisher.rb",
|
34
|
+
"lib/skein/client/rpc.rb",
|
35
|
+
"lib/skein/client/subscriber.rb",
|
36
|
+
"lib/skein/client/worker.rb",
|
37
|
+
"lib/skein/config.rb",
|
38
|
+
"lib/skein/connected.rb",
|
39
|
+
"lib/skein/context.rb",
|
40
|
+
"lib/skein/handler.rb",
|
41
|
+
"lib/skein/handler/async.rb",
|
42
|
+
"lib/skein/handler/threaded.rb",
|
43
|
+
"lib/skein/rabbitmq.rb",
|
44
|
+
"lib/skein/reporter.rb",
|
45
|
+
"lib/skein/rpc.rb",
|
46
|
+
"lib/skein/rpc/base.rb",
|
47
|
+
"lib/skein/rpc/error.rb",
|
48
|
+
"lib/skein/rpc/notification.rb",
|
49
|
+
"lib/skein/rpc/request.rb",
|
50
|
+
"lib/skein/rpc/response.rb",
|
51
|
+
"lib/skein/support.rb",
|
52
|
+
"skein.gemspec",
|
53
|
+
"test/data/sample_config.yml",
|
54
|
+
"test/helper.rb",
|
55
|
+
"test/script/em_example",
|
56
|
+
"test/unit/test_skein_client.rb",
|
57
|
+
"test/unit/test_skein_client_publisher.rb",
|
58
|
+
"test/unit/test_skein_client_subscriber.rb",
|
59
|
+
"test/unit/test_skein_client_worker.rb",
|
60
|
+
"test/unit/test_skein_config.rb",
|
61
|
+
"test/unit/test_skein_context.rb",
|
62
|
+
"test/unit/test_skein_rabbitmq.rb",
|
63
|
+
"test/unit/test_skein_reporter.rb",
|
64
|
+
"test/unit/test_skein_rpc_error.rb",
|
65
|
+
"test/unit/test_skein_rpc_request.rb",
|
66
|
+
"test/unit/test_skein_support.rb",
|
67
|
+
"tmp/.gitignore"
|
68
|
+
]
|
69
|
+
s.homepage = "http://github.com/postageapp/skein".freeze
|
70
|
+
s.licenses = ["closed".freeze]
|
71
|
+
s.rubygems_version = "2.6.8".freeze
|
72
|
+
s.summary = "RabbitMQ RPC/PubSub Library".freeze
|
73
|
+
|
74
|
+
if s.respond_to? :specification_version then
|
75
|
+
s.specification_version = 4
|
76
|
+
|
77
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
78
|
+
s.add_runtime_dependency(%q<birling>.freeze, [">= 0"])
|
79
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
80
|
+
s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
|
81
|
+
s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
|
82
|
+
else
|
83
|
+
s.add_dependency(%q<birling>.freeze, [">= 0"])
|
84
|
+
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
85
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
86
|
+
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
87
|
+
end
|
88
|
+
else
|
89
|
+
s.add_dependency(%q<birling>.freeze, [">= 0"])
|
90
|
+
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
91
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
92
|
+
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|