From 0adb39ae9b5823561f52df63ba9df38d0c412ecc Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Wed, 12 Jul 2017 17:57:15 -0700 Subject: [PATCH] Avoid concurrent device polling in daemon; add timeout (#11184) Apply a 30 second timeout to Android/iOS device polling. If there's a device poll already in progress, skip polling for new devices; wait for the first request to return/timeout. --- packages/flutter_tools/lib/src/device.dart | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 1825d531b09..614ffc2742b 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart @@ -111,7 +111,8 @@ abstract class DeviceDiscovery { abstract class PollingDeviceDiscovery extends DeviceDiscovery { PollingDeviceDiscovery(this.name); - static const Duration _pollingDuration = const Duration(seconds: 4); + static const Duration _pollingInterval = const Duration(seconds: 4); + static const Duration _pollingTimeout = const Duration(seconds: 30); final String name; ItemListNotifier _items; @@ -122,8 +123,21 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery { void startPolling() { if (_timer == null) { _items ??= new ItemListNotifier(); - _timer = new Timer.periodic(_pollingDuration, (Timer timer) async { - _items.updateWithNewList(await pollingGetDevices()); + bool _fetchingDevices = false; + _timer = new Timer.periodic(_pollingInterval, (Timer timer) async { + if (_fetchingDevices) { + printTrace('Skipping device poll: already in progress'); + return; + } + _fetchingDevices = true; + try { + final List devices = await pollingGetDevices().timeout(_pollingTimeout); + _items.updateWithNewList(devices); + } on TimeoutException { + printTrace('Device poll timed out.'); + } finally { + _fetchingDevices = false; + } }); } }