bertrpc 0.2.0 → 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.
data/README.md CHANGED
@@ -17,21 +17,43 @@ BERTRPC is a Ruby BERT-RPC client library.
17
17
  Installation
18
18
  ------------
19
19
 
20
- gem install mojombo-bertrpc -s http://gems.github.com
20
+ From GemCutter:
21
21
 
22
+ gem install bertrpc
22
23
 
23
- Example
24
- -------
24
+ From GitHub:
25
+
26
+ gem install mojombo-bertrpc -s http://gems.github.com \
27
+ -s http://gemcutter.org
28
+
29
+
30
+ Examples
31
+ --------
32
+
33
+ Require the library and create a service:
25
34
 
26
35
  require 'bertrpc'
27
-
28
36
  svc = BERTRPC::Service.new('localhost', 9999)
37
+
38
+ Make a call:
39
+
29
40
  svc.call.calc.add(1, 2)
30
41
  # => 3
31
42
 
32
- This generates a BERT-RPC request like so:
43
+ The underlying BERT-RPC transaction of the above call is:
33
44
 
34
45
  -> {call, calc, add, [1, 2]}
46
+ <- {reply, 3}
47
+
48
+ Make a cast:
49
+
50
+ svc.cast.stats.incr
51
+ # => nil
52
+
53
+ The underlying BERT-RPC transaction of the above cast is:
54
+
55
+ -> {cast, stats, incr, []}
56
+ <- {noreply}
35
57
 
36
58
 
37
59
  Copyright
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/bertrpc.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{bertrpc}
5
- s.version = "0.2.0"
5
+ s.version = "0.3.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Tom Preston-Werner"]
9
- s.date = %q{2009-08-13}
9
+ s.date = %q{2009-09-05}
10
10
  s.email = %q{tom@mojombo.com}
11
11
  s.extra_rdoc_files = [
12
12
  "LICENSE",
@@ -21,16 +21,16 @@ Gem::Specification.new do |s|
21
21
  "VERSION",
22
22
  "bertrpc.gemspec",
23
23
  "lib/bertrpc.rb",
24
- "lib/bertrpc/call.rb",
25
- "lib/bertrpc/call_proxy.rb",
24
+ "lib/bertrpc/action.rb",
26
25
  "lib/bertrpc/encodes.rb",
27
26
  "lib/bertrpc/errors.rb",
28
27
  "lib/bertrpc/mod.rb",
28
+ "lib/bertrpc/request.rb",
29
29
  "lib/bertrpc/service.rb",
30
- "test/call_proxy_test.rb",
31
- "test/call_test.rb",
30
+ "test/action_test.rb",
32
31
  "test/encodes_test.rb",
33
32
  "test/mod_test.rb",
33
+ "test/request_test.rb",
34
34
  "test/service_test.rb",
35
35
  "test/test_helper.rb"
36
36
  ]
@@ -40,10 +40,10 @@ Gem::Specification.new do |s|
40
40
  s.rubygems_version = %q{1.3.5}
41
41
  s.summary = %q{BERTRPC is a Ruby BERT-RPC client library.}
42
42
  s.test_files = [
43
- "test/call_proxy_test.rb",
44
- "test/call_test.rb",
43
+ "test/action_test.rb",
45
44
  "test/encodes_test.rb",
46
45
  "test/mod_test.rb",
46
+ "test/request_test.rb",
47
47
  "test/service_test.rb",
48
48
  "test/test_helper.rb"
49
49
  ]
@@ -0,0 +1,47 @@
1
+ module BERTRPC
2
+ class Action
3
+ include Encodes
4
+
5
+ def initialize(svc, req, mod, fun, args)
6
+ @svc = svc
7
+ @req = req
8
+ @mod = mod
9
+ @fun = fun
10
+ @args = args
11
+ end
12
+
13
+ def execute
14
+ bert_request = encode_ruby_request([@req.kind, @mod, @fun, @args])
15
+ bert_response = transaction(bert_request)
16
+ decode_bert_response(bert_response)
17
+ end
18
+
19
+ #private
20
+
21
+ def write(sock, bert)
22
+ sock.write([bert.length].pack("N"))
23
+ sock.write(bert)
24
+ end
25
+
26
+ def transaction(bert_request)
27
+ sock = TCPSocket.new(@svc.host, @svc.port)
28
+
29
+ if @req.options
30
+ if @req.options[:cache] && @req.options[:cache][0] == :validation
31
+ token = @req.options[:cache][1]
32
+ info_bert = encode_ruby_request([:info, :cache, [:validation, token]])
33
+ write(sock, info_bert)
34
+ end
35
+ end
36
+
37
+ write(sock, bert_request)
38
+ lenheader = sock.read(4)
39
+ raise ProtocolError.new("Unable to read length header from server.") unless lenheader
40
+ len = lenheader.unpack('N').first
41
+ bert_response = sock.read(len)
42
+ raise ProtocolError.new("Unable to read data from server.") unless bert_response
43
+ sock.close
44
+ bert_response
45
+ end
46
+ end
47
+ end
@@ -10,6 +10,8 @@ module BERTRPC
10
10
  case ruby_response[0]
11
11
  when :reply
12
12
  deconvert(ruby_response[1])
13
+ when :noreply
14
+ nil
13
15
  when :error
14
16
  error(ruby_response[1])
15
17
  else
@@ -18,4 +18,8 @@ module BERTRPC
18
18
  class ProxyError < BERTRPCError
19
19
 
20
20
  end
21
+
22
+ class InvalidOption < BERTRPCError
23
+
24
+ end
21
25
  end
data/lib/bertrpc/mod.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  module BERTRPC
2
2
  class Mod
3
- def initialize(svc, type, mod)
3
+ def initialize(svc, req, mod)
4
4
  @svc = svc
5
- @type = type
5
+ @req = req
6
6
  @mod = mod
7
7
  end
8
8
 
9
9
  def method_missing(cmd, *args)
10
10
  args = [*args]
11
- @type.new(@svc, @mod, cmd, args).execute
11
+ Action.new(@svc, @req, @mod, cmd, args).execute
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,15 @@
1
+ module BERTRPC
2
+ class Request
3
+ attr_accessor :kind, :options
4
+
5
+ def initialize(svc, kind, options)
6
+ @svc = svc
7
+ @kind = kind
8
+ @options = options
9
+ end
10
+
11
+ def method_missing(cmd, *args)
12
+ Mod.new(@svc, self, cmd)
13
+ end
14
+ end
15
+ end
@@ -7,8 +7,28 @@ module BERTRPC
7
7
  @port = port
8
8
  end
9
9
 
10
- def call
11
- CallProxy.new(self)
10
+ def call(options = nil)
11
+ verify_options(options)
12
+ Request.new(self, :call, options)
13
+ end
14
+
15
+ def cast(options = nil)
16
+ verify_options(options)
17
+ Request.new(self, :cast, options)
18
+ end
19
+
20
+ # private
21
+
22
+ def verify_options(options)
23
+ if options
24
+ if cache = options[:cache]
25
+ unless cache[0] == :validation && cache[1].is_a?(String)
26
+ raise InvalidOption.new("Valid :cache args are [:validation, String]")
27
+ end
28
+ else
29
+ raise InvalidOption.new("Valid options are :cache")
30
+ end
31
+ end
12
32
  end
13
33
  end
14
34
  end
data/lib/bertrpc.rb CHANGED
@@ -2,8 +2,8 @@ require 'erlectricity'
2
2
  require 'socket'
3
3
 
4
4
  require 'bertrpc/service'
5
- require 'bertrpc/call_proxy'
5
+ require 'bertrpc/request'
6
6
  require 'bertrpc/mod'
7
7
  require 'bertrpc/encodes'
8
- require 'bertrpc/call'
8
+ require 'bertrpc/action'
9
9
  require 'bertrpc/errors'
@@ -1,50 +1,53 @@
1
1
  require 'test_helper'
2
2
 
3
- class CallTest < Test::Unit::TestCase
4
- context "A Call" do
3
+ class ActionTest < Test::Unit::TestCase
4
+ context "An Action" do
5
5
  setup do
6
6
  @svc = BERTRPC::Service.new('localhost', 9941)
7
+ @req = @svc.call
7
8
  end
8
9
 
9
10
  should "be created with a Service, module name, fun name, and args" do
10
- assert BERTRPC::Call.new(@svc, :mymod, :myfun, [1, 2]).is_a?(BERTRPC::Call)
11
+ assert BERTRPC::Action.new(@svc, @req, :mymod, :myfun, [1, 2]).is_a?(BERTRPC::Action)
11
12
  end
12
13
  end
13
14
 
14
- context "A Call instance" do
15
+ context "An Action instance" do
15
16
  setup do
16
17
  @svc = BERTRPC::Service.new('localhost', 9941)
18
+ @req = @svc.call
17
19
  @enc = Enc.new
18
20
  end
19
21
 
20
22
  should "call with single-arity" do
21
23
  req = @enc.encode_ruby_request([:call, :mymod, :myfun, [1]])
22
24
  res = @enc.encode_ruby_request([:reply, 2])
23
- call = BERTRPC::Call.new(@svc, :mymod, :myfun, [1])
24
- call.expects(:sync_request).with(req).returns(res)
25
+ call = BERTRPC::Action.new(@svc, @req, :mymod, :myfun, [1])
26
+ call.expects(:transaction).with(req).returns(res)
25
27
  assert_equal 2, call.execute
26
28
  end
27
29
 
28
30
  should "call with single-arity array" do
29
31
  req = @enc.encode_ruby_request([:call, :mymod, :myfun, [[1, 2, 3]]])
30
32
  res = @enc.encode_ruby_request([:reply, [4, 5, 6]])
31
- call = BERTRPC::Call.new(@svc, :mymod, :myfun, [[1, 2, 3]])
32
- call.expects(:sync_request).with(req).returns(res)
33
+ call = BERTRPC::Action.new(@svc, @req, :mymod, :myfun, [[1, 2, 3]])
34
+ call.expects(:transaction).with(req).returns(res)
33
35
  assert_equal [4, 5, 6], call.execute
34
36
  end
35
37
 
36
38
  should "call with multi-arity" do
37
39
  req = @enc.encode_ruby_request([:call, :mymod, :myfun, [1, 2, 3]])
38
40
  res = @enc.encode_ruby_request([:reply, [4, 5, 6]])
39
- call = BERTRPC::Call.new(@svc, :mymod, :myfun, [1, 2, 3])
40
- call.expects(:sync_request).with(req).returns(res)
41
+ call = BERTRPC::Action.new(@svc, @req, :mymod, :myfun, [1, 2, 3])
42
+ call.expects(:transaction).with(req).returns(res)
41
43
  assert_equal [4, 5, 6], call.execute
42
44
  end
43
45
 
44
46
  context "sync_request" do
45
47
  setup do
46
48
  @svc = BERTRPC::Service.new('localhost', 9941)
47
- @call = BERTRPC::Call.new(@svc, :mymod, :myfun, [])
49
+ @req = @svc.call
50
+ @call = BERTRPC::Action.new(@svc, @req, :mymod, :myfun, [])
48
51
  end
49
52
 
50
53
  should "read and write BERT-Ps from the socket" do
@@ -55,7 +58,7 @@ class CallTest < Test::Unit::TestCase
55
58
  io.expects(:read).with(3).returns("bar")
56
59
  io.expects(:close)
57
60
  TCPSocket.expects(:new).returns(io)
58
- assert_equal "bar", @call.sync_request("foo")
61
+ assert_equal "bar", @call.transaction("foo")
59
62
  end
60
63
 
61
64
  should "raise a ProtocolError when the length is invalid" do
@@ -65,7 +68,7 @@ class CallTest < Test::Unit::TestCase
65
68
  io.expects(:read).with(4).returns(nil)
66
69
  TCPSocket.expects(:new).returns(io)
67
70
  assert_raises(BERTRPC::ProtocolError) do
68
- @call.sync_request("foo")
71
+ @call.transaction("foo")
69
72
  end
70
73
  end
71
74
 
@@ -77,7 +80,7 @@ class CallTest < Test::Unit::TestCase
77
80
  io.expects(:read).with(3).returns(nil)
78
81
  TCPSocket.expects(:new).returns(io)
79
82
  assert_raises(BERTRPC::ProtocolError) do
80
- @call.sync_request("foo")
83
+ @call.transaction("foo")
81
84
  end
82
85
  end
83
86
  end
data/test/encodes_test.rb CHANGED
@@ -8,7 +8,10 @@ class EncodesTest < Test::Unit::TestCase
8
8
 
9
9
  context "converter" do
10
10
  should "convert top level hashes to BERT-RPC dict form" do
11
- assert_equal([:dict, [:foo, 1], [:bar, 2]], @enc.convert({:foo => 1, :bar => 2}))
11
+ arr = @enc.convert({:foo => 1, :bar => 2})
12
+ a = [:dict, [:foo, 1], [:bar, 2]] == arr
13
+ b = [:dict, [:bar, 2], [:foo, 1]] == arr
14
+ assert(a || b)
12
15
  end
13
16
 
14
17
  should "convert nested hashes in the same way" do
@@ -33,21 +36,27 @@ class EncodesTest < Test::Unit::TestCase
33
36
  assert_equal [1, 2, "foo", :bar, 3.14], @enc.deconvert([1, 2, "foo", :bar, 3.14])
34
37
  end
35
38
  end
36
-
39
+
37
40
  context "ruby request encoder" do
38
41
  should "return BERT-RPC encoded request" do
39
42
  bert = "\203h\004d\000\004calld\000\005mymodd\000\005myfunh\003a\001a\002a\003"
40
43
  assert_equal bert, @enc.encode_ruby_request([:call, :mymod, :myfun, [1, 2, 3]])
41
44
  end
42
45
  end
43
-
46
+
44
47
  context "bert response decoder" do
45
- should "return response when successful" do
48
+ should "return response when reply" do
46
49
  req = @enc.encode_ruby_request([:reply, [1, 2, 3]])
47
50
  res = @enc.decode_bert_response(req)
48
51
  assert_equal [1, 2, 3], res
49
52
  end
50
53
 
54
+ should "return nil when noreply" do
55
+ req = @enc.encode_ruby_request([:noreply])
56
+ res = @enc.decode_bert_response(req)
57
+ assert_equal nil, res
58
+ end
59
+
51
60
  should "raise a ProtocolError error when protocol level error is returned" do
52
61
  req = @enc.encode_ruby_request([:error, [:protocol, 1, "invalid"]])
53
62
  assert_raises(BERTRPC::ProtocolError) do
data/test/mod_test.rb CHANGED
@@ -4,26 +4,28 @@ class ModTest < Test::Unit::TestCase
4
4
  context "A Mod" do
5
5
  setup do
6
6
  @svc = BERTRPC::Service.new('localhost', 9941)
7
+ @req = @svc.call
7
8
  end
8
9
 
9
- should "be created with a Service and type and module name" do
10
- assert BERTRPC::Mod.new(@svc, BERTRPC::Call, :mymod).is_a?(BERTRPC::Mod)
10
+ should "be created with a Service, request and module name" do
11
+ assert BERTRPC::Mod.new(@svc, @req, :mymod).is_a?(BERTRPC::Mod)
11
12
  end
12
13
  end
13
14
 
14
15
  context "A Mod instance" do
15
16
  setup do
16
17
  @svc = BERTRPC::Service.new('localhost', 9941)
17
- @mod = BERTRPC::Mod.new(@svc, BERTRPC::Call, :mymod)
18
+ @req = @svc.call
19
+ @mod = BERTRPC::Mod.new(@svc, @req, :mymod)
18
20
  end
19
21
 
20
22
  should "call execute on the type" do
21
23
  m = mock(:execute => nil)
22
- BERTRPC::Call.expects(:new).with(@svc, :mymod, :myfun, [1, 2, 3]).returns(m)
24
+ BERTRPC::Action.expects(:new).with(@svc, @req, :mymod, :myfun, [1, 2, 3]).returns(m)
23
25
  @mod.myfun(1, 2, 3)
24
-
26
+
25
27
  m = mock(:execute => nil)
26
- BERTRPC::Call.expects(:new).with(@svc, :mymod, :myfun, [1]).returns(m)
28
+ BERTRPC::Action.expects(:new).with(@svc, @req, :mymod, :myfun, [1]).returns(m)
27
29
  @mod.myfun(1)
28
30
  end
29
31
  end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class RequestTest < Test::Unit::TestCase
4
+ context "A Request" do
5
+ setup do
6
+ @svc = BERTRPC::Service.new('localhost', 9941)
7
+ end
8
+
9
+ should "be created with a Service and type" do
10
+ assert BERTRPC::Request.new(@svc, :call, nil).is_a?(BERTRPC::Request)
11
+ end
12
+ end
13
+
14
+ context "A Request instance" do
15
+ setup do
16
+ svc = BERTRPC::Service.new('localhost', 9941)
17
+ @req = BERTRPC::Request.new(@svc, :call, nil)
18
+ end
19
+
20
+ should "return a Mod instance" do
21
+ assert @req.myfun.is_a?(BERTRPC::Mod)
22
+ end
23
+ end
24
+ end
data/test/service_test.rb CHANGED
@@ -8,21 +8,35 @@ class ServiceTest < Test::Unit::TestCase
8
8
  end
9
9
  end
10
10
 
11
- context "A Service Instance" do
11
+ context "A Service Instance's" do
12
12
  setup do
13
13
  @svc = BERTRPC::Service.new('localhost', 9941)
14
14
  end
15
15
 
16
- should "return it's host" do
17
- assert_equal 'localhost', @svc.host
16
+ context "accessors" do
17
+ should "return it's host" do
18
+ assert_equal 'localhost', @svc.host
19
+ end
20
+
21
+ should "return it's port" do
22
+ assert_equal 9941, @svc.port
23
+ end
18
24
  end
19
25
 
20
- should "return it's port" do
21
- assert_equal 9941, @svc.port
26
+ context "call method" do
27
+ should "return a call type Request" do
28
+ req = @svc.call
29
+ assert req.is_a?(BERTRPC::Request)
30
+ assert_equal :call, req.kind
31
+ end
22
32
  end
23
33
 
24
- should "return a Call instance" do
25
- assert @svc.call.is_a?(BERTRPC::CallProxy)
34
+ context "cast method" do
35
+ should "return a cast type Request" do
36
+ req = @svc.cast
37
+ assert req.is_a?(BERTRPC::Request)
38
+ assert_equal :cast, req.kind
39
+ end
26
40
  end
27
41
  end
28
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bertrpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Preston-Werner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-13 00:00:00 -07:00
12
+ date: 2009-09-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,16 +40,16 @@ files:
40
40
  - VERSION
41
41
  - bertrpc.gemspec
42
42
  - lib/bertrpc.rb
43
- - lib/bertrpc/call.rb
44
- - lib/bertrpc/call_proxy.rb
43
+ - lib/bertrpc/action.rb
45
44
  - lib/bertrpc/encodes.rb
46
45
  - lib/bertrpc/errors.rb
47
46
  - lib/bertrpc/mod.rb
47
+ - lib/bertrpc/request.rb
48
48
  - lib/bertrpc/service.rb
49
- - test/call_proxy_test.rb
50
- - test/call_test.rb
49
+ - test/action_test.rb
51
50
  - test/encodes_test.rb
52
51
  - test/mod_test.rb
52
+ - test/request_test.rb
53
53
  - test/service_test.rb
54
54
  - test/test_helper.rb
55
55
  has_rdoc: true
@@ -81,9 +81,9 @@ signing_key:
81
81
  specification_version: 3
82
82
  summary: BERTRPC is a Ruby BERT-RPC client library.
83
83
  test_files:
84
- - test/call_proxy_test.rb
85
- - test/call_test.rb
84
+ - test/action_test.rb
86
85
  - test/encodes_test.rb
87
86
  - test/mod_test.rb
87
+ - test/request_test.rb
88
88
  - test/service_test.rb
89
89
  - test/test_helper.rb
data/lib/bertrpc/call.rb DELETED
@@ -1,33 +0,0 @@
1
- module BERTRPC
2
- class Call
3
- include Encodes
4
-
5
- def initialize(svc, mod, fun, args)
6
- @svc = svc
7
- @mod = mod
8
- @fun = fun
9
- @args = args
10
- end
11
-
12
- def execute
13
- bert_request = encode_ruby_request([:call, @mod, @fun, @args])
14
- bert_response = sync_request(bert_request)
15
- decode_bert_response(bert_response)
16
- end
17
-
18
- #private
19
-
20
- def sync_request(bert_request)
21
- sock = TCPSocket.new(@svc.host, @svc.port)
22
- sock.write([bert_request.length].pack("N"))
23
- sock.write(bert_request)
24
- lenheader = sock.read(4)
25
- raise ProtocolError.new("Unable to read length header from server.") unless lenheader
26
- len = lenheader.unpack('N').first
27
- bert_response = sock.read(len)
28
- raise ProtocolError.new("Unable to read data from server.") unless bert_response
29
- sock.close
30
- bert_response
31
- end
32
- end
33
- end
@@ -1,11 +0,0 @@
1
- module BERTRPC
2
- class CallProxy
3
- def initialize(svc)
4
- @svc = svc
5
- end
6
-
7
- def method_missing(cmd, *args)
8
- Mod.new(@svc, Call, cmd)
9
- end
10
- end
11
- end
@@ -1,24 +0,0 @@
1
- require 'test_helper'
2
-
3
- class CallProxyTest < Test::Unit::TestCase
4
- context "A CallProxy" do
5
- setup do
6
- @svc = BERTRPC::Service.new('localhost', 9941)
7
- end
8
-
9
- should "be created with a Service" do
10
- assert BERTRPC::CallProxy.new(@svc).is_a?(BERTRPC::CallProxy)
11
- end
12
- end
13
-
14
- context "A CallProxy instance" do
15
- setup do
16
- svc = BERTRPC::Service.new('localhost', 9941)
17
- @cp = BERTRPC::CallProxy.new(@svc)
18
- end
19
-
20
- should "return a Mod instance" do
21
- assert @cp.myfun.is_a?(BERTRPC::Mod)
22
- end
23
- end
24
- end