Unverified Commit 5fc6b871 authored by Alexander Aprelev's avatar Alexander Aprelev Committed by GitHub

Reland change that speeds up multiple devices hot-reload (#23695)

* Revert "Revert "Run reload asynchronously so that multiple devices can reload in parallel. (#22693)" (#23598)"

This reverts commit 0b68068d.

* Fix refreshViews so it sends app-wide(rather than per-isolate) service request.

Sending per-isolate request caused dead-lock in the engine in case of more-than-one ui isolate.
parent 0dada102
...@@ -79,11 +79,15 @@ class FlutterDevice { ...@@ -79,11 +79,15 @@ class FlutterDevice {
vmServices = localVmServices; vmServices = localVmServices;
} }
Future<void> refreshViews() async { Future<void> refreshViews() {
if (vmServices == null || vmServices.isEmpty) if (vmServices == null || vmServices.isEmpty)
return; return Future<void>.value(null);
final List<Future<void>> futures = <Future<void>>[];
for (VMService service in vmServices) for (VMService service in vmServices)
await service.vm.refreshViews(); futures.add(service.vm.refreshViews());
final Completer<void> completer = Completer<void>();
Future.wait(futures).whenComplete(() => completer.complete(null)); // ignore: unawaited_futures
return completer.future;
} }
List<FlutterView> get views { List<FlutterView> get views {
......
This diff is collapsed.
...@@ -949,15 +949,12 @@ class VM extends ServiceObjectOwner { ...@@ -949,15 +949,12 @@ class VM extends ServiceObjectOwner {
return invokeRpcRaw('_getVMTimeline', timeout: kLongRequestTimeout); return invokeRpcRaw('_getVMTimeline', timeout: kLongRequestTimeout);
} }
Future<void> refreshViews() async { Future<void> refreshViews() {
if (!isFlutterEngine) if (!isFlutterEngine)
return; return null;
_viewCache.clear(); _viewCache.clear();
for (Isolate isolate in isolates.toList()) { // Send one per-application request that refreshes all views in the app.
await vmService.vm.invokeRpc<ServiceObject>('_flutter.listViews', return vmService.vm.invokeRpc<ServiceObject>('_flutter.listViews', timeout: kLongRequestTimeout);
timeout: kLongRequestTimeout,
params: <String, dynamic> {'isolateId': isolate.id});
}
} }
Iterable<FlutterView> get views => _viewCache.values; Iterable<FlutterView> get views => _viewCache.values;
...@@ -1226,15 +1223,15 @@ class Isolate extends ServiceObjectOwner { ...@@ -1226,15 +1223,15 @@ class Isolate extends ServiceObjectOwner {
Duration timeout, Duration timeout,
bool timeoutFatal = true, bool timeoutFatal = true,
} }
) async { ) {
try { return invokeRpcRaw(method, params: params, timeout: timeout,
return await invokeRpcRaw(method, params: params, timeout: timeout, timeoutFatal: timeoutFatal); timeoutFatal: timeoutFatal).catchError((dynamic error) {
} on rpc.RpcException catch (e) { if (error is rpc.RpcException) {
// If an application is not using the framework // If an application is not using the framework
if (e.code == rpc_error_code.METHOD_NOT_FOUND) if (error.code == rpc_error_code.METHOD_NOT_FOUND)
return null; return null;
rethrow; throw error;
} }});
} }
// Debug dump extension methods. // Debug dump extension methods.
...@@ -1288,20 +1285,20 @@ class Isolate extends ServiceObjectOwner { ...@@ -1288,20 +1285,20 @@ class Isolate extends ServiceObjectOwner {
} }
// Reload related extension methods. // Reload related extension methods.
Future<Map<String, dynamic>> flutterReassemble() async { Future<Map<String, dynamic>> flutterReassemble() {
return await invokeFlutterExtensionRpcRaw( return invokeFlutterExtensionRpcRaw(
'ext.flutter.reassemble', 'ext.flutter.reassemble',
timeout: kShortRequestTimeout, timeout: kShortRequestTimeout,
timeoutFatal: true, timeoutFatal: true,
); );
} }
Future<Map<String, dynamic>> uiWindowScheduleFrame() async { Future<Map<String, dynamic>> uiWindowScheduleFrame() {
return await invokeFlutterExtensionRpcRaw('ext.ui.window.scheduleFrame'); return invokeFlutterExtensionRpcRaw('ext.ui.window.scheduleFrame');
} }
Future<Map<String, dynamic>> flutterEvictAsset(String assetPath) async { Future<Map<String, dynamic>> flutterEvictAsset(String assetPath) {
return await invokeFlutterExtensionRpcRaw('ext.flutter.evict', return invokeFlutterExtensionRpcRaw('ext.flutter.evict',
params: <String, dynamic>{ params: <String, dynamic>{
'value': assetPath, 'value': assetPath,
} }
...@@ -1309,8 +1306,8 @@ class Isolate extends ServiceObjectOwner { ...@@ -1309,8 +1306,8 @@ class Isolate extends ServiceObjectOwner {
} }
// Application control extension methods. // Application control extension methods.
Future<Map<String, dynamic>> flutterExit() async { Future<Map<String, dynamic>> flutterExit() {
return await invokeFlutterExtensionRpcRaw( return invokeFlutterExtensionRpcRaw(
'ext.flutter.exit', 'ext.flutter.exit',
timeout: const Duration(seconds: 2), timeout: const Duration(seconds: 2),
timeoutFatal: false, timeoutFatal: false,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment