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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +69 -0
  4. data/README.md +57 -0
  5. data/RELEASES.md +4 -0
  6. data/Rakefile +30 -0
  7. data/VERSION +1 -0
  8. data/bin/skein +186 -0
  9. data/config/.gitignore +3 -0
  10. data/config/skein.yml.example +11 -0
  11. data/lib/skein.rb +24 -0
  12. data/lib/skein/client.rb +51 -0
  13. data/lib/skein/client/publisher.rb +14 -0
  14. data/lib/skein/client/rpc.rb +96 -0
  15. data/lib/skein/client/subscriber.rb +25 -0
  16. data/lib/skein/client/worker.rb +51 -0
  17. data/lib/skein/config.rb +87 -0
  18. data/lib/skein/connected.rb +52 -0
  19. data/lib/skein/context.rb +38 -0
  20. data/lib/skein/handler.rb +86 -0
  21. data/lib/skein/handler/async.rb +9 -0
  22. data/lib/skein/handler/threaded.rb +7 -0
  23. data/lib/skein/rabbitmq.rb +44 -0
  24. data/lib/skein/reporter.rb +11 -0
  25. data/lib/skein/rpc.rb +24 -0
  26. data/lib/skein/rpc/base.rb +23 -0
  27. data/lib/skein/rpc/error.rb +34 -0
  28. data/lib/skein/rpc/notification.rb +2 -0
  29. data/lib/skein/rpc/request.rb +62 -0
  30. data/lib/skein/rpc/response.rb +38 -0
  31. data/lib/skein/support.rb +67 -0
  32. data/skein.gemspec +95 -0
  33. data/test/data/sample_config.yml +13 -0
  34. data/test/helper.rb +42 -0
  35. data/test/script/em_example +28 -0
  36. data/test/unit/test_skein_client.rb +18 -0
  37. data/test/unit/test_skein_client_publisher.rb +10 -0
  38. data/test/unit/test_skein_client_subscriber.rb +41 -0
  39. data/test/unit/test_skein_client_worker.rb +61 -0
  40. data/test/unit/test_skein_config.rb +33 -0
  41. data/test/unit/test_skein_context.rb +44 -0
  42. data/test/unit/test_skein_rabbitmq.rb +14 -0
  43. data/test/unit/test_skein_reporter.rb +4 -0
  44. data/test/unit/test_skein_rpc_error.rb +10 -0
  45. data/test/unit/test_skein_rpc_request.rb +93 -0
  46. data/test/unit/test_skein_support.rb +95 -0
  47. metadata +148 -0
@@ -0,0 +1,9 @@
1
+ class Skein::Handler::Async < Skein::Handler
2
+ # == Instance Methods =====================================================
3
+
4
+ def delegate(*args)
5
+ @target.send(*args) do |response, error|
6
+ yield(response, error)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ class Skein::Handler::Threaded < Skein::Handler
2
+ # == Instance Methods =====================================================
3
+
4
+ def delegate(*args)
5
+ yield(@target.send(*args))
6
+ end
7
+ end
@@ -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
@@ -0,0 +1,11 @@
1
+ class Skein::Reporter
2
+ # == Instance Methods =====================================================
3
+
4
+ def initialize
5
+ @logger = Birling.new
6
+ end
7
+
8
+ def exception!(e, *meta)
9
+ # ...
10
+ end
11
+ 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,2 @@
1
+ class Skein::RPC::Notification < Skein::RPC::Base
2
+ 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
+
@@ -0,0 +1,13 @@
1
+ development:
2
+ host: dev.host
3
+ port: 25672
4
+ username: dev_user
5
+ password: dev_password
6
+ namespace: example
7
+
8
+ test:
9
+ host: test.host
10
+ port: 5670
11
+ username: test_user
12
+ password: test_password
13
+ namespace: test