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) { |