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

Side by Side Diff: runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart

Issue 135843006: Improve Code object support in service and observatory (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months 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
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of observatory; 5 part of observatory;
6 6
7 /// A request response interceptor is called for each response. 7 /// A request response interceptor is called for each response.
8 typedef void RequestResponseInterceptor(); 8 typedef void RequestResponseInterceptor();
9 9
10 abstract class RequestManager extends Observable { 10 abstract class RequestManager extends Observable {
11 ObservatoryApplication _application; 11 ObservatoryApplication _application;
12 ObservatoryApplication get application => _application; 12 ObservatoryApplication get application => _application;
13 RequestResponseInterceptor interceptor; 13 RequestResponseInterceptor interceptor;
14 14
15 /// The default request prefix is 127.0.0.1 on port 8181. 15 /// The default request prefix is 127.0.0.1 on port 8181.
16 @observable String prefix = 'http://127.0.0.1:8181'; 16 @observable String prefix = 'http://127.0.0.1:8181';
17 /// List of responses. 17 /// List of responses.
18 @observable List<Map> responses = toObservable([]); 18 @observable List<Map> responses = toObservable([]);
19 19
20 /// Decode [response] into a map.
21 Map decodeResponse(String response) {
22 var m;
23 try {
24 m = JSON.decode(response);
25 } catch (e, st) {
26 setResponseError('$e $st');
turnidge 2014/01/17 19:30:21 What if we returned the error response and checked
Cutch 2014/01/17 21:15:42 I'm going to punt on this because I plan on revisi
27 };
28 return m;
29 }
30
20 /// Parse 31 /// Parse
21 void parseResponses(String responseString) { 32 void parseResponses(String responseString) {
22 var r; 33 var r = decodeResponse(responseString);
23 try { 34 if (r == null) {
24 r = JSON.decode(responseString); 35 return;
25 } catch (e) {
26 setResponseError(e.message);
27 } 36 }
28 if (r is Map) { 37 if (r is Map) {
29 setResponses([r]); 38 setResponses([r]);
30 } else { 39 } else {
31 setResponses(r); 40 setResponses(r);
32 } 41 }
33 } 42 }
34 43
35 void setResponses(List<Map> r) { 44 void setResponses(List<Map> r) {
36 responses = toObservable(r); 45 responses = toObservable(r);
37 if (interceptor != null) { 46 if (interceptor != null) {
38 interceptor(); 47 interceptor();
39 } 48 }
40 } 49 }
41 50
42 void setResponseRequestError(HttpRequest request) { 51 void setResponseRequestError(HttpRequest request) {
43 String error = '${request.status} ${request.statusText}'; 52 String error = '${request.status} ${request.statusText}';
44 if (request.status == 0) { 53 if (request.status == 0) {
45 error = 'No service found. Did you run with --enable-vm-service ?'; 54 error = 'No service found. Did you run with --enable-vm-service ?';
46 } 55 }
47 setResponses([{ 56 setResponses([{
48 'type': 'RequestError', 57 'type': 'Error',
58 'errorType': 'RequestError',
49 'error': error 59 'error': error
50 }]); 60 }]);
51 } 61 }
52 62
53 void setResponseError(String message) { 63 void setResponseError(String message) {
54 setResponses([{ 64 setResponses([{
55 'type': 'Error', 65 'type': 'Error',
66 'errorType': 'ResponseError',
56 'text': message 67 'text': message
57 }]); 68 }]);
69 Logger.root.severe(message);
58 } 70 }
59 71
60 /// Request [requestString] from the VM service. Updates [responses]. 72 static final RegExp _codeMatcher = new RegExp(r'/isolates/\d+/code/');
73 static bool isCodeRequest(url) => _codeMatcher.hasMatch(url);
74 static int codeAddressFromRequest(String url) {
75 Match m = _codeMatcher.matchAsPrefix(url);
76 if (m == null) {
77 return 0;
78 }
79 try {
80 var a = int.parse(m.input.substring(m.end), radix: 16);
81 return a;
82 } catch (e) {
83 return 0;
84 }
85 }
86
87 static final RegExp _isolateMatcher = new RegExp(r"/isolates/\d+");
88 static String isolatePrefixFromRequest(String url) {
89 Match m = _isolateMatcher.matchAsPrefix(url);
90 if (m == null) {
91 return null;
92 }
93 return m.input.substring(m.start, m.end);
94 }
95
96 static String isolateIdFromRequest(String url) {
97 var prefix = isolatePrefixFromRequest(url);
98 if (prefix == null) {
99 return null;
100 }
101 // Chop off the '/'.
102 return prefix.substring(1);
103 }
104
105 void _setModelResponse(String type, String modelName, dynamic model) {
106 var response = {
107 'type': type,
108 modelName: model
109 };
110 setResponses([response]);
111 }
112
113 /// Handle 'Code' requests
114 void _getCode(String requestString) {
115 var isolateId = isolateIdFromRequest(requestString);
116 if (isolateId == null) {
117 setResponseError('$isolateId is not an isolate id.');
118 return;
119 }
120 var isolate = _application.isolateManager.getIsolate(isolateId);
121 if (isolate == null) {
122 setResponseError('$isolateId could not be found.');
123 return;
124 }
125 var address = codeAddressFromRequest(requestString);
126 if (address == 0) {
127 setResponseError('$requestString is not a valid code request.');
128 return;
129 }
130 var code = isolate.findCodeByAddress(address);
131 if (code != null) {
132 Logger.root.info(
133 'Found code with 0x${address.toRadixString(16)} in isolate.');
134 _setModelResponse('Code', 'code', code);
135 return;
136 }
137 request(requestString).then((responseString) {
138 var map = decodeResponse(responseString);
139 if (map == null) {
140 return;
141 }
142 assert(map['type'] == 'Code');
143 var code = new Code.fromMap(map);
144 Logger.root.info(
145 'Added code with 0x${address.toRadixString(16)} to isolate.');
146 isolate.codes.add(code);
147 _setModelResponse('Code', 'code', code);
148 }).catchError(_requestCatchError);
149 }
150
151 void _requestCatchError(e, st) {
152 if (e is HttpRequest) {
153 setResponseRequestError(e.target);
154 } else {
155 setResponseError('$e $st');
156 }
157 }
158
159 /// Request [request] from the VM service. Updates [responses].
61 /// Will trigger [interceptor] if one is set. 160 /// Will trigger [interceptor] if one is set.
62 void get(String requestString) { 161 void get(String requestString) {
162 if (isCodeRequest(requestString)) {
163 _getCode(requestString);
164 return;
165 }
63 request(requestString).then((responseString) { 166 request(requestString).then((responseString) {
64 parseResponses(responseString); 167 parseResponses(responseString);
65 }).catchError((e) { 168 }).catchError(_requestCatchError);
66 setResponseRequestError(e.target);
67 return null;
68 });
69 } 169 }
70 170
71 /// Abstract method. Given the [requestString], return a String in the 171 /// Abstract method. Given the [requestString], return a String in the
72 /// future which contains the reply from the VM service. 172 /// future which contains the reply from the VM service.
73 Future<String> request(String requestString); 173 Future<String> request(String requestString);
174
175 Future<Map> requestMap(String requestString) {
176 return request(requestString).then((response) {
177 var m = JSON.decode(response);
turnidge 2014/01/17 19:30:21 We don't check for JSON decoding errors as we do a
Cutch 2014/01/17 21:15:42 Done.
178 return m;
179 });
180 }
74 } 181 }
75 182
76 183
77 class HttpRequestManager extends RequestManager { 184 class HttpRequestManager extends RequestManager {
78 Future<String> request(String requestString) { 185 Future<String> request(String requestString) {
186 Logger.root.info('Requesting $requestString');
79 return HttpRequest.getString(prefix + requestString); 187 return HttpRequest.getString(prefix + requestString);
80 } 188 }
81 } 189 }
82 190
83 class PostMessageRequestManager extends RequestManager { 191 class PostMessageRequestManager extends RequestManager {
84 final Map _outstandingRequests = new Map(); 192 final Map _outstandingRequests = new Map();
85 int _requestSerial = 0; 193 int _requestSerial = 0;
86 PostMessageRequestManager() { 194 PostMessageRequestManager() {
87 window.onMessage.listen(_messageHandler); 195 window.onMessage.listen(_messageHandler);
88 } 196 }
(...skipping 24 matching lines...) Expand all
113 message['query'] = requestString; 221 message['query'] = requestString;
114 _requestSerial++; 222 _requestSerial++;
115 223
116 var completer = new Completer(); 224 var completer = new Completer();
117 _outstandingRequests[idString] = completer; 225 _outstandingRequests[idString] = completer;
118 226
119 window.parent.postMessage(JSON.encode(message), '*'); 227 window.parent.postMessage(JSON.encode(message), '*');
120 return completer.future; 228 return completer.future;
121 } 229 }
122 } 230 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698