Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |