skein 0.3.7 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +4 -1
  3. data/Gemfile.lock +49 -36
  4. data/LICENSE.md +1 -1
  5. data/README.md +9 -4
  6. data/RELEASES.md +2 -0
  7. data/VERSION +1 -1
  8. data/bin/skein +1 -1
  9. data/examples/echo +66 -0
  10. data/examples/echo-server +77 -0
  11. data/lib/skein/adapter.rb +3 -0
  12. data/lib/skein/client/publisher.rb +10 -2
  13. data/lib/skein/client/rpc.rb +78 -19
  14. data/lib/skein/client/subscriber.rb +27 -4
  15. data/lib/skein/client/worker.rb +221 -63
  16. data/lib/skein/client.rb +20 -11
  17. data/lib/skein/config.rb +3 -1
  18. data/lib/skein/connected.rb +88 -17
  19. data/lib/skein/context.rb +5 -2
  20. data/lib/skein/handler/async.rb +6 -2
  21. data/lib/skein/handler.rb +131 -20
  22. data/lib/skein/rabbitmq.rb +1 -0
  23. data/lib/skein/timeout_queue.rb +43 -0
  24. data/lib/skein.rb +18 -2
  25. data/skein.gemspec +21 -24
  26. data/test/helper.rb +29 -0
  27. data/test/unit/test_skein_client.rb +4 -1
  28. data/test/unit/test_skein_client_publisher.rb +1 -1
  29. data/test/unit/test_skein_client_rpc.rb +37 -0
  30. data/test/unit/test_skein_client_subscriber.rb +29 -12
  31. data/test/unit/test_skein_client_worker.rb +22 -9
  32. data/test/unit/test_skein_connected.rb +21 -0
  33. data/test/unit/test_skein_rpc_timeout.rb +19 -0
  34. data/test/unit/test_skein_worker.rb +4 -0
  35. metadata +41 -16
  36. data/lib/skein/rpc/base.rb +0 -23
  37. data/lib/skein/rpc/error.rb +0 -34
  38. data/lib/skein/rpc/notification.rb +0 -2
  39. data/lib/skein/rpc/request.rb +0 -62
  40. data/lib/skein/rpc/response.rb +0 -38
  41. data/lib/skein/rpc.rb +0 -24
  42. data/test/unit/test_skein_rpc_error.rb +0 -10
  43. data/test/unit/test_skein_rpc_request.rb +0 -93
@@ -9,9 +9,12 @@ class TestSkeinClient < Test::Unit::TestCase
9
9
  client = Skein::Client.new
10
10
 
11
11
  assert client.context
12
+ assert_false client.connection_shared?
13
+
14
+ client&.close
12
15
 
13
16
  ensure
14
- client and client.close
17
+ client&.close
15
18
  end
16
19
  end
17
20
  end
@@ -5,6 +5,6 @@ class TestSkeinPublisher < Test::Unit::TestCase
5
5
  publisher = Skein::Client::Publisher.new('test_name')
6
6
 
7
7
  ensure
8
- publisher and publisher.close
8
+ publisher and publisher.close(delete_queue: true)
9
9
  end
10
10
  end
@@ -0,0 +1,37 @@
1
+ require_relative '../helper'
2
+
3
+ class ExampleWorker < Skein::Client::Worker
4
+ def echo(*args)
5
+ args
6
+ end
7
+
8
+ def pops_exception
9
+ invalid_code!
10
+ end
11
+ end
12
+
13
+ class TestSkeinPublisher < Test::Unit::TestCase
14
+ def setup
15
+ @test_queue = 'rpc_test_q'
16
+
17
+ @rpc = Skein::Client::RPC.new('', routing_key: @test_queue)
18
+ @worker = ExampleWorker.new(@test_queue)
19
+ end
20
+
21
+ def teardown
22
+ @rpc and @rpc.close
23
+ @worker and @worker.close
24
+ end
25
+
26
+ def test_can_echo
27
+ result = @rpc.echo('example')
28
+
29
+ assert_equal %w[ example ], result
30
+ end
31
+
32
+ def test_can_handle_exceptions
33
+ assert_raise_kind_of(NoMethodError) do
34
+ @rpc.pops_exception
35
+ end
36
+ end
37
+ end
@@ -1,6 +1,29 @@
1
1
  require_relative '../helper'
2
2
 
3
3
  class TestSkeinClientSubscriber < Test::Unit::TestCase
4
+ def test_immediate_close
5
+ client = Skein::Client.new
6
+
7
+ received = nil
8
+
9
+ subscriber = client.subscriber('test', '*.*')
10
+ subscribing = false
11
+
12
+ thread = in_thread do
13
+ subscribing = true
14
+
15
+ subscriber.listen do |payload|
16
+ received = payload
17
+ end
18
+ end
19
+
20
+ wait_for { subscribing }
21
+
22
+ ensure
23
+ subscriber and subscriber.close(delete_queue: true)
24
+ client and client.close
25
+ end
26
+
4
27
  def test_cycle
5
28
  client = Skein::Client.new
6
29
 
@@ -11,31 +34,25 @@ class TestSkeinClientSubscriber < Test::Unit::TestCase
11
34
  subscriber = client.subscriber('test', '*.*')
12
35
  subscribing = false
13
36
 
14
- thread = Thread.new do
15
- Thread.abort_on_exception = true
16
-
37
+ thread = in_thread do
17
38
  subscribing = true
18
39
 
19
40
  subscriber.listen do |payload|
20
41
  received = payload
21
-
22
- Thread.exit
23
42
  end
24
43
  end
25
44
 
26
- while (!subscribing)
27
- # Spin-lock to wait for the subscriber to come online
28
- end
45
+ wait_for { subscribing }
29
46
 
30
47
  publisher.publish!({ data: true }, 'test.notification')
31
48
 
32
- thread.join
49
+ wait_for { received }
33
50
 
34
- assert_equal({ "data" => true }, received)
51
+ assert_equal({ 'data' => true }, received)
35
52
 
36
53
  ensure
37
- publisher and publisher.close
38
- subscriber and subscriber.close
54
+ publisher and publisher.close(delete_queue: true)
55
+ subscriber and subscriber.close(delete_queue: true)
39
56
  client and client.close
40
57
  end
41
58
  end
@@ -11,8 +11,8 @@ class TestSkeinClientWorker < Test::Unit::TestCase
11
11
  end
12
12
 
13
13
  def test_example
14
- worker = Skein::Client::Worker.new('test_rpc')
15
- handler = Skein::Handler.for(worker)
14
+ worker = ErrorGenerator.new('test_rpc')
15
+ handler = worker.send(:handler)
16
16
 
17
17
  message = {
18
18
  method: 'ident',
@@ -20,12 +20,15 @@ class TestSkeinClientWorker < Test::Unit::TestCase
20
20
  id: '43d8352c-4907-4c32-9c81-fc34e91a3884'
21
21
  }
22
22
 
23
- handler.handle(JSON.dump(message)) do |response_json, error|
23
+ metrics = worker.send(:metrics_tracker)
24
+ state = worker.send(:state_tracker)
25
+
26
+ handler.handle(JSON.dump(message), metrics, state) do |response_json, error|
24
27
  response = JSON.load(response_json)
25
28
 
26
29
  expected = {
30
+ 'jsonrpc' => '2.0',
27
31
  'result' => worker.ident,
28
- 'error' => nil,
29
32
  'id' => message[:id]
30
33
  }
31
34
 
@@ -33,7 +36,7 @@ class TestSkeinClientWorker < Test::Unit::TestCase
33
36
  end
34
37
 
35
38
  ensure
36
- worker and worker.close
39
+ worker and worker.close(delete_queue: true)
37
40
  end
38
41
 
39
42
  def test_throws_exception
@@ -45,17 +48,27 @@ class TestSkeinClientWorker < Test::Unit::TestCase
45
48
  id: '29fe8a40-fccf-43c6-ba48-818598c66e6f'
46
49
  }
47
50
 
48
- handler.handle(JSON.dump(message)) do |response_json, error|
51
+ metrics = worker.send(:metrics_tracker)
52
+ state = worker.send(:state_tracker)
53
+
54
+ handler.handle(JSON.dump(message), metrics, state) do |response_json, error|
49
55
  expected = {
50
- 'result' => nil,
51
- 'error' => '[TestSkeinClientWorker::ErrorGenerator::CustomError] Example error!',
56
+ 'jsonrpc' => '2.0',
57
+ 'error' => {
58
+ 'code' => -32063,
59
+ 'message' => '[TestSkeinClientWorker::ErrorGenerator::CustomError] Example error!'
60
+ },
52
61
  'id' => message[:id]
53
62
  }
54
63
 
55
64
  assert_equal(expected.to_json, response_json)
65
+
66
+ assert_equal(1, metrics[:failed])
67
+ assert_equal(1, metrics[:errors][:exception])
68
+ assert(metrics[:time] >= 0, 'Time (%.3f) should be positive' % metrics[:time])
56
69
  end
57
70
 
58
71
  ensure
59
- worker and worker.close
72
+ worker and worker.close(delete_queue: true)
60
73
  end
61
74
  end
@@ -0,0 +1,21 @@
1
+ require_relative '../helper'
2
+
3
+ class TestSkeinConnected < Test::Unit::TestCase
4
+ def test_construct_with_defaults
5
+ connected = Skein::Connected.new
6
+
7
+ assert connected
8
+
9
+ assert connected.context
10
+ assert connected.ident
11
+ assert connected.connection
12
+ end
13
+
14
+ def test_construct_with_ident
15
+ ident = ('test-%s' % SecureRandom.uuid).freeze
16
+ connected = Skein::Connected.new(ident: ident)
17
+
18
+ assert connected
19
+ assert_equal ident, connected.ident
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ require_relative '../helper'
2
+
3
+ class TestSkeinRpcTimeout< Test::Unit::TestCase
4
+ def test_low_timeout
5
+ assert_raise Skein::TimeoutException do
6
+ client = Skein::Client.new
7
+
8
+ result = client.rpc('', routing_key: "test", timeout: 0.1).test
9
+ end
10
+ end
11
+
12
+ def test_short_timeout
13
+ assert_raise Skein::TimeoutException do
14
+ client = Skein::Client.new
15
+
16
+ result = client.rpc('', routing_key: "test", timeout: 2).test
17
+ end
18
+ end
19
+ end
@@ -19,6 +19,8 @@ class TestSkeinWorker < Test::Unit::TestCase
19
19
  assert_equal false, worker.async?
20
20
 
21
21
  ensure
22
+ worker and worker.close(delete_queue: true)
23
+
22
24
  client and client.close
23
25
  end
24
26
 
@@ -33,6 +35,8 @@ class TestSkeinWorker < Test::Unit::TestCase
33
35
  assert_equal true, worker.initialized
34
36
 
35
37
  ensure
38
+ worker and worker.close(delete_queue: true)
39
+
36
40
  client and client.close
37
41
  end
38
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skein
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Tadman
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-20 00:00:00.000000000 Z
11
+ date: 2020-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: birling
@@ -16,9 +16,37 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bunny
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: march_hare
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
22
50
  version_requirements: !ruby/object:Gem::Requirement
23
51
  requirements:
24
52
  - - ">="
@@ -86,6 +114,8 @@ files:
86
114
  - bin/skein
87
115
  - config/.gitignore
88
116
  - config/skein.yml.example
117
+ - examples/echo
118
+ - examples/echo-server
89
119
  - lib/skein.rb
90
120
  - lib/skein/adapter.rb
91
121
  - lib/skein/client.rb
@@ -101,27 +131,23 @@ files:
101
131
  - lib/skein/handler/threaded.rb
102
132
  - lib/skein/rabbitmq.rb
103
133
  - lib/skein/reporter.rb
104
- - lib/skein/rpc.rb
105
- - lib/skein/rpc/base.rb
106
- - lib/skein/rpc/error.rb
107
- - lib/skein/rpc/notification.rb
108
- - lib/skein/rpc/request.rb
109
- - lib/skein/rpc/response.rb
110
134
  - lib/skein/support.rb
135
+ - lib/skein/timeout_queue.rb
111
136
  - skein.gemspec
112
137
  - test/data/sample_config.yml
113
138
  - test/helper.rb
114
139
  - test/script/em_example
115
140
  - test/unit/test_skein_client.rb
116
141
  - test/unit/test_skein_client_publisher.rb
142
+ - test/unit/test_skein_client_rpc.rb
117
143
  - test/unit/test_skein_client_subscriber.rb
118
144
  - test/unit/test_skein_client_worker.rb
119
145
  - test/unit/test_skein_config.rb
146
+ - test/unit/test_skein_connected.rb
120
147
  - test/unit/test_skein_context.rb
121
148
  - test/unit/test_skein_rabbitmq.rb
122
149
  - test/unit/test_skein_reporter.rb
123
- - test/unit/test_skein_rpc_error.rb
124
- - test/unit/test_skein_rpc_request.rb
150
+ - test/unit/test_skein_rpc_timeout.rb
125
151
  - test/unit/test_skein_support.rb
126
152
  - test/unit/test_skein_worker.rb
127
153
  - tmp/.gitignore
@@ -129,7 +155,7 @@ homepage: http://github.com/postageapp/skein
129
155
  licenses:
130
156
  - MIT
131
157
  metadata: {}
132
- post_install_message:
158
+ post_install_message:
133
159
  rdoc_options: []
134
160
  require_paths:
135
161
  - lib
@@ -144,9 +170,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
170
  - !ruby/object:Gem::Version
145
171
  version: '0'
146
172
  requirements: []
147
- rubyforge_project:
148
- rubygems_version: 2.5.2
149
- signing_key:
173
+ rubygems_version: 3.2.15
174
+ signing_key:
150
175
  specification_version: 4
151
176
  summary: RabbitMQ RPC/PubSub Library
152
177
  test_files: []
@@ -1,23 +0,0 @@
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
@@ -1,34 +0,0 @@
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
@@ -1,2 +0,0 @@
1
- class Skein::RPC::Notification < Skein::RPC::Base
2
- end
@@ -1,62 +0,0 @@
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