Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stdout not printing until after reading stdin when using terminal #2164

Closed
mpfaff opened this issue Dec 10, 2019 · 3 comments
Closed

Stdout not printing until after reading stdin when using terminal #2164

mpfaff opened this issue Dec 10, 2019 · 3 comments
Labels
in cli Relates to running Dart CLI scripts in debugger Relates to the debug adapter or process of launching a debug session is bug
Milestone

Comments

@mpfaff
Copy link

mpfaff commented Dec 10, 2019

I've noticed that stdout output and stdin input don't seem to be happening in the correct order if I set "console": "terminal" in my launch config. I'm guessing that maybe Dart-Code is caching the stdout output for some reason.

import 'dart:convert';
import 'dart:io';

import 'package:io/io.dart';

final Stream<String> stdinUtf8 = sharedStdIn.transform(utf8.decoder).asBroadcastStream();
final Stream<String> stdinLined = stdinUtf8.transform(LineSplitter());

Future<T> prompt<T>(String question, {T fallback, T def, String hint, T Function(String) parse}) async {
  assert(T is String || parse != null, '`parse` can only be null if T is String. T is $T');
  stdout.write('$question${hint != null || def != null ? ' (${hint ?? def})' : ''} >>> ');
  final ret = await stdinLined.first;
  print('[OUTPUT = $ret]'); // for debugging
  if (ret.isEmpty && fallback != null) return def;
  else if (parse != null) {
    try {
      return parse(ret);
    } on FormatException {
      return fallback;
    }
  }

  return ret as T;
}

Example:

Future<void> main() async {
  final name = await prompt<String>('What is your name?');
}

Expected Output (works in non-debug terminal):

$ dart bin/main.dart
What is your name? >>> <some user input>
[OUTPUT = <some user input>]

Actual Output:

$ dart bin/main.dart
<some user input>
What is your name? >>> [OUTPUT = <some user input>]
@DanTup
Copy link
Member

DanTup commented Dec 10, 2019

You're right - we do buffer the output until we get a newline. This was done because sometimes messages from Dart were coming through in pieces, and we sometimes missed paths in the stack traces, and failed to link them up (see 70a2a8a).

This does seem like a problem though. We could potentially flush the buffer periodically (eg. make it time-based rather than line-based), though I'm not sure if that might just introduce other issues.

I'll have a think!

@DanTup DanTup added in cli Relates to running Dart CLI scripts in debugger Relates to the debug adapter or process of launching a debug session is bug labels Dec 10, 2019
@DanTup DanTup added this to the v3.8.0 milestone Dec 10, 2019
@mpfaff
Copy link
Author

mpfaff commented Dec 10, 2019

@DanTup, thanks for the quick update! Could it be configured to print to the same line until a newline character is received, or does it only support full lines?

@DanTup
Copy link
Member

DanTup commented Dec 11, 2019

@mpfaff we can send characters at any time, the issue is just that we need to scan a whole line in order to detect stack frame paths. For example we might get:

[5:01:50] tion: Oop
[5:01:50] s
[5:01:50]
[5:01:50] #
[5:01:50] 0
[5:01:50]
[5:01:50]
[5:01:50]     main (file:///D:/a/
[5:01:50] Dart-Code/Dart-Code/src/test/test_projects/hello_world/bin/broken.dart:2:3)

Each line is a chunk of data we received. If we sent each chunk as we got it, then we wouldn't be able to send a single line with the additional metadata required to make links. The links won't actually work in the terminal though, so it's a bit weird to have this limitation (it's because the terminal and the debug console share the same debug adapter code).

Some possible thoughts:

  • Just skip the buffering (or immediately flush the buffer) when in terminal mode
  • Test what happens if we send a line in multiple chunks and attach the location metadata only to the last chunk

@DanTup DanTup closed this as completed in 093858e Jan 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in cli Relates to running Dart CLI scripts in debugger Relates to the debug adapter or process of launching a debug session is bug
Projects
None yet
Development

No branches or pull requests

2 participants