bertrpc 0.2.0 → 0.3.0

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