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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/bin/vmservice/observatory/lib/src/service/object.dart
diff --git a/runtime/bin/vmservice/observatory/lib/src/service/object.dart b/runtime/bin/vmservice/observatory/lib/src/service/object.dart
index 32055de734f4b986228c6f2300ff393a7c887be1..ea40c3c92e515d5453eea4d1e825e34475de643b 100644
--- a/runtime/bin/vmservice/observatory/lib/src/service/object.dart
+++ b/runtime/bin/vmservice/observatory/lib/src/service/object.dart
@@ -76,12 +76,18 @@ abstract class ServiceObject extends Observable {
case 'Code':
obj = new Code._empty(owner);
break;
+ case 'Counter':
+ obj = new Metric._empty(owner);
+ break;
case 'Error':
obj = new DartError._empty(owner);
break;
case 'Function':
obj = new ServiceFunction._empty(owner);
break;
+ case 'Gauge':
+ obj = new Metric._empty(owner);
+ break;
case 'Isolate':
obj = new Isolate._empty(owner.vm);
break;
@@ -697,6 +703,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
String id = map['id'];
var obj = _cache[id];
if (obj != null) {
+ // Consider calling update when map is not a reference.
return obj;
}
// Build the object from the map directly.
@@ -1009,7 +1016,6 @@ class Isolate extends ServiceObjectOwner with Coverage {
}
Future stepInto() {
- print('isolate.stepInto');
return get("debug/resume?step=into").then((result) {
if (result is DartError) {
// TODO(turnidge): Handle this more gracefully.
@@ -1038,6 +1044,25 @@ class Isolate extends ServiceObjectOwner with Coverage {
return isolate.reload();
});
}
+
+ final ObservableMap<String, Metric> metrics =
+ new ObservableMap<String, Metric>();
+
+ Future<ObservableMap<String, Metric>> refreshMetrics() {
+ return get('metrics').then((result) {
+ if (result is DartError) {
+ // TODO(turnidge): Handle this more gracefully.
+ Logger.root.severe(result.message);
+ }
+ // Clear metrics map.
+ metrics.clear();
+ // Repopulate metrics map.
+ var members = result['members'];
+ for (var metric in members) {
+ metrics[metric.name] = metric;
+ }
+ });
+ }
}
/// A [ServiceObject] which implements [ObservableMap].
@@ -1515,7 +1540,7 @@ class ScriptLine extends Observable {
ScriptLine(this.script, this.line, this.text) {
possibleBpt = !_isTrivialLine(text);
-
+
// TODO(turnidge): This is not so efficient. Consider improving.
for (var bpt in this.script.isolate.breakpoints['breakpoints']) {
var bptScript = bpt['location']['script'];
@@ -2193,6 +2218,101 @@ class Socket extends ServiceObject {
}
}
+class MetricSample {
+ final double value;
+ final DateTime time;
+ MetricSample(this.value) : time = new DateTime.now();
+}
+
+class Metric extends ServiceObject {
+ Metric._empty(ServiceObjectOwner owner) : super._empty(owner) {
+ }
+
+ bool get canCache => true;
+ bool get immutable => false;
+
+ @observable bool recording = false;
+ MetricPoller poller;
+
+ // 8 seconds, 4 seconds, 2 seconds, 1 second, and one hundred milliseconds.
+ 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
+
+ final ObservableList<MetricSample> samples =
+ new ObservableList<MetricSample>();
+ int _sampleBufferSize = 100;
+ int get sampleBufferSize => _sampleBufferSize;
+ set sampleBufferSize(int size) {
+ _sampleBufferSize = size;
+ _removeOld();
+ }
+
+ void addSample(MetricSample sample) {
+ samples.add(sample);
+ _removeOld();
+ }
+
+ void _removeOld() {
+ if (samples.length > _sampleBufferSize) {
+ int count = samples.length - _sampleBufferSize;
+ 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.
+ }
+ }
+
+ @observable String description;
+ @observable double value = 0.0;
+ @observable double min;
+ @observable double max;
+
+ 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.
+
+ void _update(ObservableMap map, bool mapIsRef) {
+ name = map['name'];
+ description = map['description'];
+ vmName = map['name'];
+ value = map['value'];
+ min = map['min'];
+ max = map['max'];
+ }
+}
+
+class MetricPoller {
+ // Metrics to be polled.
+ final List<Metric> metrics = new List<Metric>();
+ 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.
+ final Duration _pollPeriod;
+ Timer _pollTimer;
+
+ MetricPoller(int milliseconds) :
+ period = milliseconds,
+ _pollPeriod = new Duration(milliseconds: milliseconds) {
+ start();
+ }
+
+ void start() {
+ _pollTimer = new Timer.periodic(_pollPeriod, _onPoll);
+ }
+
+ void cancel() {
+ if (_pollTimer != null) {
+ _pollTimer.cancel();
+ }
+ _pollTimer = null;
+ }
+
+ void _onPoll(_) {
+ if (metrics.length == 0) {
koda 2014/08/11 16:34:53 Redundant.
Cutch 2014/08/27 22:25:40 Done.
+ return;
+ }
+ // Reload metrics and add a sample to each.
+ 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.
+ var metric = metrics[i];
+ metric.reload().then((m) {
+ m.addSample(new MetricSample(m.value));
+ });
+ }
+ }
+}
+
// Convert any ServiceMaps representing a null instance into an actual null.
_convertNull(obj) {
if (obj is ServiceMap &&

Powered by Google App Engine
This is Rietveld 408576698