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

Side by Side Diff: runtime/bin/vmservice/observatory/lib/src/service/object.dart

Issue 457803002: Initial UI for Metrics in Observatory (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 service; 5 part of service;
6 6
7 /// A [ServiceObject] is an object known to the VM service and is tied 7 /// A [ServiceObject] is an object known to the VM service and is tied
8 /// to an owning [Isolate]. 8 /// to an owning [Isolate].
9 abstract class ServiceObject extends Observable { 9 abstract class ServiceObject extends Observable {
10 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { 10 static int LexicalSortName(ServiceObject o1, ServiceObject o2) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 var type = _stripRef(map['type']); 69 var type = _stripRef(map['type']);
70 var obj = null; 70 var obj = null;
71 assert(type != 'VM'); 71 assert(type != 'VM');
72 switch (type) { 72 switch (type) {
73 case 'Class': 73 case 'Class':
74 obj = new Class._empty(owner); 74 obj = new Class._empty(owner);
75 break; 75 break;
76 case 'Code': 76 case 'Code':
77 obj = new Code._empty(owner); 77 obj = new Code._empty(owner);
78 break; 78 break;
79 case 'Counter':
80 obj = new ServiceMetric._empty(owner);
81 break;
79 case 'Error': 82 case 'Error':
80 obj = new DartError._empty(owner); 83 obj = new DartError._empty(owner);
81 break; 84 break;
82 case 'Function': 85 case 'Function':
83 obj = new ServiceFunction._empty(owner); 86 obj = new ServiceFunction._empty(owner);
84 break; 87 break;
88 case 'Gauge':
89 obj = new ServiceMetric._empty(owner);
90 break;
85 case 'Isolate': 91 case 'Isolate':
86 obj = new Isolate._empty(owner.vm); 92 obj = new Isolate._empty(owner.vm);
87 break; 93 break;
88 case 'Library': 94 case 'Library':
89 obj = new Library._empty(owner); 95 obj = new Library._empty(owner);
90 break; 96 break;
91 case 'ServiceError': 97 case 'ServiceError':
92 obj = new ServiceError._empty(owner); 98 obj = new ServiceError._empty(owner);
93 break; 99 break;
94 case 'ServiceEvent': 100 case 'ServiceEvent':
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 return new Future.value(objectClass); 700 return new Future.value(objectClass);
695 } 701 }
696 702
697 ServiceObject getFromMap(ObservableMap map) { 703 ServiceObject getFromMap(ObservableMap map) {
698 if (map == null) { 704 if (map == null) {
699 return null; 705 return null;
700 } 706 }
701 String id = map['id']; 707 String id = map['id'];
702 var obj = _cache[id]; 708 var obj = _cache[id];
703 if (obj != null) { 709 if (obj != null) {
710 // Consider calling update when map is not a reference.
704 return obj; 711 return obj;
705 } 712 }
706 // Build the object from the map directly. 713 // Build the object from the map directly.
707 obj = new ServiceObject._fromMap(this, map); 714 obj = new ServiceObject._fromMap(this, map);
708 if (obj != null && obj.canCache) { 715 if (obj != null && obj.canCache) {
709 _cache[id] = obj; 716 _cache[id] = obj;
710 } 717 }
711 return obj; 718 return obj;
712 } 719 }
713 720
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 return get("debug/resume").then((result) { 1013 return get("debug/resume").then((result) {
1007 if (result is DartError) { 1014 if (result is DartError) {
1008 // TODO(turnidge): Handle this more gracefully. 1015 // TODO(turnidge): Handle this more gracefully.
1009 Logger.root.severe(result.message); 1016 Logger.root.severe(result.message);
1010 } 1017 }
1011 return isolate.reload(); 1018 return isolate.reload();
1012 }); 1019 });
1013 } 1020 }
1014 1021
1015 Future stepInto() { 1022 Future stepInto() {
1016 print('isolate.stepInto');
1017 return get("debug/resume?step=into").then((result) { 1023 return get("debug/resume?step=into").then((result) {
1018 if (result is DartError) { 1024 if (result is DartError) {
1019 // TODO(turnidge): Handle this more gracefully. 1025 // TODO(turnidge): Handle this more gracefully.
1020 Logger.root.severe(result.message); 1026 Logger.root.severe(result.message);
1021 } 1027 }
1022 return isolate.reload(); 1028 return isolate.reload();
1023 }); 1029 });
1024 } 1030 }
1025 1031
1026 Future stepOver() { 1032 Future stepOver() {
1027 return get("debug/resume?step=over").then((result) { 1033 return get("debug/resume?step=over").then((result) {
1028 if (result is DartError) { 1034 if (result is DartError) {
1029 // TODO(turnidge): Handle this more gracefully. 1035 // TODO(turnidge): Handle this more gracefully.
1030 Logger.root.severe(result.message); 1036 Logger.root.severe(result.message);
1031 } 1037 }
1032 return isolate.reload(); 1038 return isolate.reload();
1033 }); 1039 });
1034 } 1040 }
1035 1041
1036 Future stepOut() { 1042 Future stepOut() {
1037 return get("debug/resume?step=out").then((result) { 1043 return get("debug/resume?step=out").then((result) {
1038 if (result is DartError) { 1044 if (result is DartError) {
1039 // TODO(turnidge): Handle this more gracefully. 1045 // TODO(turnidge): Handle this more gracefully.
1040 Logger.root.severe(result.message); 1046 Logger.root.severe(result.message);
1041 } 1047 }
1042 return isolate.reload(); 1048 return isolate.reload();
1043 }); 1049 });
1044 } 1050 }
1045 1051
1052 final ObservableMap<String, ServiceMetric> dartMetrics =
1053 new ObservableMap<String, ServiceMetric>();
1054
1055 final ObservableMap<String, ServiceMetric> vmMetrics =
1056 new ObservableMap<String, ServiceMetric>();
1057
1058 Future<ObservableMap<String, ServiceMetric>> _refreshMetrics(
1059 String id,
1060 ObservableMap<String, ServiceMetric> metricsMap) {
1061 return get(id).then((result) {
1062 if (result is DartError) {
1063 // TODO(turnidge): Handle this more gracefully.
1064 Logger.root.severe(result.message);
1065 return null;
1066 }
1067 // Clear metrics map.
1068 metricsMap.clear();
1069 // Repopulate metrics map.
1070 var members = result['members'];
1071 for (var metric in members) {
1072 metricsMap[metric.id] = metric;
1073 }
1074 return metricsMap;
1075 });
1076 }
1077
1078 Future<ObservableMap<String, ServiceMetric>> refreshDartMetrics() {
1079 return _refreshMetrics('metrics', dartMetrics);
1080 }
1081
1082 Future<ObservableMap<String, ServiceMetric>> refreshVMMetrics() {
1083 return _refreshMetrics('metrics/vm', vmMetrics);
1084 }
1085
1086 Future refreshMetrics() {
1087 return refreshDartMetrics().then((_) => refreshVMMetrics());
1088 }
1089
1046 String toString() => "Isolate($_id)"; 1090 String toString() => "Isolate($_id)";
1047 } 1091 }
1048 1092
1049 /// A [ServiceObject] which implements [ObservableMap]. 1093 /// A [ServiceObject] which implements [ObservableMap].
1050 class ServiceMap extends ServiceObject implements ObservableMap { 1094 class ServiceMap extends ServiceObject implements ObservableMap {
1051 final ObservableMap _map = new ObservableMap(); 1095 final ObservableMap _map = new ObservableMap();
1052 static String objectIdRingPrefix = 'objects/'; 1096 static String objectIdRingPrefix = 'objects/';
1053 1097
1054 bool get canCache { 1098 bool get canCache {
1055 return (_serviceType == 'Class' || 1099 return (_serviceType == 'Class' ||
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1534 if (!_isTrivialToken(token)) { 1578 if (!_isTrivialToken(token)) {
1535 return false; 1579 return false;
1536 } 1580 }
1537 } 1581 }
1538 } 1582 }
1539 return true; 1583 return true;
1540 } 1584 }
1541 1585
1542 ScriptLine(this.script, this.line, this.text) { 1586 ScriptLine(this.script, this.line, this.text) {
1543 possibleBpt = !_isTrivialLine(text); 1587 possibleBpt = !_isTrivialLine(text);
1544 1588
1545 // TODO(turnidge): This is not so efficient. Consider improving. 1589 // TODO(turnidge): This is not so efficient. Consider improving.
1546 for (var bpt in this.script.isolate.breakpoints['breakpoints']) { 1590 for (var bpt in this.script.isolate.breakpoints['breakpoints']) {
1547 var bptScript = bpt['location']['script']; 1591 var bptScript = bpt['location']['script'];
1548 var bptTokenPos = bpt['location']['tokenPos']; 1592 var bptTokenPos = bpt['location']['tokenPos'];
1549 if (bptScript == this.script && 1593 if (bptScript == this.script &&
1550 bptScript.tokenToLine(bptTokenPos) == line) { 1594 bptScript.tokenToLine(bptTokenPos) == line) {
1551 this.bpt = bpt; 1595 this.bpt = bpt;
1552 } 1596 }
1553 } 1597 }
1554 } 1598 }
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 localAddress = map['localAddress']; 2256 localAddress = map['localAddress'];
2213 localPort = map['localPort']; 2257 localPort = map['localPort'];
2214 remoteAddress = map['remoteAddress']; 2258 remoteAddress = map['remoteAddress'];
2215 remotePort = map['remotePort']; 2259 remotePort = map['remotePort'];
2216 2260
2217 fd = map['fd']; 2261 fd = map['fd'];
2218 socketOwner = map['owner']; 2262 socketOwner = map['owner'];
2219 } 2263 }
2220 } 2264 }
2221 2265
2266 class MetricSample {
2267 final double value;
2268 final DateTime time;
2269 MetricSample(this.value) : time = new DateTime.now();
2270 }
2271
2272 class ServiceMetric extends ServiceObject {
2273 ServiceMetric._empty(ServiceObjectOwner owner) : super._empty(owner) {
2274 }
2275
2276 bool get canCache => true;
2277 bool get immutable => false;
2278
2279 @observable bool recording = false;
2280 MetricPoller poller;
2281
2282 final ObservableList<MetricSample> samples =
2283 new ObservableList<MetricSample>();
2284 int _sampleBufferSize = 100;
2285 int get sampleBufferSize => _sampleBufferSize;
2286 set sampleBufferSize(int size) {
2287 _sampleBufferSize = size;
2288 _removeOld();
2289 }
2290
2291 void addSample(MetricSample sample) {
2292 samples.add(sample);
2293 _removeOld();
2294 }
2295
2296 void _removeOld() {
2297 // TODO(johnmccutchan): If this becomes hot, consider using a circular
2298 // buffer.
2299 if (samples.length > _sampleBufferSize) {
2300 int count = samples.length - _sampleBufferSize;
2301 samples.removeRange(0, count);
2302 }
2303 }
2304
2305 @observable String description;
2306 @observable double value = 0.0;
2307 // Only a guage has a non-null min and max.
2308 @observable double min;
2309 @observable double max;
2310
2311 bool get isGauge => (min != null) && (max != null);
2312
2313 void _update(ObservableMap map, bool mapIsRef) {
2314 name = map['name'];
2315 description = map['description'];
2316 vmName = map['name'];
2317 value = map['value'];
2318 min = map['min'];
2319 max = map['max'];
2320 }
2321
2322 String toString() => "ServiceMetric($_id)";
2323 }
2324
2325 class MetricPoller {
2326 // Metrics to be polled.
2327 final List<ServiceMetric> metrics = new List<ServiceMetric>();
2328 final Duration pollPeriod;
2329 Timer _pollTimer;
2330
2331 MetricPoller(int milliseconds) :
2332 pollPeriod = new Duration(milliseconds: milliseconds) {
2333 start();
2334 }
2335
2336 void start() {
2337 _pollTimer = new Timer.periodic(pollPeriod, _onPoll);
2338 }
2339
2340 void cancel() {
2341 if (_pollTimer != null) {
2342 _pollTimer.cancel();
2343 }
2344 _pollTimer = null;
2345 }
2346
2347 void _onPoll(_) {
2348 // Reload metrics and add a sample to each.
2349 for (var metric in metrics) {
2350 metric.reload().then((m) {
2351 m.addSample(new MetricSample(m.value));
2352 });
2353 }
2354 }
2355 }
2356
2222 // Convert any ServiceMaps representing a null instance into an actual null. 2357 // Convert any ServiceMaps representing a null instance into an actual null.
2223 _convertNull(obj) { 2358 _convertNull(obj) {
2224 if (obj is ServiceMap && 2359 if (obj is ServiceMap &&
2225 obj.serviceType == 'Null') { 2360 obj.serviceType == 'Null') {
2226 return null; 2361 return null;
2227 } 2362 }
2228 return obj; 2363 return obj;
2229 } 2364 }
2230 2365
2231 // Returns true if [map] is a service map. i.e. it has the following keys: 2366 // Returns true if [map] is a service map. i.e. it has the following keys:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 var v = list[i]; 2403 var v = list[i];
2269 if ((v is ObservableMap) && _isServiceMap(v)) { 2404 if ((v is ObservableMap) && _isServiceMap(v)) {
2270 list[i] = owner.getFromMap(v); 2405 list[i] = owner.getFromMap(v);
2271 } else if (v is ObservableList) { 2406 } else if (v is ObservableList) {
2272 _upgradeObservableList(v, owner); 2407 _upgradeObservableList(v, owner);
2273 } else if (v is ObservableMap) { 2408 } else if (v is ObservableMap) {
2274 _upgradeObservableMap(v, owner); 2409 _upgradeObservableMap(v, owner);
2275 } 2410 }
2276 } 2411 }
2277 } 2412 }
OLDNEW
« no previous file with comments | « runtime/bin/vmservice/observatory/lib/src/elements/vm_view.html ('k') | runtime/bin/vmservice/observatory/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698