msgpack-rpc 0.4.0 → 0.4.1

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