Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: corelib/src/proxy.dart

Issue 8536006: rpc example for directory file listing (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fixed comment Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * Base class for all RpcProxy's
Siggi Cherem (dart-lang) 2011/11/11 23:41:51 generally use the dart-doc style through-out (e.g.
7 *
8 * RpcProxy objects run in the "client" isolate and have a SendPort which
9 * they use to send messages to RpcReceiver objects running in a "service"
10 * isolate.
11 */
12
13 class RpcProxy {
14 final Future<SendPort> futurePort;
Ben Laurie (Google) 2011/11/11 21:51:43 _futurePort?
15 RpcProxy(this.futurePort);
16
17 /**
18 * Called by derived classes to send a command through a SendPort to
19 * an RpcReceiver.
20 *
21 * parameters:
22 * command - String identifying what command to execute
23 * args - optional list of arguments to the command (this may contain other
24 * RpcProxy objects to refer to other target objects in the service
25 * isolate).
Ben Laurie (Google) 2011/11/11 21:51:43 How does that work? I don't see code to send RpcPr
mattsh 2011/11/11 22:16:02 Right. That's not in this CL yet, but plan to add
Siggi Cherem (dart-lang) 2011/11/11 23:41:51 is the purpose of this to establish a bi-direction
26 *
27 * returns:
28 * a Future object that will be set to the value that was
29 * received as a reply to the SendPort call.
30 */
31 Future sendCommand(String command, List args) {
32 Completer completer = new Completer();
33 futurePort.then((SendPort port) {
34 port.call({"command" : command, "args" : args}).receive((value, ignoreRe plyTo) {
Siggi Cherem (dart-lang) 2011/11/11 23:41:51 80
35 assert(ignoreReplyTo === null);
36 value = _filterException(value);
37 if (value is Exception) {
38 completer.completeException(value);
39 } else {
40 completer.complete(value);
41 }
42 }
43 );
44 });
45 return completer.future;
46 }
47
48 // TODO (mattsh) hack, remove once we have serializable exceptions
49 Object _filterException(Object value) {
50 // Check if value is a serialized exception.
51 Exception e = RpcException.parse(value);
52 if (e != null) {
53 return e;
54 } else {
55 return value;
56 }
57 }
58 }
59
60
61
62 /**
63 * Base class for all Receivers
64 *
65 * RpcReceiver objects have a ReceivePort, where they receive commands (from
66 * RpcProxy objects) that they interpret and translate into method
67 * calls on a "target" object.
68 *
69 * All RpcReceiver derived classes must implement the [receiveCommand] abstract
70 * method (where they actually command messages and call
71 * appropriate methods on the target object).
72 *
73 */
74 class RpcReceiver {
75
76 // static map of containing all receivers in this isolate. This is used
77 // to be able to find a receiver and target, given a SendPort.
78 static Map<SendPort, RpcReceiver> _receivers;
79 static _register(RpcReceiver receiver) {
80 if (_receivers == null) {
81 _receivers = new Map<SendPort, RpcReceiver>();
82 }
83 _receivers[receiver._receivePort.toSendPort()] = receiver;
84 }
85
86 static void closeAll() {
87 for (RpcReceiver receiver in _receivers.getValues()) {
88 receiver._receivePort.close();
89 }
90 }
91
92 // the port that this receiver will listen on
93 final ReceivePort _receivePort;
94
95 RpcReceiver(this._receivePort) {
96 // place this receiver in the receiver registry
97 _register(this);
98
99 // start listening on the receive port for command messages
100 _receivePort.receive((var message, SendPort replyTo) {
101 String command = message["command"];
102 List<Object> args = message["args"];
103
104 // Call the derived RpcReceiver to execute the command
105 // (if the command throws an exception, then catch the
106 // exception, serialize it, and send as the reply)
107 Object reply;
108 try {
109 reply = receiveCommand(message["command"], args);
110 } catch (Object e) {
111 reply = RpcException.format(e);
112 }
113
114 // send reply back to the proxy
115 replyTo.send(reply, null);
116 });
117 }
118
119 /**
120 * (implemented by derived classes).
121 *
122 * parameters -
123 * command - String identifying what command to execute
124 * on the target object
125 * args - list of arguments to the command (if any arguments
126 * were ReceivePorts, these have been translated to the
127 * corresponding target objects, so this List79 will not
128 * contain any ReceivePorts)
129 */
130 abstract Object receiveCommand(String command, List args);
131 }
132
133 // TODO - hack - need better way to serialize exceptions. For now
134 // we take the message, and prefix with a recognizable string.
135 class RpcException implements Exception {
136
137 static final String prefix = "RpcException:";
138
139 final String message;
140 const RpcException(this.message);
141
142 String toString() {
143 return message;
144 }
145
146 static String format(Exception e) {
147 return prefix + e.toString();
148 }
149
150 static RpcException parse(Object object) {
151 if (object === null || !(object is String)) {
152 return null;
153 }
154 String s = object;
155 if (!s.startsWith(prefix)) {
156 return null;
157 }
158 return new RpcException(s.substring(prefix.length, s.length));
159 }
160 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698