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

Side by Side Diff: lib/src/isolate.dart

Issue 1670283002: add sendRequest to VMIsolateRef Base URL: git@github.com:yjbanov/vm_service_client.git@master
Patch Set: address comments 2 Created 4 years, 10 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
« no previous file with comments | « no previous file | lib/src/scope.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:collection'; 6 import 'dart:collection';
7 7
8 import 'package:async/async.dart'; 8 import 'package:async/async.dart';
9 import 'package:crypto/crypto.dart'; 9 import 'package:crypto/crypto.dart';
10 import 'package:json_rpc_2/json_rpc_2.dart' as rpc; 10 import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 /// A broadcast stream that emits a [VMPauseEvent] whenever this isolate is 61 /// A broadcast stream that emits a [VMPauseEvent] whenever this isolate is
62 /// paused or resumed. 62 /// paused or resumed.
63 Stream<VMPauseEvent> get onPauseOrResume => _onPauseOrResume; 63 Stream<VMPauseEvent> get onPauseOrResume => _onPauseOrResume;
64 Stream<VMPauseEvent> _onPauseOrResume; 64 Stream<VMPauseEvent> _onPauseOrResume;
65 65
66 /// A broadcast stream that emits a [VMBreakpoint] whenever a breakpoint is 66 /// A broadcast stream that emits a [VMBreakpoint] whenever a breakpoint is
67 /// added. 67 /// added.
68 Stream<VMBreakpoint> get onBreakpointAdded => _onBreakpointAdded; 68 Stream<VMBreakpoint> get onBreakpointAdded => _onBreakpointAdded;
69 Stream<VMBreakpoint> _onBreakpointAdded; 69 Stream<VMBreakpoint> _onBreakpointAdded;
70 70
71 /// A broadcast stream that emits custom events posted via `postEvent` from
72 /// the `dart:developer` package.
73 Stream<VMExtensionEvent> get onExtensionEvent => _onExtensionEvent;
74 Stream<VMExtensionEvent> _onExtensionEvent;
75
76 /// A broadcast stream that emits custom events posted via `postEvent` from
77 /// the `dart:developer` package, limited to specific [kind].
78 ///
79 /// If [prefix] is `true`, then [kind] is matched to the event kind as a
80 /// prefix.
81 Stream<VMExtensionEvent> selectExtensionEvents(String kind,
82 {bool prefix: false}) =>
83 transform(_onExtensionEvent,
84 (VMExtensionEvent event, EventSink<VMExtensionEvent> sink) {
85 if (event.kind == kind || (prefix && event.kind.startsWith(kind))) {
86 sink.add(event);
87 }
88 });
89
71 /// A broadcast stream that emits this isolate's standard output. 90 /// A broadcast stream that emits this isolate's standard output.
72 /// 91 ///
73 /// This is only usable for embedders that provide access to `dart:io`. 92 /// This is only usable for embedders that provide access to `dart:io`.
74 /// 93 ///
75 /// Note that as of the VM service version 3.0, this stream doesn't emit 94 /// Note that as of the VM service version 3.0, this stream doesn't emit
76 /// strings passed to the `print()` function unless the host process's 95 /// strings passed to the `print()` function unless the host process's
77 /// standard output is actively being drained (see [sdk#24351][]). 96 /// standard output is actively being drained (see [sdk#24351][]).
78 /// 97 ///
79 /// [sdk#24351]: https://github.com/dart-lang/sdk/issues/24351 98 /// [sdk#24351]: https://github.com/dart-lang/sdk/issues/24351
80 Stream<List<int>> get stdout => _stdout; 99 Stream<List<int>> get stdout => _stdout;
81 Stream<List<int>> _stdout; 100 Stream<List<int>> _stdout;
82 101
83 /// A broadcast stream that emits this isolate's standard error. 102 /// A broadcast stream that emits this isolate's standard error.
84 /// 103 ///
85 /// This is only usable for embedders that provide access to `dart:io`. 104 /// This is only usable for embedders that provide access to `dart:io`.
86 Stream<List<int>> get stderr => _stderr; 105 Stream<List<int>> get stderr => _stderr;
87 Stream<List<int>> _stderr; 106 Stream<List<int>> _stderr;
88 107
108 /// A broadcast stream that emits the name of VM service extensions
109 Stream<String> get onServiceExtensionAdded =>
110 _onServiceExtensionAdded;
111 Stream<String> _onServiceExtensionAdded;
112
89 /// A future that fires when the isolate exits. 113 /// A future that fires when the isolate exits.
90 /// 114 ///
91 /// If the isolate has already exited, this will complete immediately. 115 /// If the isolate has already exited, this will complete immediately.
92 Future get onExit => _onExitMemo.runOnce(() async { 116 Future get onExit => _onExitMemo.runOnce(() async {
93 try { 117 try {
94 await _scope.getInState(_scope.streams.isolate, () async { 118 await _scope.getInState(_scope.streams.isolate, () async {
95 try { 119 try {
96 await load(); 120 await load();
97 return null; 121 return null;
98 } on VMSentinelException catch (_) { 122 } on VMSentinelException catch (_) {
(...skipping 20 matching lines...) Expand all
119 name = json["name"] { 143 name = json["name"] {
120 _onGC = _transform(_scope.streams.gc, (json, sink) { 144 _onGC = _transform(_scope.streams.gc, (json, sink) {
121 if (json["kind"] == "GC") sink.add(null); 145 if (json["kind"] == "GC") sink.add(null);
122 }); 146 });
123 147
124 _onUpdate = _transform(_scope.streams.isolate, (json, sink) { 148 _onUpdate = _transform(_scope.streams.isolate, (json, sink) {
125 if (json["kind"] != "IsolateUpdate") return; 149 if (json["kind"] != "IsolateUpdate") return;
126 sink.add(new VMIsolateRef._(_scope, json["isolate"])); 150 sink.add(new VMIsolateRef._(_scope, json["isolate"]));
127 }); 151 });
128 152
153 _onServiceExtensionAdded = _transform(_scope.streams.isolate, (json, sink) {
154 if (json["kind"] != "ServiceExtensionAdded") return;
155 sink.add(json["extensionRPC"]);
156 });
157
129 _onPauseOrResume = _transform(_scope.streams.debug, (json, sink) { 158 _onPauseOrResume = _transform(_scope.streams.debug, (json, sink) {
130 var event = newVMPauseEvent(_scope, json); 159 var event = newVMPauseEvent(_scope, json);
131 if (event != null) sink.add(event); 160 if (event != null) sink.add(event);
132 }); 161 });
133 162
134 _onBreakpointAdded = _transform(_scope.streams.debug, (json, sink) { 163 _onBreakpointAdded = _transform(_scope.streams.debug, (json, sink) {
135 if (json["kind"] != "BreakpointAdded") return; 164 if (json["kind"] != "BreakpointAdded") return;
136 sink.add(newVMBreakpoint(_scope, json["breakpoint"])); 165 sink.add(newVMBreakpoint(_scope, json["breakpoint"]));
137 }); 166 });
138 167
139 _stdout = _transform(_scope.streams.stdout, (json, sink) { 168 _stdout = _transform(_scope.streams.stdout, (json, sink) {
140 if (json["kind"] != "WriteEvent") return; 169 if (json["kind"] != "WriteEvent") return;
141 var bytes = CryptoUtils.base64StringToBytes(json["bytes"]); 170 var bytes = CryptoUtils.base64StringToBytes(json["bytes"]);
142 sink.add(bytes); 171 sink.add(bytes);
143 }); 172 });
144 173
145 _stderr = _transform(_scope.streams.stderr, (json, sink) { 174 _stderr = _transform(_scope.streams.stderr, (json, sink) {
146 if (json["kind"] != "WriteEvent") return; 175 if (json["kind"] != "WriteEvent") return;
147 sink.add(CryptoUtils.base64StringToBytes(json["bytes"])); 176 sink.add(CryptoUtils.base64StringToBytes(json["bytes"]));
148 }); 177 });
178
179 _onExtensionEvent = _transform(_scope.streams.extension, (json, sink) {
180 sink.add(
181 new VMExtensionEvent._(json['extensionKind'], json['extensionData']));
182 });
149 } 183 }
150 184
151 /// Like [transform], but only calls [handleData] for events related to this 185 /// Like [transform], but only calls [handleData] for events related to this
152 /// isolate. 186 /// isolate.
153 Stream _transform(Stream<Map> stream, handleData(Map json, StreamSink sink)) { 187 Stream _transform(Stream<Map> stream, handleData(Map json, StreamSink sink)) {
154 return transform(stream, (json, sink) { 188 return transform(stream, (json, sink) {
155 if (json["isolate"]["id"] != _scope.isolateId) return; 189 if (json["isolate"]["id"] != _scope.isolateId) return;
156 handleData(json, sink); 190 handleData(json, sink);
157 }); 191 });
158 } 192 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 var response = await _scope.sendRequest( 291 var response = await _scope.sendRequest(
258 "addBreakpointWithScriptUri", params); 292 "addBreakpointWithScriptUri", params);
259 return newVMBreakpoint(_scope, response); 293 return newVMBreakpoint(_scope, response);
260 } on rpc.RpcException catch (error) { 294 } on rpc.RpcException catch (error) {
261 // Error 102 indicates that the breakpoint couldn't be created. 295 // Error 102 indicates that the breakpoint couldn't be created.
262 if (error.code == 102) return null; 296 if (error.code == 102) return null;
263 rethrow; 297 rethrow;
264 } 298 }
265 } 299 }
266 300
301 /// Returns a future that completes once extension with the given [name] is
302 /// available.
303 ///
304 /// This works whether the extension is already registered or has yet to be
305 /// registered.
306 Future waitForExtension(String name) async {
307 return _scope.getInState(_scope.streams.isolate, () async {
308 var extensions = (await load()).extensionRpcs;
309 return extensions.contains(name);
310 }, (Map json) {
311 return json["kind"] == "ServiceExtensionAdded" &&
312 json["extensionRPC"] == name;
313 }).then((_) => null);
314 }
315
316 /// Makes a raw RPC to a VM service extension registered in this isolate
317 /// corresponding to the ID [number].
318 ///
319 /// [method] must correspond to a VM service extension installed on the VM
320 /// isolate and it must begin with prefix "ext.".
321 ///
322 /// [params] are passed to the extension handler and must be serializable to
323 /// a JSON string.
324 Future<Object> invokeExtension(String method, [Map<String, String> params]) {
325 if (!method.startsWith('ext.')) {
326 throw new ArgumentError.value(method, 'method',
327 'must begin with "ext." prefix');
328 }
329 return _scope.sendRequest(method, params);
330 }
331
267 bool operator ==(other) => other is VMIsolateRef && 332 bool operator ==(other) => other is VMIsolateRef &&
268 other._scope.isolateId == _scope.isolateId; 333 other._scope.isolateId == _scope.isolateId;
269 334
270 int get hashCode => _scope.isolateId.hashCode; 335 int get hashCode => _scope.isolateId.hashCode;
271 336
272 String toString() => name; 337 String toString() => name;
273 } 338 }
274 339
275 /// A full isolate on the remote VM. 340 /// A full isolate on the remote VM.
276 class VMIsolate extends VMIsolateRef { 341 class VMIsolate extends VMIsolateRef {
(...skipping 13 matching lines...) Expand all
290 355
291 /// Whether this isolate is paused. 356 /// Whether this isolate is paused.
292 bool get isPaused => pauseEvent is! VMResumeEvent; 357 bool get isPaused => pauseEvent is! VMResumeEvent;
293 358
294 /// The error that's causing the isolate to exit or `null`. 359 /// The error that's causing the isolate to exit or `null`.
295 final VMError error; 360 final VMError error;
296 361
297 /// All breakpoints currently registered for this isolate. 362 /// All breakpoints currently registered for this isolate.
298 final List<VMBreakpoint> breakpoints; 363 final List<VMBreakpoint> breakpoints;
299 364
365 /// The list of service extension RPCs that are registered for this isolate.
366 final List<String> extensionRpcs;
367
300 VMIsolate._(Scope scope, Map json) 368 VMIsolate._(Scope scope, Map json)
301 : startTime = new DateTime.fromMillisecondsSinceEpoch( 369 : startTime = new DateTime.fromMillisecondsSinceEpoch(
302 // Prior to v3.0, this was emitted as a double rather than an int. 370 // Prior to v3.0, this was emitted as a double rather than an int.
303 json["startTime"].round()), 371 json["startTime"].round()),
304 livePorts = json["livePorts"], 372 livePorts = json["livePorts"],
305 pauseOnExit = json["pauseOnExit"], 373 pauseOnExit = json["pauseOnExit"],
306 pauseEvent = newVMPauseEvent(scope, json["pauseEvent"]), 374 pauseEvent = newVMPauseEvent(scope, json["pauseEvent"]),
307 error = newVMError(scope, json["error"]), 375 error = newVMError(scope, json["error"]),
308 breakpoints = new UnmodifiableListView(json["breakpoints"] 376 breakpoints = new UnmodifiableListView(json["breakpoints"]
309 .map((breakpoint) => newVMBreakpoint(scope, breakpoint)) 377 .map((breakpoint) => newVMBreakpoint(scope, breakpoint))
310 .toList()), 378 .toList()),
379 // The returned list is null when no extensions are registered
380 extensionRpcs = new UnmodifiableListView(json["extensionRPCs"] ?? []),
311 super._(scope, json); 381 super._(scope, json);
312 } 382 }
313 383
314 /// A full isolate on the remote VM that's ready to run code. 384 /// A full isolate on the remote VM that's ready to run code.
315 /// 385 ///
316 /// The VM service exposes isolates very early, before their contents are 386 /// The VM service exposes isolates very early, before their contents are
317 /// fully-loaded. These in-progress isolates, represented by plain [VMIsolate] 387 /// fully-loaded. These in-progress isolates, represented by plain [VMIsolate]
318 /// instances, have limited amounts of metadata available. Only once they're 388 /// instances, have limited amounts of metadata available. Only once they're
319 /// runnable is the full suite of metadata available. 389 /// runnable is the full suite of metadata available.
320 /// 390 ///
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 428
359 /// The isolate continues until it exits the current function. 429 /// The isolate continues until it exits the current function.
360 static const out = const VMStep._("Out"); 430 static const out = const VMStep._("Out");
361 431
362 /// The string name of the step type. 432 /// The string name of the step type.
363 final String _value; 433 final String _value;
364 434
365 const VMStep._(this._value); 435 const VMStep._(this._value);
366 436
367 String toString() => _value; 437 String toString() => _value;
368 } 438 }
439
440 /// An event posted via `postEvent` from the `dart:developer` package.
441 class VMExtensionEvent {
442 /// Event kind.
443 final String kind;
444
445 /// Event data.
446 final Map data;
447
448 VMExtensionEvent._(this.kind, this.data);
449 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/scope.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698