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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart b/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
index 60541f6acb960152c4b362b9d50cb6caa089a13b..a6c6c5187548a073df1f35cbb58b9a76e6c95ca1 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
@@ -17,13 +17,22 @@ abstract class RequestManager extends Observable {
/// List of responses.
@observable List<Map> responses = toObservable([]);
+ /// Decode [response] into a map.
+ Map decodeResponse(String response) {
+ var m;
+ try {
+ m = JSON.decode(response);
+ } catch (e, st) {
+ 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
+ };
+ return m;
+ }
+
/// Parse
void parseResponses(String responseString) {
- var r;
- try {
- r = JSON.decode(responseString);
- } catch (e) {
- setResponseError(e.message);
+ var r = decodeResponse(responseString);
+ if (r == null) {
+ return;
}
if (r is Map) {
setResponses([r]);
@@ -45,7 +54,8 @@ abstract class RequestManager extends Observable {
error = 'No service found. Did you run with --enable-vm-service ?';
}
setResponses([{
- 'type': 'RequestError',
+ 'type': 'Error',
+ 'errorType': 'RequestError',
'error': error
}]);
}
@@ -53,29 +63,127 @@ abstract class RequestManager extends Observable {
void setResponseError(String message) {
setResponses([{
'type': 'Error',
+ 'errorType': 'ResponseError',
'text': message
}]);
+ Logger.root.severe(message);
+ }
+
+ static final RegExp _codeMatcher = new RegExp(r'/isolates/\d+/code/');
+ static bool isCodeRequest(url) => _codeMatcher.hasMatch(url);
+ static int codeAddressFromRequest(String url) {
+ Match m = _codeMatcher.matchAsPrefix(url);
+ if (m == null) {
+ return 0;
+ }
+ try {
+ var a = int.parse(m.input.substring(m.end), radix: 16);
+ return a;
+ } catch (e) {
+ return 0;
+ }
+ }
+
+ static final RegExp _isolateMatcher = new RegExp(r"/isolates/\d+");
+ static String isolatePrefixFromRequest(String url) {
+ Match m = _isolateMatcher.matchAsPrefix(url);
+ if (m == null) {
+ return null;
+ }
+ return m.input.substring(m.start, m.end);
+ }
+
+ static String isolateIdFromRequest(String url) {
+ var prefix = isolatePrefixFromRequest(url);
+ if (prefix == null) {
+ return null;
+ }
+ // Chop off the '/'.
+ return prefix.substring(1);
}
- /// Request [requestString] from the VM service. Updates [responses].
+ void _setModelResponse(String type, String modelName, dynamic model) {
+ var response = {
+ 'type': type,
+ modelName: model
+ };
+ setResponses([response]);
+ }
+
+ /// Handle 'Code' requests
+ void _getCode(String requestString) {
+ var isolateId = isolateIdFromRequest(requestString);
+ if (isolateId == null) {
+ setResponseError('$isolateId is not an isolate id.');
+ return;
+ }
+ var isolate = _application.isolateManager.getIsolate(isolateId);
+ if (isolate == null) {
+ setResponseError('$isolateId could not be found.');
+ return;
+ }
+ var address = codeAddressFromRequest(requestString);
+ if (address == 0) {
+ setResponseError('$requestString is not a valid code request.');
+ return;
+ }
+ var code = isolate.findCodeByAddress(address);
+ if (code != null) {
+ Logger.root.info(
+ 'Found code with 0x${address.toRadixString(16)} in isolate.');
+ _setModelResponse('Code', 'code', code);
+ return;
+ }
+ request(requestString).then((responseString) {
+ var map = decodeResponse(responseString);
+ if (map == null) {
+ return;
+ }
+ assert(map['type'] == 'Code');
+ var code = new Code.fromMap(map);
+ Logger.root.info(
+ 'Added code with 0x${address.toRadixString(16)} to isolate.');
+ isolate.codes.add(code);
+ _setModelResponse('Code', 'code', code);
+ }).catchError(_requestCatchError);
+ }
+
+ void _requestCatchError(e, st) {
+ if (e is HttpRequest) {
+ setResponseRequestError(e.target);
+ } else {
+ setResponseError('$e $st');
+ }
+ }
+
+ /// Request [request] from the VM service. Updates [responses].
/// Will trigger [interceptor] if one is set.
void get(String requestString) {
+ if (isCodeRequest(requestString)) {
+ _getCode(requestString);
+ return;
+ }
request(requestString).then((responseString) {
parseResponses(responseString);
- }).catchError((e) {
- setResponseRequestError(e.target);
- return null;
- });
+ }).catchError(_requestCatchError);
}
/// Abstract method. Given the [requestString], return a String in the
/// future which contains the reply from the VM service.
Future<String> request(String requestString);
+
+ Future<Map> requestMap(String requestString) {
+ return request(requestString).then((response) {
+ 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.
+ return m;
+ });
+ }
}
class HttpRequestManager extends RequestManager {
Future<String> request(String requestString) {
+ Logger.root.info('Requesting $requestString');
return HttpRequest.getString(prefix + requestString);
}
}

Powered by Google App Engine
This is Rietveld 408576698