From edd4c6207adb9ab243cf8376b111cb56232c4cdb Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 19 Mar 2019 16:19:45 -0700 Subject: [PATCH] prevent stream notifications from interfering with reload (#29467) --- packages/flutter_tools/lib/src/run_hot.dart | 29 +++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 90572d76802..524f9ff6f5a 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -215,7 +215,7 @@ class HotRunner extends ResidentRunner { printStatus('Running in benchmark mode.'); // Measure time to perform a hot restart. printStatus('Benchmarking hot restart'); - await restart(fullRestart: true); + await restart(fullRestart: true, benchmarkMode: true); printStatus('Benchmarking hot reload'); // Measure time to perform a hot reload. await restart(fullRestart: false); @@ -402,7 +402,7 @@ class HotRunner extends ResidentRunner { } - Future _restartFromSources({ String reason }) async { + Future _restartFromSources({ String reason, bool benchmarkMode = false }) async { final Map analyticsParameters = reason == null ? null @@ -465,6 +465,25 @@ class HotRunner extends ResidentRunner { restartTimer.elapsed.inMilliseconds); flutterUsage.sendEvent('hot', 'restart', parameters: analyticsParameters); flutterUsage.sendTiming('hot', 'restart', restartTimer.elapsed); + + // In benchmark mode, make sure all stream notifications have finished. + if (benchmarkMode) { + final List> isolateNotifications = >[]; + for (FlutterDevice device in flutterDevices) { + for (FlutterView view in device.views) { + isolateNotifications.add( + view.owner.vm.vmService.onIsolateEvent.then((Stream serviceEvents) async { + await for (ServiceEvent serviceEvent in serviceEvents) { + if (serviceEvent.owner.name.contains('_spawn') && serviceEvent.kind == ServiceEvent.kIsolateExit) { + return; + } + } + }), + ); + } + } + await Future.wait(isolateNotifications); + } return OperationResult.ok; } @@ -511,7 +530,7 @@ class HotRunner extends ResidentRunner { bool get supportsRestart => true; @override - Future restart({ bool fullRestart = false, bool pauseAfterRestart = false, String reason }) async { + Future restart({ bool fullRestart = false, bool pauseAfterRestart = false, String reason, bool benchmarkMode = false }) async { final Stopwatch timer = Stopwatch()..start(); if (fullRestart) { if (!canHotRestart) { @@ -525,7 +544,7 @@ class HotRunner extends ResidentRunner { try { if (!(await hotRunnerConfig.setupHotRestart())) return OperationResult(1, 'setupHotRestart failed'); - final OperationResult result = await _restartFromSources(reason: reason); + final OperationResult result = await _restartFromSources(reason: reason, benchmarkMode: benchmarkMode,); if (!result.isOk) return result; } finally { @@ -573,7 +592,7 @@ class HotRunner extends ResidentRunner { } } - Future _reloadSources({ bool pause = false, String reason, void Function(String message) onSlow }) async { + Future _reloadSources({ bool pause = false, String reason, void Function(String message) onSlow, }) async { final Map analyticsParameters = {}; if (reason != null) { analyticsParameters[kEventReloadReasonParameterName] = reason;