msgpack-rpc 0.4.0 → 0.4.1

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.
@@ -30,8 +30,16 @@ class Server < SessionPool
30
30
  @listeners = []
31
31
  end
32
32
 
33
+ # 1. serve(dispatcher)
34
+ # 2. serve(obj, accept = obj.public_methods)
33
35
  def serve(obj, accept = obj.public_methods)
34
- @dispatcher = ObjectDispatcher.new(obj, accept)
36
+ if obj.is_a?(Dispatcher)
37
+ # 2.
38
+ @dispatcher = obj
39
+ else
40
+ # 1.
41
+ @dispatcher = ObjectDispatcher.new(obj, accept)
42
+ end
35
43
  self
36
44
  end
37
45
 
@@ -70,12 +78,81 @@ class Server < SessionPool
70
78
  # from ServerTransport
71
79
  def on_request(sendable, msgid, method, param) #:nodoc:
72
80
  responder = Responder.new(sendable, msgid)
73
- @dispatcher.dispatch_request(self, method, param, responder)
81
+ dispatch_method(method, param, responder)
74
82
  end
75
83
 
76
84
  # from ServerTransport
77
85
  def on_notify(method, param) #:nodoc:
78
- @dispatcher.dispatch_notify(self, method, param)
86
+ responder = NullResponder.new
87
+ dispatch_method(method, param, responder)
88
+ end
89
+
90
+ private
91
+ def dispatch_method(method, param, responder) #:nodoc:
92
+ begin
93
+ sent = false
94
+ early_result = nil
95
+ result = @dispatcher.dispatch(method, param) do |result_|
96
+ unless result_.is_a?(AsyncResult)
97
+ responder.result(result_)
98
+ sent = true
99
+ end
100
+ early_result = result_
101
+ end
102
+
103
+ #FIXME on NoMethodError
104
+ # res.error(NO_METHOD_ERROR); return
105
+
106
+ #FIXME on ArgumentError
107
+ # res.error(ArgumentError); return
108
+
109
+ rescue
110
+ responder.error($!.to_s)
111
+ return
112
+ end
113
+
114
+ if early_result.is_a?(AsyncResult)
115
+ early_result.set_responder(responder)
116
+ elsif sent
117
+ return
118
+ elsif result.is_a?(AsyncResult)
119
+ result.set_responder(responder)
120
+ else
121
+ responder.result(result)
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+ class AsyncResult
128
+ def initialize
129
+ @responder = nil
130
+ @sent = false
131
+ end
132
+
133
+ def result(retval, err = nil)
134
+ unless @sent
135
+ if @responder
136
+ @responder.result(retval, err)
137
+ else
138
+ @result = [retval, err]
139
+ end
140
+ @sent = true
141
+ end
142
+ nil
143
+ end
144
+
145
+ def error(err)
146
+ result(nil, err)
147
+ nil
148
+ end
149
+
150
+ def set_responder(res) #:nodoc:
151
+ @responder = res
152
+ if @sent && @result
153
+ @responder.result(*@result)
154
+ @result = nil
155
+ end
79
156
  end
80
157
  end
81
158
 
@@ -84,11 +161,20 @@ class Responder
84
161
  def initialize(sendable, msgid)
85
162
  @sendable = sendable # send_message method is required
86
163
  @msgid = msgid
164
+ @sent = false
165
+ end
166
+
167
+ def sent?
168
+ @sent
87
169
  end
88
170
 
89
171
  def result(retval, err = nil)
90
- data = [RESPONSE, @msgid, err, retval].to_msgpack
91
- @sendable.send_data(data)
172
+ unless @sent
173
+ data = [RESPONSE, @msgid, err, retval].to_msgpack
174
+ @sendable.send_data(data)
175
+ @sent = true
176
+ end
177
+ nil
92
178
  end
93
179
 
94
180
  def error(err, retval = nil)
@@ -97,6 +183,21 @@ class Responder
97
183
  end
98
184
 
99
185
 
186
+ class NullResponder
187
+ def sent?
188
+ true
189
+ end
190
+
191
+ def result(retval, err = nil)
192
+ nil
193
+ end
194
+
195
+ def error(err, retval = nil)
196
+ nil
197
+ end
198
+ end
199
+
200
+
100
201
  #:nodoc:
101
202
  class Server::Base
102
203
  def initialize(*args)
@@ -37,12 +37,12 @@ class Session
37
37
 
38
38
  # backward compatibility
39
39
  def port #:nodoc:
40
- @address.port;
40
+ @address.port
41
41
  end
42
42
 
43
43
  # backward compatibility
44
44
  def host #:nodoc:
45
- @address.host;
45
+ @address.host
46
46
  end
47
47
 
48
48
  # call-seq:
@@ -51,7 +51,17 @@ class Session
51
51
  # Calls remote method.
52
52
  # This method is same as call_async(method, *args).get
53
53
  def call(method, *args)
54
- call_async(method, *args).get
54
+ send_request(method, args).get
55
+ end
56
+
57
+ # call-seq:
58
+ # call_apply(symbol, params) -> result of remote method
59
+ #
60
+ # Calls remote method.
61
+ # This method is same as call(method, *args) excepting that
62
+ # the arugment is a array.
63
+ def call_apply(method, params)
64
+ send_request(method, params).get
55
65
  end
56
66
 
57
67
  # call-seq:
@@ -63,6 +73,16 @@ class Session
63
73
  future = send_request(method, args)
64
74
  end
65
75
 
76
+ # call-seq:
77
+ # call_async_apply(symbol, params) -> Future
78
+ #
79
+ # Calls remote method asynchronously.
80
+ # This method is same as call_async(method, *args) excepting that
81
+ # the arugment is a array.
82
+ def call_async_apply(method, params)
83
+ future = send_request(method, params)
84
+ end
85
+
66
86
  # backward compatibility
67
87
  alias send call_async #:nodoc:
68
88
 
@@ -78,6 +98,19 @@ class Session
78
98
  future
79
99
  end
80
100
 
101
+ # call-seq:
102
+ # callback_apply(symbol, params) {|future| }
103
+ #
104
+ # Calls remote method asynchronously.
105
+ # The callback method is called with Future when the result is reached.
106
+ # This method is same as callback(method, *args).attach_callback {|future| }
107
+ # excepting that the argument is a array.
108
+ def callback_apply(method, params, &block)
109
+ future = send_request(method, params)
110
+ future.attach_callback(block)
111
+ future
112
+ end
113
+
81
114
  # call-seq:
82
115
  # notify(symbol, *args) -> nil
83
116
  #
@@ -89,6 +122,19 @@ class Session
89
122
  nil
90
123
  end
91
124
 
125
+ # call-seq:
126
+ # notify_apply(symbol, params) -> nil
127
+ #
128
+ # Calls remote method with NOTIFY protocol.
129
+ # It doesn't require server to return results.
130
+ # This method is non-blocking and returns nil.
131
+ # This method is same as notify(method, *args) excepting that
132
+ # the argument is a array.
133
+ def notify_apply(method, params)
134
+ send_notify(method, params)
135
+ nil
136
+ end
137
+
92
138
  # Closes underlaying Transport and destroy resources.
93
139
  def close
94
140
  @transport.close
@@ -107,10 +153,7 @@ class Session
107
153
  # from ClientTransport
108
154
  def on_connect_failed #:nodoc:
109
155
  @reqtable.reject! {|msgid, future|
110
- begin
111
- future.set_result ConnectError.new, nil
112
- rescue
113
- end
156
+ future.set_result ConnectionTimeoutError::CODE, ["connection timed out"]
114
157
  true
115
158
  }
116
159
  nil
@@ -126,10 +169,7 @@ class Session
126
169
  end
127
170
  }
128
171
  timedout.each {|future|
129
- begin
130
- future.set_result TimeoutError.new, nil
131
- rescue
132
- end
172
+ future.set_result TimeoutError::CODE, ["request timed out"]
133
173
  }
134
174
  !@reqtable.empty?
135
175
  end
@@ -37,6 +37,15 @@ class TCPTransport
37
37
  @pac = MessagePack::Unpacker.new
38
38
  end
39
39
 
40
+ # from Rev::TCPSocket
41
+ def on_readable
42
+ super
43
+ rescue
44
+ # FIXME send Connection Close message
45
+ # FIXME log
46
+ close
47
+ end
48
+
40
49
  # from Rev::TCPSocket
41
50
  def on_read(data)
42
51
  @pac.feed(data)
@@ -142,12 +151,12 @@ class TCPClientTransport
142
151
 
143
152
  # MessageReceiver interface
144
153
  def on_request(msgid, method, param)
145
- raise RPCError.new("request message on client session")
154
+ raise Error.new("request message on client session")
146
155
  end
147
156
 
148
157
  # MessageReceiver interface
149
158
  def on_notify(method, param)
150
- raise RPCError.new("notify message on client session")
159
+ raise Error.new("notify message on client session")
151
160
  end
152
161
 
153
162
  # MessageReceiver interface
@@ -232,7 +241,7 @@ class TCPServerTransport
232
241
 
233
242
  # MessageReceiver interface
234
243
  def on_response(msgid, error, result)
235
- raise RPCError.new("response message on server session")
244
+ raise Error.new("response message on server session")
236
245
  end
237
246
  end
238
247
  end
@@ -29,7 +29,10 @@ class UDPTransport
29
29
  end
30
30
 
31
31
  class BasicSocket < Rev::IOWatcher
32
+ HAVE_DNRL = UDPSocket.public_instance_methods.include?(:do_not_reverse_lookup)
33
+
32
34
  def initialize(io)
35
+ io.do_not_reverse_lookup = true if HAVE_DNRL
33
36
  super(io)
34
37
  @io = io
35
38
  end
@@ -46,6 +49,9 @@ class UDPTransport
46
49
  # FIXME multiple objects in one message
47
50
  obj = MessagePack.unpack(data)
48
51
  on_message(obj, addr)
52
+ rescue
53
+ # FIXME log
54
+ return
49
55
  end
50
56
 
51
57
  include MessageReceiver
@@ -98,12 +104,12 @@ class UDPClientTransport
98
104
 
99
105
  # MessageReceiver interface
100
106
  def on_request(msgid, method, param, addr)
101
- raise RPCError.new("request message on client session")
107
+ raise Error.new("request message on client session")
102
108
  end
103
109
 
104
110
  # MessageReceiver interface
105
111
  def on_notify(method, param, addr)
106
- raise RPCError.new("notify message on client session")
112
+ raise Error.new("notify message on client session")
107
113
  end
108
114
 
109
115
  # MessageReceiver interface
@@ -169,7 +175,7 @@ class UDPServerTransport
169
175
 
170
176
  # MessageReceiver interface
171
177
  def on_response(msgid, error, result, addr)
172
- raise RPCError.new("response message on server session")
178
+ raise Error.new("response message on server session")
173
179
  end
174
180
  end
175
181
 
@@ -34,6 +34,15 @@ class UNIXTransport
34
34
  @pac = MessagePack::Unpacker.new
35
35
  end
36
36
 
37
+ # from Rev::TCPSocket
38
+ def on_readable
39
+ super
40
+ rescue
41
+ # FIXME send Connection Close message
42
+ # FIXME log
43
+ close
44
+ end
45
+
37
46
  # from Rev::UNIXSocket
38
47
  def on_read(data)
39
48
  @pac.feed(data)
@@ -90,12 +99,12 @@ class UNIXClientTransport
90
99
 
91
100
  # MessageReceiver interface
92
101
  def on_request(msgid, method, param)
93
- raise RPCError.new("request message on client session")
102
+ raise Error.new("request message on client session")
94
103
  end
95
104
 
96
105
  # MessageReceiver interface
97
106
  def on_notify(method, param)
98
- raise RPCError.new("notify message on client session")
107
+ raise Error.new("notify message on client session")
99
108
  end
100
109
 
101
110
  # MessageReceiver interface
@@ -155,7 +164,7 @@ class UNIXServerTransport
155
164
 
156
165
  # MessageReceiver interface
157
166
  def on_response(msgid, error, result)
158
- raise RPCError.new("response message on server session")
167
+ raise Error.new("response message on server session")
159
168
  end
160
169
  end
161
170
  end
@@ -0,0 +1,7 @@
1
+ module MessagePack
2
+ module RPC
3
+
4
+ VERSION = '0.4.1'
5
+
6
+ end
7
+ end
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
  require File.dirname(__FILE__) + '/test_helper.rb'
3
- require 'test/unit'
4
3
 
5
4
  $port = 65500
6
5
 
data/test/test_helper.rb CHANGED
@@ -1,3 +1,7 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue LoadError
4
+ end
1
5
  require 'test/unit'
2
6
  $LOAD_PATH.unshift File.dirname(__FILE__)+'/../lib'
3
7
  require 'msgpack/rpc'
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msgpack-rpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ hash: 13
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 1
10
+ version: 0.4.1
5
11
  platform: ruby
6
12
  authors:
7
13
  - FURUHASHI Sadayuki
@@ -9,29 +15,41 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-05-29 00:00:00 +09:00
18
+ date: 2010-08-27 00:00:00 +09:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: msgpack
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 0
32
+ - 4
33
+ - 1
23
34
  version: 0.4.1
24
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: rev
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 19
46
+ segments:
47
+ - 0
48
+ - 3
49
+ - 0
33
50
  version: 0.3.0
34
- version:
51
+ type: :runtime
52
+ version_requirements: *id002
35
53
  description:
36
54
  email: frsyuki@users.sourceforge.jp
37
55
  executables: []
@@ -41,13 +59,20 @@ extensions: []
41
59
  extra_rdoc_files: []
42
60
 
43
61
  files:
62
+ - AUTHORS
63
+ - ChangeLog
64
+ - NOTICE
65
+ - README
66
+ - lib/msgpack/rpc.rb
44
67
  - lib/msgpack/rpc/address.rb
45
68
  - lib/msgpack/rpc/client.rb
46
69
  - lib/msgpack/rpc/dispatcher.rb
47
70
  - lib/msgpack/rpc/exception.rb
71
+ - lib/msgpack/rpc/exception.rb.old
48
72
  - lib/msgpack/rpc/future.rb
49
73
  - lib/msgpack/rpc/loop.rb
50
74
  - lib/msgpack/rpc/message.rb
75
+ - lib/msgpack/rpc/multi_future.rb
51
76
  - lib/msgpack/rpc/server.rb
52
77
  - lib/msgpack/rpc/session.rb
53
78
  - lib/msgpack/rpc/session_pool.rb
@@ -55,38 +80,40 @@ files:
55
80
  - lib/msgpack/rpc/transport/tcp.rb
56
81
  - lib/msgpack/rpc/transport/udp.rb
57
82
  - lib/msgpack/rpc/transport/unix.rb
58
- - lib/msgpack/rpc.rb
83
+ - lib/msgpack/rpc/version.rb
59
84
  - test/msgpack_rpc_test.rb
60
85
  - test/test_helper.rb
61
- - AUTHORS
62
- - ChangeLog
63
- - NOTICE
64
- - README
65
86
  has_rdoc: true
66
- homepage: http://msgpack.sourceforge.jp/
87
+ homepage: http://msgpack.org/
67
88
  licenses: []
68
89
 
69
90
  post_install_message:
70
- rdoc_options: []
71
-
91
+ rdoc_options:
92
+ - --charset=UTF-8
72
93
  require_paths:
73
94
  - lib
74
95
  required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
75
97
  requirements:
76
98
  - - ">="
77
99
  - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
78
103
  version: "0"
79
- version:
80
104
  required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
81
106
  requirements:
82
107
  - - ">="
83
108
  - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
111
+ - 0
84
112
  version: "0"
85
- version:
86
113
  requirements: []
87
114
 
88
115
  rubyforge_project: msgpack
89
- rubygems_version: 1.3.5
116
+ rubygems_version: 1.3.7
90
117
  signing_key:
91
118
  specification_version: 3
92
119
  summary: MessagePack-RPC, asynchronous RPC library using MessagePack