Fix hanging event handler for `stdin`. (#3218)
Piping `stdin` to a `LineSplitter` and then using a `StreamQueue` causes
event handler to wait for next characters after a line has been read.
Hence, if we don't `exit()` explicitly or hit `stdin.close()` then the
process will hang waiting for input on `stdin`.
Using `stdin.readLineSync()` alleviates this issue. Having a timeout on
prompts for tokens is nice, but only really required if we prompt while
the solver is running. Which we probably won't need to do anyways, so
not having a timeout is likely fine.
diff --git a/lib/src/command/token_add.dart b/lib/src/command/token_add.dart
index fddc0cc..caf3b8b 100644
--- a/lib/src/command/token_add.dart
+++ b/lib/src/command/token_add.dart
@@ -57,17 +57,11 @@
} on FormatException catch (e) {
usageException('Invalid [hosted-url]: "$rawHostedUrl"\n'
'${e.message}');
- } on TimeoutException catch (_) {
- // Timeout is added to readLine call to make sure automated jobs doesn't
- // get stuck on noop state if user forget to pipe token to the 'token add'
- // command. This behavior might be removed.
- throw ApplicationException('Token is not provided within 15 minutes.');
}
}
Future<void> _addTokenFromStdin(Uri hostedUrl) async {
- final token = await stdinPrompt('Enter secret token:', echoMode: false)
- .timeout(const Duration(minutes: 15));
+ final token = await stdinPrompt('Enter secret token:', echoMode: false);
if (token.isEmpty) {
usageException('Token is not provided.');
}
diff --git a/lib/src/io.dart b/lib/src/io.dart
index 641da73..d6af9c2 100644
--- a/lib/src/io.dart
+++ b/lib/src/io.dart
@@ -8,7 +8,6 @@
import 'dart:convert';
import 'dart:io';
-import 'package:async/async.dart';
import 'package:cli_util/cli_util.dart'
show EnvironmentNotFoundException, applicationConfigHome;
import 'package:http/http.dart' show ByteStream;
@@ -562,10 +561,6 @@
return path.fromUri(url);
})();
-/// A line-by-line stream of standard input.
-final StreamQueue<String> _stdinLines = StreamQueue(
- ByteStream(stdin).toStringStream().transform(const LineSplitter()));
-
/// Displays a message and reads a yes/no confirmation from the user.
///
/// Returns a [Future] that completes to `true` if the user confirms or `false`
@@ -591,14 +586,14 @@
final previousEchoMode = stdin.echoMode;
try {
stdin.echoMode = echoMode;
- final result = await _stdinLines.next;
+ final result = stdin.readLineSync() ?? '';
stdout.write('\n');
return result;
} finally {
stdin.echoMode = previousEchoMode;
}
} else {
- return await _stdinLines.next;
+ return stdin.readLineSync() ?? '';
}
}