skein 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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