msgpack-rpc-over-http-jruby 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ jruby-1.7.3
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in msgpack-rpc-over-http.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'test-unit', '~> 2.5.2'
8
+ gem 'mizuno'
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Narihiro Nakamura
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # MessagePack-RPC over HTTP (JRuby)
2
+
3
+ This library provides [MessagePack-RPC](https://github.com/msgpack/msgpack-rpc) via HTTP as XML-RPC.
4
+ The original MessagePack-RPC Server in Ruby is not good in some cases.
5
+ It doesn't scale. It's incompatible with Thread. There is no decent termination processing...
6
+
7
+ We alreadly have various high perfomance HTTP servers.
8
+ We can use these in MessagePack-RPC over HTTP.
9
+
10
+ **CAUTION**
11
+
12
+ There is no compatibility with other implementation of normal MessagePack-RPC (not over HTTP).
13
+ So a normal RPC client can not connect a HTTP server.
14
+
15
+ **PLATFORM NOTIFICATION**
16
+
17
+ This branch is for JRuby, and protocol is comatible with the original gem (msgpack-rpc-over-http) for CRuby.
18
+ Code is 100% same with msgpack-rpc-over-http by authorNari. See: https://github.com/authorNari/msgpack-rpc-over-http
19
+
20
+ ## Usage
21
+
22
+ **Server**
23
+
24
+ confir.ru:
25
+ ```ruby
26
+ require 'msgpack-rpc-over-http-jruby'
27
+ class MyHandler
28
+ def add(x,y) return x+y end
29
+ end
30
+
31
+ run MessagePack::RPCOverHTTP::Server.app(MyHandler.new)
32
+ ```
33
+
34
+ rackup:
35
+ ```zsh
36
+ % rackup config.ru -s mizuno
37
+ Mizuno 0.6.6 (Jetty 8.1.3.v20120416) listening on 0.0.0.0:9292
38
+ ```
39
+
40
+ **Client**
41
+
42
+ client.rb:
43
+ ```ruby
44
+ require 'msgpack-rpc-over-http-jruby'
45
+ c = MessagePack::RPCOverHTTP::Client.new("http://0.0.0.0:9292/")
46
+ result = c.call(:add, 1, 2) #=> 3
47
+ ```
48
+
49
+ ## Extended futures
50
+
51
+ Support streaming response via Chunked Transfer-Encoding.
52
+
53
+ ```ruby
54
+ # server side
55
+ class Handler
56
+ include MessagePack::RPCOverHTTP::Server::Streamer
57
+ def log
58
+ return stream do
59
+ File.open('/var/log/syslog') do |f|
60
+ while line = f.gets.chomp
61
+ # write a chunked data
62
+ chunk(line)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ # client
70
+ client = MessagePack::RPCOverHTTP::Client.new("http://0.0.0.0:80/")
71
+ client.stream do |line|
72
+ p line # => "Nov 3 ..."
73
+ end
74
+ ```
75
+
76
+ ## Installation
77
+
78
+ Add this line to your application's Gemfile:
79
+
80
+ gem 'msgpack-rpc-over-http-jruby'
81
+
82
+ And then execute:
83
+
84
+ $ bundle
85
+
86
+ Or install it yourself as:
87
+
88
+ $ gem install msgpack-rpc-over-http-jruby
89
+
90
+ ## Usage
91
+
92
+ TODO: Write usage instructions here
93
+
94
+ ## Contributing
95
+
96
+ 1. Fork it
97
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
98
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
99
+ 4. Push to the branch (`git push origin my-new-feature`)
100
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/setup"
3
+ Bundler.require(:default, :development)
4
+ require "bundler/gem_tasks"
5
+
6
+ task :default do
7
+ sh "/usr/bin/env ruby test/run-test.rb"
8
+ end
@@ -0,0 +1,111 @@
1
+ require 'celluloid'
2
+ require 'httpclient'
3
+ require 'forwardable'
4
+
5
+ module MessagePack
6
+ module RPCOverHTTP
7
+
8
+ # Cliet for MessagePack-RPC over HTTP.
9
+ class Client
10
+ extend Forwardable
11
+
12
+ HEADER = {"Content-Type" => 'application/x-msgpack'}
13
+
14
+ def initialize(url, options={})
15
+ @url = url
16
+ @client = HTTPClient.new
17
+ @reqtable = {}
18
+ @seqid = 0
19
+ end
20
+
21
+ def_delegators(:@client,
22
+ :connect_timeout, :send_timeout, :receive_timeout, :debug_dev=)
23
+
24
+ # call-seq:
25
+ # call(symbol, *args) -> result of remote method
26
+ #
27
+ # Calls remote method.
28
+ # This method is same as call_async(method, *args).value
29
+ def call(method, *args)
30
+ return send_request(method, args)
31
+ end
32
+
33
+ # call-seq:
34
+ # call_async(symbol, *args) -> Celluloid::Future
35
+ #
36
+ # Calls remote method asynchronously.
37
+ # This method is non-blocking and returns Future.
38
+ def call_async(method, *args)
39
+ return Celluloid::Future.new{ send_request(method, args) }
40
+ end
41
+
42
+ # call-seq:
43
+ # callback(symbol, *args) {|res, err| } -> Celluloid::Future
44
+ #
45
+ # Calls remote method asynchronously.
46
+ # The callback method is called with Future when the result is reached.
47
+ # `err' is assigned a instance of RemoteError or child if res is nil.
48
+ def callback(method, *args, &block)
49
+ return Celluloid::Future.new do
50
+ begin
51
+ block.call(send_request(method, args))
52
+ rescue RemoteError => ex
53
+ block.call(nil, ex)
54
+ end
55
+ end
56
+ end
57
+
58
+ # call-seq:
59
+ # stream(symbol, *args) {|chunk| }
60
+ #
61
+ # Calls remote method with streaming.
62
+ # Remote method have to return a chunked response.
63
+ def stream(method, *args, &block)
64
+ data = create_request_body(method, args)
65
+ @client.post_content(@url, :body => data, :header => HEADER) do |chunk|
66
+ begin
67
+ block.call(get_result(chunk))
68
+ rescue RemoteError => ex
69
+ block.call(nil, ex)
70
+ end
71
+ end
72
+ end
73
+
74
+ # call-seq:
75
+ # stream_async(symbol, *args) {|chunk| } -> Celluloid::Future
76
+ #
77
+ # Calls remote method asynchronously with streaming.
78
+ def stream_async(method, *args, &block)
79
+ return Celluloid::Future.new do
80
+ stream(method, *args, &block)
81
+ end
82
+ end
83
+
84
+ private
85
+ def send_request(method, param)
86
+ data = create_request_body(method, param)
87
+ body = @client.post_content(@url, :body => data, :header => HEADER)
88
+ return get_result(body)
89
+ end
90
+
91
+ def create_request_body(method, param)
92
+ method = method.to_s
93
+ msgid = @seqid
94
+ @seqid += 1
95
+ @seqid = 0 if @seqid >= (1 << 31)
96
+ data = [REQUEST, msgid, method, param].to_msgpack
97
+ end
98
+
99
+ def get_result(body)
100
+ type, msgid, err, res = MessagePack.unpack(body)
101
+ raise "Unknown message type #{type}" if type != RESPONSE
102
+
103
+ if err.nil?
104
+ return res
105
+ else
106
+ raise RemoteError.create(err, res)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,44 @@
1
+ module MessagePack
2
+
3
+ ##
4
+ ## MessagePack-RPCOverHTTP Exception
5
+ ##
6
+ #
7
+ # RemoteError
8
+ # |
9
+ # +-- RuntimeError
10
+ # |
11
+ # +-- (user-defined errors)
12
+ #
13
+ module RPCOverHTTP
14
+ class RemoteError < StandardError
15
+ def initialize(code, *data)
16
+ @code = code.to_s
17
+ @data = data
18
+ super(@data.shift || @code)
19
+ end
20
+
21
+ attr_reader :code
22
+ attr_reader :data
23
+
24
+ def self.create(code, data)
25
+ error_class = constantize(code)
26
+ if error_class < RemoteError
27
+ error_class.new(code, *data)
28
+ else
29
+ self.new(code, *data)
30
+ end
31
+ end
32
+
33
+ private
34
+ def self.constantize(name)
35
+ return name.split("::").inject(Object) do |memo, i|
36
+ memo.const_get(i)
37
+ end
38
+ end
39
+ end
40
+
41
+ class RuntimeError < RemoteError
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,24 @@
1
+ module MessagePack
2
+ module RPCOverHTTP
3
+ class Server
4
+
5
+ # Dispatcher of user-defined handler.
6
+ class Dispatcher
7
+ def initialize(handler, accept=handler.public_methods)
8
+ @handler = handler
9
+ @accept = accept
10
+ end
11
+
12
+ def call(env)
13
+ method = env['msgpack-rpc.method']
14
+ params = env['msgpack-rpc.params']
15
+ unless @accept.include?(method)
16
+ raise NoMethodError, "method `#{method}' is not accepted"
17
+ end
18
+
19
+ return @handler.send(method, *params)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,69 @@
1
+ module MessagePack
2
+ module RPCOverHTTP
3
+ class Server
4
+
5
+ # Rack Middleware that unpacks a serialized string in a HTTP
6
+ # request.
7
+ class RequestUnpacker
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ req = Rack::Request.new(env)
14
+ if (error = check_request(req))
15
+ return error
16
+ end
17
+
18
+ unpack(env, req.body.read)
19
+ return @app.call(env)
20
+ end
21
+
22
+ private
23
+ def check_request(req)
24
+ if req.request_method != "POST"
25
+ return [
26
+ 405, # Method Not Allowed
27
+ {'Content-Type' => 'text/plain'},
28
+ ["Only POST is allowed"]
29
+ ]
30
+ end
31
+
32
+ if req.media_type != "application/x-msgpack"
33
+ return [
34
+ 400, # Bad Request
35
+ {'Content-Type' => 'text/plain'},
36
+ ["Only text/plain is allowed #{req.content_type}"]
37
+ ]
38
+ end
39
+
40
+ if req.content_length.to_i <= 0
41
+ return [
42
+ 411, # Length Required
43
+ {'Content-Type' => 'text/plain'},
44
+ ["Missing Content-Length"]
45
+ ]
46
+ end
47
+
48
+ return nil
49
+ end
50
+
51
+ def unpack(env, body)
52
+ msg = MessagePack.unpack(body)
53
+ env['msgpack-rpc.type'] = msg[0]
54
+ case msg[0]
55
+ when REQUEST
56
+ env['msgpack-rpc.msgid'] = msg[1]
57
+ env['msgpack-rpc.method'] = msg[2].to_sym
58
+ env['msgpack-rpc.params'] = msg[3]
59
+ when NOTIFY
60
+ env['msgpack-rpc.method'] = msg[1].to_sym
61
+ env['msgpack-rpc.params'] = msg[2]
62
+ else
63
+ raise "unknown message type #{msg[0]}"
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,41 @@
1
+ module MessagePack
2
+ module RPCOverHTTP
3
+ class Server
4
+
5
+ # Rack Middleware that packs a result of a handler method and
6
+ # create a HTTP Responce.
7
+ class ResponsePacker
8
+ def initialize(dispatcher)
9
+ @dispatcher = dispatcher
10
+ end
11
+
12
+ def call(env)
13
+ res = Rack::Response.new
14
+ res["Content-type"] = "text/plain"
15
+ msgid = env['msgpack-rpc.msgid']
16
+
17
+ body = @dispatcher.call(env)
18
+ if body.is_a?(Streamer::Body)
19
+ body.msgid = msgid
20
+ res.body = body
21
+ return [res.status.to_i, res.header, body]
22
+ else
23
+ res.write self.class.pack(msgid, nil, body)
24
+ return res.finish
25
+ end
26
+ rescue RPCOverHTTP::RemoteError => ex
27
+ res.write self.class.pack(msgid, ex.class.name, ex.message)
28
+ return res.finish
29
+ rescue ::RuntimeError => ex
30
+ res.write(self.class.pack(
31
+ msgid, RPCOverHTTP::RuntimeError.name, ex.message))
32
+ return res.finish
33
+ end
34
+
35
+ def self.pack(msgid, error, result)
36
+ return MessagePack.pack([RESPONSE, msgid, error, result])
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,67 @@
1
+ require 'fiber'
2
+
3
+ module MessagePack
4
+ module RPCOverHTTP
5
+ class Server
6
+
7
+ # Support streaming
8
+ module Streamer
9
+ class Body
10
+ attr_accessor :msgid
11
+
12
+ def initialize(&proc)
13
+ @proc = proc
14
+ end
15
+
16
+ def each(&block)
17
+ @proc.call(msgid, block)
18
+ return self
19
+ end
20
+ end
21
+
22
+ # call-seq:
23
+ # stream(&writer) -> streamable body
24
+ #
25
+ # Returns a Body object that responds to each.
26
+ # Chunks of body are created with calling chunk() in given block.
27
+ #
28
+ # def passwd
29
+ # return stream do
30
+ # File.open('/etc/passwd') do |file|
31
+ # while line = file.gets
32
+ # chunk(file.gets)
33
+ # end
34
+ # end
35
+ # end
36
+ # end
37
+ def stream(&writer)
38
+ fi = Fiber.new do
39
+ writer.call
40
+ end
41
+
42
+ Body.new do |msgid, sender|
43
+ begin
44
+ while true
45
+ chunk = fi.resume
46
+ break unless fi.alive?
47
+ sender.call(ResponsePacker.pack(msgid, nil, chunk))
48
+ end
49
+ rescue RemoteError => ex
50
+ sender.call(ResponsePacker.pack(msgid, ex.class.name, nil))
51
+ rescue ::RuntimeError => ex
52
+ sender.call(ResponsePacker.pack(msgid, RuntimeError.name, nil))
53
+ end
54
+ end
55
+ end
56
+
57
+ # call-seq:
58
+ # chunk(obj)
59
+ #
60
+ # Send a object as chunked data in block of stream().
61
+ def chunk(obj)
62
+ Fiber.yield(obj)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ require 'rack'
2
+ require 'rack/builder'
3
+ require_relative 'server/dispatcher'
4
+ require_relative 'server/request_unpacker'
5
+ require_relative 'server/response_packer'
6
+ require_relative 'server/streamer'
7
+
8
+ module MessagePack
9
+ module RPCOverHTTP
10
+ class Server
11
+
12
+ # Retruns the application for MessagePack-RPC.
13
+ # It's create with Rack::Builder
14
+ def self.app(handler)
15
+ return Rack::Builder.app do
16
+ use Rack::Chunked
17
+ use RequestUnpacker
18
+ use ResponsePacker
19
+ use Dispatcher
20
+ run handler
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module MessagePack
2
+ module RPCOverHTTP
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ require 'msgpack'
2
+ require_relative "msgpack/rpc_over_http/version"
3
+ require_relative "msgpack/rpc_over_http/error"
4
+ require_relative "msgpack/rpc_over_http/server"
5
+ require_relative "msgpack/rpc_over_http/client"
6
+
7
+ module MessagePack
8
+ module RPCOverHTTP
9
+ REQUEST = 0 # [0, msgid, method, param]
10
+ RESPONSE = 1 # [1, msgid, error, result]
11
+ NOTIFY = 2 # [2, method, param]
12
+
13
+ NO_METHOD_ERROR = 0x01;
14
+ ARGUMENT_ERROR = 0x02;
15
+ end
16
+ end
17
+
18
+ # for compatibility between msgpack(cruby) and msgpack-jruby
19
+ class Array
20
+ def to_msgpack
21
+ MessagePack.pack(self)
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/msgpack/rpc_over_http/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["TAGOMORI Satoshi"]
6
+ gem.email = ["tagomoris@gmail.com"]
7
+ gem.description = %q{This library provides MessagePack-RPC via HTTP, jruby fork}
8
+ gem.summary = %q{This library provides MessagePack-RPC via HTTP, jruby fork}
9
+ gem.homepage = "https://github.com/tagomoris/msgpack-rpc-over-http/tree/jruby"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "msgpack-rpc-over-http-jruby"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = MessagePack::RPCOverHTTP::VERSION
17
+
18
+ gem.add_development_dependency "rack", "~> 1.4.1"
19
+ gem.add_development_dependency "msgpack-jruby", "~> 1.3.2"
20
+ gem.add_development_dependency "celluloid", "~> 0.12.3"
21
+ gem.add_development_dependency "httpclient", "~> 2.3.0.1"
22
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'net/http'
2
+ require 'timeout'
3
+
4
+ class MockHandler
5
+ include MessagePack::RPCOverHTTP::Server::Streamer
6
+
7
+ class Error < MessagePack::RPCOverHTTP::RemoteError
8
+ end
9
+
10
+ def test(*args)
11
+ return args
12
+ end
13
+
14
+ def stream_normal(*args)
15
+ return stream { args.each{|arg| chunk(arg) } }
16
+ end
17
+
18
+ def stream_error(*args)
19
+ return stream do
20
+ args.each{|arg| chunk(arg) }
21
+ raise "Error"
22
+ end
23
+ end
24
+
25
+ def error
26
+ raise "Something Error"
27
+ end
28
+
29
+ def user_defined_error
30
+ raise Error, "Something Error"
31
+ end
32
+ end
33
+
34
+ def sleep_until_http_server_is_started(host, port)
35
+ timeout(30) do
36
+ while stopped_test_app_server?(host, port)
37
+ sleep 1
38
+ end
39
+ end
40
+ end
41
+
42
+ def stopped_test_app_server?(host, port)
43
+ begin
44
+ Net::HTTP.get(host, '/', port)
45
+ return false
46
+ rescue => ex
47
+ return true
48
+ end
49
+ end
@@ -0,0 +1,8 @@
1
+ #\ -s mizuno
2
+ $LOAD_PATH.unshift(File.expand_path("./../lib", File.dirname(__FILE__)))
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+
5
+ require 'msgpack-rpc-over-http-jruby'
6
+ require 'helper'
7
+
8
+ run MessagePack::RPCOverHTTP::Server.app(MockHandler.new)
data/test/run-test.rb ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ base_dir = File.expand_path(File.dirname(__FILE__))
3
+ top_dir = File.expand_path("..", base_dir)
4
+ $LOAD_PATH.unshift(File.join(top_dir, "lib"))
5
+ $LOAD_PATH.unshift(File.join(top_dir, "test"))
6
+
7
+ require "bundler"
8
+ Bundler.require(:default, :test)
9
+ require "test/unit"
10
+
11
+ require "msgpack-rpc-over-http-jruby"
12
+ require "helper"
13
+
14
+ test_file = "./test/test_*.rb"
15
+ Dir.glob(test_file) do |file|
16
+ require file
17
+ end
@@ -0,0 +1,95 @@
1
+ module MessagePack::RPCOverHTTP
2
+ class TestClient < Test::Unit::TestCase
3
+ def self.unused_port
4
+ s = TCPServer.open(0)
5
+ port = s.addr[1]
6
+ s.close
7
+ port
8
+ end
9
+
10
+ @@server_port = unused_port
11
+ @@is_stopped_test_app_server = true
12
+
13
+ def setup
14
+ @client = Client.new("http://0.0.0.0:#{@@server_port}/")
15
+ if @@is_stopped_test_app_server
16
+ # pid = fork {
17
+ # Rack::Server.start(config: "test/mock_server.ru", Port: @@server_port)
18
+ # exit 0
19
+ # }
20
+ # at_exit do
21
+ # Process.kill(:INT, pid)
22
+ # Process.waitpid(pid)
23
+ # end
24
+ @thread = Thread.new do
25
+ Rack::Server.start(config: "test/mock_server.ru", Port: @@server_port)
26
+ end
27
+ at_exit do
28
+ @thread.kill
29
+ # @thread.join
30
+ end
31
+ sleep_until_http_server_is_started("0.0.0.0", @@server_port)
32
+ @@is_stopped_test_app_server = false
33
+ end
34
+ end
35
+
36
+ def test_call
37
+ assert_equal ["a", "b"], @client.call(:test, "a", "b")
38
+ assert_raise(MessagePack::RPCOverHTTP::RuntimeError) do
39
+ @client.call(:error)
40
+ end
41
+ assert_raise(MockHandler::Error) do
42
+ @client.call(:user_defined_error)
43
+ end
44
+ end
45
+
46
+ def test_call_async
47
+ future = @client.call_async(:test, "a", "b")
48
+ assert_equal ["a", "b"], future.value
49
+ assert_raise(MessagePack::RPCOverHTTP::RuntimeError) do
50
+ future = @client.call(:error)
51
+ future.value
52
+ end
53
+
54
+ # multi-call
55
+ (1..20).map{|i| [@client.call_async(:test, i), i] }.each do |f, i|
56
+ assert_equal [i], f.value
57
+ end
58
+ end
59
+
60
+ def test_callback
61
+ future = @client.callback(:test, "a", "b") do |res|
62
+ assert_equal ["a", "b"], res
63
+ end
64
+ future.value
65
+ future = @client.callback(:error) do |res, err|
66
+ assert_kind_of MessagePack::RPCOverHTTP::RuntimeError, err
67
+ end
68
+ future.value
69
+ end
70
+
71
+ def test_stream
72
+ expect = ["a", "b"]
73
+ @client.stream(:stream_normal, "a", "b") do |res|
74
+ assert_equal expect.shift, res
75
+ end
76
+
77
+ expect = ["a", "b"]
78
+ @client.stream(:stream_error) do |res, err|
79
+ if res
80
+ assert_equal expect.shift, res
81
+ else
82
+ assert_kind_of MessagePack::RPCOverHTTP::RuntimeError, err
83
+ end
84
+ end
85
+ end
86
+
87
+ def test_stream_async
88
+ expect = ["a", "b"]
89
+ future = @client.stream_async(:stream_normal, "a", "b") do |res|
90
+ assert_equal expect.shift, res
91
+ end
92
+ future.value
93
+ end
94
+ end
95
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: msgpack-rpc-over-http-jruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - TAGOMORI Satoshi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 1.4.1
21
+ none: false
22
+ requirement: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.1
27
+ none: false
28
+ prerelease: false
29
+ type: :development
30
+ - !ruby/object:Gem::Dependency
31
+ name: msgpack-jruby
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: 1.3.2
37
+ none: false
38
+ requirement: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: 1.3.2
43
+ none: false
44
+ prerelease: false
45
+ type: :development
46
+ - !ruby/object:Gem::Dependency
47
+ name: celluloid
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: 0.12.3
53
+ none: false
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: 0.12.3
59
+ none: false
60
+ prerelease: false
61
+ type: :development
62
+ - !ruby/object:Gem::Dependency
63
+ name: httpclient
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.3.0.1
69
+ none: false
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 2.3.0.1
75
+ none: false
76
+ prerelease: false
77
+ type: :development
78
+ description: This library provides MessagePack-RPC via HTTP, jruby fork
79
+ email:
80
+ - tagomoris@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - ".gitignore"
86
+ - ".ruby-version"
87
+ - Gemfile
88
+ - LICENSE
89
+ - README.md
90
+ - Rakefile
91
+ - lib/msgpack-rpc-over-http-jruby.rb
92
+ - lib/msgpack/rpc_over_http/client.rb
93
+ - lib/msgpack/rpc_over_http/error.rb
94
+ - lib/msgpack/rpc_over_http/server.rb
95
+ - lib/msgpack/rpc_over_http/server/dispatcher.rb
96
+ - lib/msgpack/rpc_over_http/server/request_unpacker.rb
97
+ - lib/msgpack/rpc_over_http/server/response_packer.rb
98
+ - lib/msgpack/rpc_over_http/server/streamer.rb
99
+ - lib/msgpack/rpc_over_http/version.rb
100
+ - msgpack-rpc-over-http-jruby.gemspec
101
+ - test/helper.rb
102
+ - test/mock_server.ru
103
+ - test/run-test.rb
104
+ - test/test_client.rb
105
+ homepage: https://github.com/tagomoris/msgpack-rpc-over-http/tree/jruby
106
+ licenses: []
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ segments:
116
+ - 0
117
+ hash: 2
118
+ version: !binary |-
119
+ MA==
120
+ none: false
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ segments:
126
+ - 0
127
+ hash: 2
128
+ version: !binary |-
129
+ MA==
130
+ none: false
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 1.8.24
134
+ signing_key:
135
+ specification_version: 3
136
+ summary: This library provides MessagePack-RPC via HTTP, jruby fork
137
+ test_files:
138
+ - test/helper.rb
139
+ - test/mock_server.ru
140
+ - test/run-test.rb
141
+ - test/test_client.rb