mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
reduce retry attempts for flutter creatte --list-samples (#32833)
This commit is contained in:
parent
bfae0bb5cf
commit
50a9c31f5e
@ -14,18 +14,23 @@ const int kNetworkProblemExitCode = 50;
|
||||
typedef HttpClientFactory = HttpClient Function();
|
||||
|
||||
/// Download a file from the given URL and return the bytes.
|
||||
Future<List<int>> fetchUrl(Uri url) async {
|
||||
Future<List<int>> fetchUrl(Uri url, {int maxAttempts}) async {
|
||||
int attempts = 0;
|
||||
int duration = 1;
|
||||
int durationSeconds = 1;
|
||||
while (true) {
|
||||
attempts += 1;
|
||||
final List<int> result = await _attempt(url);
|
||||
if (result != null)
|
||||
return result;
|
||||
printStatus('Download failed -- attempting retry $attempts in $duration second${ duration == 1 ? "" : "s"}...');
|
||||
await Future<void>.delayed(Duration(seconds: duration));
|
||||
if (duration < 64)
|
||||
duration *= 2;
|
||||
if (maxAttempts != null && attempts >= maxAttempts) {
|
||||
printStatus('Download failed -- retry $attempts');
|
||||
return null;
|
||||
}
|
||||
printStatus('Download failed -- attempting retry $attempts in '
|
||||
'$durationSeconds second${ durationSeconds == 1 ? "" : "s"}...');
|
||||
await Future<void>.delayed(Duration(seconds: durationSeconds));
|
||||
if (durationSeconds < 64)
|
||||
durationSeconds *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,8 @@ class CreateCommand extends FlutterCommand {
|
||||
|
||||
/// Fetches the samples index file from the Flutter docs website.
|
||||
Future<String> _fetchSamplesIndexFromServer() async {
|
||||
return utf8.decode(await fetchUrl(Uri.https(_snippetsHost, 'snippets/index.json')));
|
||||
return utf8.decode(
|
||||
await fetchUrl(Uri.https(_snippetsHost, 'snippets/index.json'), maxAttempts: 2));
|
||||
}
|
||||
|
||||
/// Fetches the samples index file from the server and writes it to
|
||||
@ -214,8 +215,14 @@ class CreateCommand extends FlutterCommand {
|
||||
if (outputFile.existsSync()) {
|
||||
throwToolExit('File "$outputFilePath" already exists', exitCode: 1);
|
||||
}
|
||||
outputFile.writeAsStringSync(await _fetchSamplesIndexFromServer());
|
||||
printStatus('Wrote samples JSON to "$outputFilePath"');
|
||||
final String samplesJson = await _fetchSamplesIndexFromServer();
|
||||
if (samplesJson == null) {
|
||||
throwToolExit('Unable to download samples', exitCode: 2);
|
||||
}
|
||||
else {
|
||||
outputFile.writeAsStringSync(samplesJson);
|
||||
printStatus('Wrote samples JSON to "$outputFilePath"');
|
||||
}
|
||||
} catch (e) {
|
||||
throwToolExit('Failed to write samples JSON to "$outputFilePath": $e', exitCode: 2);
|
||||
}
|
||||
@ -224,6 +231,9 @@ class CreateCommand extends FlutterCommand {
|
||||
@override
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
if (argResults['list-samples'] != null) {
|
||||
// _writeSamplesJson can potentially be long-lived.
|
||||
Cache.releaseLockEarly();
|
||||
|
||||
await _writeSamplesJson(argResults['list-samples']);
|
||||
return null;
|
||||
}
|
||||
|
@ -104,6 +104,30 @@ void main() {
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('max attempts', () async {
|
||||
String error;
|
||||
List<int> actualResult;
|
||||
FakeAsync().run((FakeAsync time) {
|
||||
fetchUrl(Uri.parse('http://example.invalid/'), maxAttempts: 3).then((List<int> value) {
|
||||
actualResult = value;
|
||||
}, onError: (dynamic exception) {
|
||||
error = 'test failed unexpectedly: $exception';
|
||||
});
|
||||
expect(testLogger.statusText, '');
|
||||
time.elapse(const Duration(milliseconds: 10000));
|
||||
expect(testLogger.statusText,
|
||||
'Download failed -- attempting retry 1 in 1 second...\n'
|
||||
'Download failed -- attempting retry 2 in 2 seconds...\n'
|
||||
'Download failed -- retry 3\n',
|
||||
);
|
||||
});
|
||||
expect(testLogger.errorText, isEmpty);
|
||||
expect(error, isNull);
|
||||
expect(actualResult, isNull);
|
||||
}, overrides: <Type, Generator>{
|
||||
HttpClientFactory: () => () => MockHttpClient(500),
|
||||
});
|
||||
|
||||
testUsingContext('remote file non-existant', () async {
|
||||
final Uri invalid = Uri.parse('http://example.invalid/');
|
||||
final bool result = await doesRemoteFileExist(invalid);
|
||||
|
Loading…
Reference in New Issue
Block a user