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

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, 4 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 Metric._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 Metric._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 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 return new Future.value(objectClass); 696 return new Future.value(objectClass);
691 } 697 }
692 698
693 ServiceObject getFromMap(ObservableMap map) { 699 ServiceObject getFromMap(ObservableMap map) {
694 if (map == null) { 700 if (map == null) {
695 return null; 701 return null;
696 } 702 }
697 String id = map['id']; 703 String id = map['id'];
698 var obj = _cache[id]; 704 var obj = _cache[id];
699 if (obj != null) { 705 if (obj != null) {
706 // Consider calling update when map is not a reference.
700 return obj; 707 return obj;
701 } 708 }
702 // Build the object from the map directly. 709 // Build the object from the map directly.
703 obj = new ServiceObject._fromMap(this, map); 710 obj = new ServiceObject._fromMap(this, map);
704 if (obj != null && obj.canCache) { 711 if (obj != null && obj.canCache) {
705 _cache[id] = obj; 712 _cache[id] = obj;
706 } 713 }
707 return obj; 714 return obj;
708 } 715 }
709 716
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 return get("debug/resume").then((result) { 1009 return get("debug/resume").then((result) {
1003 if (result is DartError) { 1010 if (result is DartError) {
1004 // TODO(turnidge): Handle this more gracefully. 1011 // TODO(turnidge): Handle this more gracefully.
1005 Logger.root.severe(result.message); 1012 Logger.root.severe(result.message);
1006 } 1013 }
1007 return isolate.reload(); 1014 return isolate.reload();
1008 }); 1015 });
1009 } 1016 }
1010 1017
1011 Future stepInto() { 1018 Future stepInto() {
1012 print('isolate.stepInto');
1013 return get("debug/resume?step=into").then((result) { 1019 return get("debug/resume?step=into").then((result) {
1014 if (result is DartError) { 1020 if (result is DartError) {
1015 // TODO(turnidge): Handle this more gracefully. 1021 // TODO(turnidge): Handle this more gracefully.
1016 Logger.root.severe(result.message); 1022 Logger.root.severe(result.message);
1017 } 1023 }
1018 return isolate.reload(); 1024 return isolate.reload();
1019 }); 1025 });
1020 } 1026 }
1021 1027
1022 Future stepOver() { 1028 Future stepOver() {
1023 return get("debug/resume?step=over").then((result) { 1029 return get("debug/resume?step=over").then((result) {
1024 if (result is DartError) { 1030 if (result is DartError) {
1025 // TODO(turnidge): Handle this more gracefully. 1031 // TODO(turnidge): Handle this more gracefully.
1026 Logger.root.severe(result.message); 1032 Logger.root.severe(result.message);
1027 } 1033 }
1028 return isolate.reload(); 1034 return isolate.reload();
1029 }); 1035 });
1030 } 1036 }
1031 1037
1032 Future stepOut() { 1038 Future stepOut() {
1033 return get("debug/resume?step=out").then((result) { 1039 return get("debug/resume?step=out").then((result) {
1034 if (result is DartError) { 1040 if (result is DartError) {
1035 // TODO(turnidge): Handle this more gracefully. 1041 // TODO(turnidge): Handle this more gracefully.
1036 Logger.root.severe(result.message); 1042 Logger.root.severe(result.message);
1037 } 1043 }
1038 return isolate.reload(); 1044 return isolate.reload();
1039 }); 1045 });
1040 } 1046 }
1047
1048 final ObservableMap<String, Metric> metrics =
1049 new ObservableMap<String, Metric>();
1050
1051 Future<ObservableMap<String, Metric>> refreshMetrics() {
1052 return get('metrics').then((result) {
1053 if (result is DartError) {
1054 // TODO(turnidge): Handle this more gracefully.
1055 Logger.root.severe(result.message);
1056 }
1057 // Clear metrics map.
1058 metrics.clear();
1059 // Repopulate metrics map.
1060 var members = result['members'];
1061 for (var metric in members) {
1062 metrics[metric.name] = metric;
1063 }
1064 });
1065 }
1041 } 1066 }
1042 1067
1043 /// A [ServiceObject] which implements [ObservableMap]. 1068 /// A [ServiceObject] which implements [ObservableMap].
1044 class ServiceMap extends ServiceObject implements ObservableMap { 1069 class ServiceMap extends ServiceObject implements ObservableMap {
1045 final ObservableMap _map = new ObservableMap(); 1070 final ObservableMap _map = new ObservableMap();
1046 static String objectIdRingPrefix = 'objects/'; 1071 static String objectIdRingPrefix = 'objects/';
1047 1072
1048 bool get canCache { 1073 bool get canCache {
1049 return (_serviceType == 'Class' || 1074 return (_serviceType == 'Class' ||
1050 _serviceType == 'Function' || 1075 _serviceType == 'Function' ||
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1508 if (!_isTrivialToken(token)) { 1533 if (!_isTrivialToken(token)) {
1509 return false; 1534 return false;
1510 } 1535 }
1511 } 1536 }
1512 } 1537 }
1513 return true; 1538 return true;
1514 } 1539 }
1515 1540
1516 ScriptLine(this.script, this.line, this.text) { 1541 ScriptLine(this.script, this.line, this.text) {
1517 possibleBpt = !_isTrivialLine(text); 1542 possibleBpt = !_isTrivialLine(text);
1518 1543
1519 // TODO(turnidge): This is not so efficient. Consider improving. 1544 // TODO(turnidge): This is not so efficient. Consider improving.
1520 for (var bpt in this.script.isolate.breakpoints['breakpoints']) { 1545 for (var bpt in this.script.isolate.breakpoints['breakpoints']) {
1521 var bptScript = bpt['location']['script']; 1546 var bptScript = bpt['location']['script'];
1522 var bptTokenPos = bpt['location']['tokenPos']; 1547 var bptTokenPos = bpt['location']['tokenPos'];
1523 if (bptScript == this.script && 1548 if (bptScript == this.script &&
1524 bptScript.tokenToLine(bptTokenPos) == line) { 1549 bptScript.tokenToLine(bptTokenPos) == line) {
1525 this.bpt = bpt; 1550 this.bpt = bpt;
1526 } 1551 }
1527 } 1552 }
1528 } 1553 }
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
2186 localAddress = map['localAddress']; 2211 localAddress = map['localAddress'];
2187 localPort = map['localPort']; 2212 localPort = map['localPort'];
2188 remoteAddress = map['remoteAddress']; 2213 remoteAddress = map['remoteAddress'];
2189 remotePort = map['remotePort']; 2214 remotePort = map['remotePort'];
2190 2215
2191 fd = map['fd']; 2216 fd = map['fd'];
2192 socketOwner = map['owner']; 2217 socketOwner = map['owner'];
2193 } 2218 }
2194 } 2219 }
2195 2220
2221 class MetricSample {
2222 final double value;
2223 final DateTime time;
2224 MetricSample(this.value) : time = new DateTime.now();
2225 }
2226
2227 class Metric extends ServiceObject {
2228 Metric._empty(ServiceObjectOwner owner) : super._empty(owner) {
2229 }
2230
2231 bool get canCache => true;
2232 bool get immutable => false;
2233
2234 @observable bool recording = false;
2235 MetricPoller poller;
2236
2237 // 8 seconds, 4 seconds, 2 seconds, 1 second, and one hundred milliseconds.
2238 static final List<int> pollPeriods = [8000, 4000, 2000, 1000, 100];
koda 2014/08/11 16:34:53 Couldn't you traverse the DOM to get this list ins
Cutch 2014/08/27 22:25:40 The service library doesn't import dart:html. Also
2239
2240 final ObservableList<MetricSample> samples =
2241 new ObservableList<MetricSample>();
2242 int _sampleBufferSize = 100;
2243 int get sampleBufferSize => _sampleBufferSize;
2244 set sampleBufferSize(int size) {
2245 _sampleBufferSize = size;
2246 _removeOld();
2247 }
2248
2249 void addSample(MetricSample sample) {
2250 samples.add(sample);
2251 _removeOld();
2252 }
2253
2254 void _removeOld() {
2255 if (samples.length > _sampleBufferSize) {
2256 int count = samples.length - _sampleBufferSize;
2257 samples.removeRange(0, count);
koda 2014/08/11 16:34:54 I assume ObservableList is backed by an array? If
Cutch 2014/08/27 22:25:40 Done.
2258 }
2259 }
2260
2261 @observable String description;
2262 @observable double value = 0.0;
2263 @observable double min;
2264 @observable double max;
2265
2266 bool get isGauge => (min != null) && (max != null);
koda 2014/08/11 16:34:53 The fact that 'null' is valid and has this particu
Cutch 2014/08/27 22:25:40 Noted.
2267
2268 void _update(ObservableMap map, bool mapIsRef) {
2269 name = map['name'];
2270 description = map['description'];
2271 vmName = map['name'];
2272 value = map['value'];
2273 min = map['min'];
2274 max = map['max'];
2275 }
2276 }
2277
2278 class MetricPoller {
2279 // Metrics to be polled.
2280 final List<Metric> metrics = new List<Metric>();
2281 final int period;
koda 2014/08/11 16:34:54 Redundant? In any case, avoid untyped times (or at
Cutch 2014/08/27 22:25:40 Redundant. Removed.
2282 final Duration _pollPeriod;
2283 Timer _pollTimer;
2284
2285 MetricPoller(int milliseconds) :
2286 period = milliseconds,
2287 _pollPeriod = new Duration(milliseconds: milliseconds) {
2288 start();
2289 }
2290
2291 void start() {
2292 _pollTimer = new Timer.periodic(_pollPeriod, _onPoll);
2293 }
2294
2295 void cancel() {
2296 if (_pollTimer != null) {
2297 _pollTimer.cancel();
2298 }
2299 _pollTimer = null;
2300 }
2301
2302 void _onPoll(_) {
2303 if (metrics.length == 0) {
koda 2014/08/11 16:34:53 Redundant.
Cutch 2014/08/27 22:25:40 Done.
2304 return;
2305 }
2306 // Reload metrics and add a sample to each.
2307 for (var i = 0; i < metrics.length; i++) {
koda 2014/08/11 16:34:53 Use for-in when possible.
Cutch 2014/08/27 22:25:40 Done.
2308 var metric = metrics[i];
2309 metric.reload().then((m) {
2310 m.addSample(new MetricSample(m.value));
2311 });
2312 }
2313 }
2314 }
2315
2196 // Convert any ServiceMaps representing a null instance into an actual null. 2316 // Convert any ServiceMaps representing a null instance into an actual null.
2197 _convertNull(obj) { 2317 _convertNull(obj) {
2198 if (obj is ServiceMap && 2318 if (obj is ServiceMap &&
2199 obj.serviceType == 'Null') { 2319 obj.serviceType == 'Null') {
2200 return null; 2320 return null;
2201 } 2321 }
2202 return obj; 2322 return obj;
2203 } 2323 }
2204 2324
2205 // Returns true if [map] is a service map. i.e. it has the following keys: 2325 // 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
2242 var v = list[i]; 2362 var v = list[i];
2243 if ((v is ObservableMap) && _isServiceMap(v)) { 2363 if ((v is ObservableMap) && _isServiceMap(v)) {
2244 list[i] = owner.getFromMap(v); 2364 list[i] = owner.getFromMap(v);
2245 } else if (v is ObservableList) { 2365 } else if (v is ObservableList) {
2246 _upgradeObservableList(v, owner); 2366 _upgradeObservableList(v, owner);
2247 } else if (v is ObservableMap) { 2367 } else if (v is ObservableMap) {
2248 _upgradeObservableMap(v, owner); 2368 _upgradeObservableMap(v, owner);
2249 } 2369 }
2250 } 2370 }
2251 } 2371 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698