skein 0.3.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 +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
|
+
|