Chromium Code Reviews| Index: pkg/front_end/lib/src/vm/reload.dart |
| diff --git a/pkg/front_end/lib/src/vm/reload.dart b/pkg/front_end/lib/src/vm/reload.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..13857805008b401007804861356fbe7298cf0505 |
| --- /dev/null |
| +++ b/pkg/front_end/lib/src/vm/reload.dart |
| @@ -0,0 +1,94 @@ |
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +/// A helper library to connect to an existing VM and trigger a hot-reload via |
| +/// its service protocol. |
| +/// |
| +/// Usage: |
| +/// |
| +/// ``` |
| +/// var reloader = new VmReloader(); |
| +/// await reloader.reload(uriToEntryScript); |
| +/// ... |
| +/// await reloader.disconnect(); |
| +/// ``` |
| +library front_end.src.vm.reload; |
| + |
| +import 'dart:async'; |
| +import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc; |
| +import 'package:stream_channel/stream_channel.dart'; |
| +import 'package:web_socket_channel/io.dart'; |
| + |
| +/// A user API to trigger hot reloads on a running VM via the VM's service |
| +/// protocol. |
| +class VmReloader { |
| + /// Port used to connect to the vm service protocol, typically 8181. |
| + final int port; |
| + |
| + /// An peer point used to send service protocol messages. The service |
| + /// protocol uses JSON rpc on top of web-sockets. |
| + json_rpc.Peer get rpc => _rpc ??= _createPeer(); |
| + json_rpc.Peer _rpc; |
| + |
| + /// The main isolate ID of the running VM. Needed to indicate to the VM which |
| + /// isolate to reload. |
| + FutureOr<String> get mainId async => _mainId ??= await _computeMainId(); |
| + String _mainId; |
| + |
| + VmReloader([int port = 8181]) : port = port; |
|
scheglov
2017/06/07 00:27:23
[this.port = 8181] and you don't need "port = port
|
| + |
| + /// Establishes the JSON rpc connection. |
| + _createPeer() { |
|
scheglov
2017/06/07 00:27:23
Please add the return type.
|
| + StreamChannel socket = |
| + new IOWebSocketChannel.connect('ws://127.0.0.1:$port/ws'); |
| + var peer = new json_rpc.Peer(socket); |
| + peer.listen().then((_) { |
| + if (VERBOSE_DEBUG) print('connection to vm-service closed'); |
| + return disconnect(); |
| + }).catchError((e) { |
| + if (VERBOSE_DEBUG) print('error connecting to the vm-service'); |
| + return disconnect(); |
| + }); |
| + return peer; |
| + } |
| + |
| + /// Retrieves the ID of the main isolate using the service protocol. |
| + Future<String> _computeMainId() async { |
| + var vm = await rpc.sendRequest('getVM'); |
| + var isolates = vm['isolates']; |
| + for (var isolate in isolates) { |
| + if (isolate['name'].contains('\$main')) { |
|
scheglov
2017/06/07 00:27:23
I that think using r'$main' would show that we our
|
| + return isolate['id']; |
| + } |
| + } |
| + return isolates.first['id']; |
| + } |
| + |
| + /// Send a request to the VM to reload sources from [entryUri]. |
| + /// |
| + /// This will establish a connection with the VM assuming it is running on the |
| + /// local machine and listening on [port] for service protocol requests. |
|
scheglov
2017/06/07 00:27:23
Please document and type what is returned.
|
| + Future reload(Uri entryUri) async { |
| + var id = await mainId; |
| + var result = await rpc.sendRequest('reloadSources', { |
| + 'isolateId': id, |
| + 'rootLibUri': entryUri.path, |
| + }); |
| + return result; |
| + } |
| + |
| + /// Close any connections used to communicate with the VM. |
| + disconnect() async { |
|
scheglov
2017/06/07 00:27:23
Please add the return type.
|
| + if (_rpc == null) return null; |
| + this._mainId = null; |
| + if (!_rpc.isClosed) { |
| + var future = _rpc.close(); |
| + _rpc = null; |
| + return future; |
| + } |
| + return null; |
| + } |
| +} |
| + |
| +const VERBOSE_DEBUG = false; |