| Index: runtime/observatory/lib/src/app/application.dart
|
| diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
|
| index 5306b13ba3e4672ead5979805feb713fc48e7835..f847c231c98902a40125cfa8d0d8875b19a7b63b 100644
|
| --- a/runtime/observatory/lib/src/app/application.dart
|
| +++ b/runtime/observatory/lib/src/app/application.dart
|
| @@ -16,41 +16,75 @@ class ObservatoryApplication {
|
| LocationManager _locationManager;
|
| LocationManager get locationManager => _locationManager;
|
| Page currentPage;
|
| + bool _vmConnected = false;
|
| VM _vm;
|
| VM get vm => _vm;
|
|
|
| - _setVM(VM vm) {
|
| - if (_vm == vm) {
|
| + bool isConnectedVMTarget(WebSocketVMTarget target) {
|
| + if (_vm is CommonWebSocketVM) {
|
| + if ((_vm as CommonWebSocketVM).target == target) {
|
| + return _vm.isConnected;
|
| + }
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + _switchVM(VM newVM) {
|
| + final VM oldVM = _vm;
|
| +
|
| + Logger.root.info('_switchVM from:${oldVM} to:${newVM}');
|
| +
|
| + if (oldVM == newVM) {
|
| // Do nothing.
|
| return;
|
| }
|
| - if (_vm != null) {
|
| - _gcSubscription = null;
|
| +
|
| + if (oldVM != null) {
|
| + print('disconnecting from the old VM ${oldVM}--');
|
| // Disconnect from current VM.
|
| + stopGCEventListener();
|
| notifications.deleteAll();
|
| - _vm.disconnect();
|
| + oldVM.disconnect();
|
| }
|
| - if (vm != null) {
|
| - Logger.root.info('Registering new VM callbacks');
|
|
|
| - vm.onConnect.then((_) {
|
| + if (newVM != null) {
|
| + // Mark that we haven't connected yet.
|
| + _vmConnected = false;
|
| + // On connect:
|
| + newVM.onConnect.then((_) {
|
| + // We connected.
|
| + _vmConnected = true;
|
| notifications.deleteDisconnectEvents();
|
| });
|
| -
|
| - vm.onDisconnect.then((String reason) {
|
| - if (this.vm != vm) {
|
| + // On disconnect:
|
| + newVM.onDisconnect.then((String reason) {
|
| + if (this.vm != newVM) {
|
| // This disconnect event occured *after* a new VM was installed.
|
| return;
|
| }
|
| - events.add(new ConnectionClosedEvent(new DateTime.now(), reason));
|
| + // Let anyone looking at the targets know that we have disconnected
|
| + // from one.
|
| + targets.emitDisconnectEvent();
|
| + if (!_vmConnected) {
|
| + // Connection error. Navigate back to the connect page.
|
| + Logger.root.info('Connection failed, navigating to VM connect page.');
|
| + // Clear the vm.
|
| + _vm = null;
|
| + app.locationManager.go(Uris.vmConnect());
|
| + } else {
|
| + // Disconnect. Stay at the current page and push an a connection
|
| + // closed event.
|
| + Logger.root.info('Lost an existing connection to a VM');
|
| + events.add(new ConnectionClosedEvent(new DateTime.now(), reason));
|
| + }
|
| });
|
| -
|
| // TODO(cbernaschina) smart connection of streams in the events object.
|
| - vm.listenEventStream(VM.kVMStream, _onEvent);
|
| - vm.listenEventStream(VM.kIsolateStream, _onEvent);
|
| - vm.listenEventStream(VM.kDebugStream, _onEvent);
|
| + newVM.listenEventStream(VM.kVMStream, _onEvent);
|
| + newVM.listenEventStream(VM.kIsolateStream, _onEvent);
|
| + newVM.listenEventStream(VM.kDebugStream, _onEvent);
|
| }
|
| - _vm = vm;
|
| +
|
| + _vm = newVM;
|
| }
|
|
|
| StreamSubscription _gcSubscription;
|
| @@ -192,13 +226,24 @@ class ObservatoryApplication {
|
|
|
| ObservatoryApplication(this.rootElement) {
|
| _locationManager = new LocationManager(this);
|
| - targets.onChange.listen((e) {
|
| - if (targets.current == null) return _setVM(null);
|
| - if ((_vm as WebSocketVM)?.target != targets.current) {
|
| - _setVM(new WebSocketVM(targets.current));
|
| + targets.onChange.listen((TargetChangeEvent e) {
|
| + if (e.disconnected) {
|
| + // We don't care about disconnected events.
|
| + return;
|
| + }
|
| + if (targets.current == null) {
|
| + _switchVM(null);
|
| + }
|
| + final bool currentTarget =
|
| + (_vm as WebSocketVM)?.target == targets.current;
|
| + final bool currentTargetConnected = (_vm != null) && !_vm.isDisconnected;
|
| + if (!currentTarget || !currentTargetConnected) {
|
| + _switchVM(new WebSocketVM(targets.current));
|
| }
|
| });
|
| - _setVM(new WebSocketVM(targets.current));
|
| +
|
| + Logger.root.info('Setting initial target to ${targets.current.name}');
|
| + _switchVM(new WebSocketVM(targets.current));
|
| _initOnce();
|
|
|
| // delete pause events.
|
| @@ -217,11 +262,12 @@ class ObservatoryApplication {
|
| events.onPauseInterrupted.listen(_addNotification);
|
| events.onPauseException.listen(_addNotification);
|
| events.onInspect.listen(_addNotification);
|
| + events.onConnectionClosed.listen(_addNotification);
|
| }
|
|
|
| loadCrashDump(Map crashDump) {
|
| - _setVM(new FakeVM(crashDump['result']));
|
| - app.locationManager.go('#/vm');
|
| + _switchVM(new FakeVM(crashDump['result']));
|
| + app.locationManager.go(Uris.vm());
|
| }
|
|
|
| void handleException(e, st) {
|
|
|