BREAKING CHANGE: dart:io's stdout and stderr is now truly async

167 views
Skip to first unread message

Anders Johnsen

unread,
Sep 24, 2013, 7:54:22 AM9/24/13
to announce
What changes?
Writes to stdout and stderr used to be blocking, on all platforms. As part of a cleanup, this is now async/non-blocking as any other Streams in dart:io.

How do I update my code?
Most code should work just like it used to, except a a few cases when calling 'exit': If you are writing to stdout/stderr and calling exit immediately after, the writes to stdout and stderr may be lost. Instead, do the following:

  Future.wait([stdout.close(), stderr.close()])
      .then((_) => exit());

As stdout/stderr .close will make sure to flush any pending writes.

Why did this change happen?
Everything in dart:io was async, with the exception of stdout/stderr. This is now fixed.

When will the change take effect?
This change landed in r27811. It should be available in the next release.

Florian Loitsch

unread,
Sep 24, 2013, 8:59:21 AM9/24/13
to e...@dartlang.org, announce
With "next release" Anders means the one in roughly one week.

--
For more news and information, visit http://news.dartlang.org/
 
To join the conversation, visit https://groups.google.com/a/dartlang.org/

To unsubscribe from this group and stop receiving emails from it, send an email to announce+u...@dartlang.org.



--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry Pratchett

Bob Nystrom

unread,
Sep 24, 2013, 12:31:33 PM9/24/13
to e...@dartlang.org, announce

On Tue, Sep 24, 2013 at 4:54 AM, Anders Johnsen <ajoh...@google.com> wrote:
Instead, do the following:

  Future.wait([stdout.close(), stderr.close()])
      .then((_) => exit());

It would be double-plus awesome if dart:io had a method that did that. Maybe:

Future exit() => Future.wait([stdout.close(), stderr.close()]).then((_) => exitSync());
void exitSync() => what exit() does now...

Thoughts?

- bob

Søren Gjesse

unread,
Sep 26, 2013, 5:06:19 AM9/26/13
to e...@dartlang.org, announce
As mentioned on issue https://code.google.com/p/dart/issues/detail?id=13546 normal VM termination already waits for all IO to terminate. For normal termination it is also possible to set the exit code using the exitCode top level setter. If one is using exit the VM terminated immediately, and it should be used with care if used for termination when some IO channels should close first.

Regards,
Søren


--

Anders Johnsen

unread,
Oct 8, 2013, 1:44:59 AM10/8/13
to General Dart Discussion, e...@dartlang.org, announce
Hi Daniel,

We did have some issues with print, but they should be fixed now. Comments inlined.

    import 'dart:async';
    import 'dart:io';
    
    main() {
      print("Done");
      Future.wait([ stdout.close(), stderr.close() ])
        .then((_) => print("Goo"));
    }

If I run from emacs shell I get:

    bash-3.2$ dart closestdout.dart 
    Done
    bash-3.2$ exit
    
    Process shell finished

This is actually working as expected. Closing stdout/stderr means closing the associated file-descriptor (or HANDLE on Windows). Any call to print after that, will simply be ignored as the file-descriptor is no longer available. Usually. one never have to use stdout.close or stderr.close, unless they have to use exit (and usage of exit is not rarely recommended).

Is it possible there is some inheritance of stdout/stderr going on and closing those handles also closes the parent's stdout/stderr thus messing up the shell parent?

That should not be the case at all. However, we did have an issue (fixed in r28081), where using stdout would make print unpredictable (non-blocking).

Along the same lines, why does this misbehave in the following way: If -maxdepth is 1 as shown it is fine. If maxdetph is greater more data will be output and in this case the print("All done") is not shown?

    import 'dart:async';
    import 'dart:io';
    
    main() {
      var task = Process
        .run('/usr/bin/find', [ '/', '-maxdepth', '1' ])
        .then((ProcessResult process) {
          print(process.stdout);
          print(process.stderr);
          return process.exitCode;
        })
        .then((rc) {
          print("All done");
          Future.wait([ stdout.close(), stderr.close() ])
            .then((rc) => exit(rc));
        });
    
    }

Could it be possible that your Dart binary is older than r28081? This looks a lot like the issues we saw before the fix.

Cheers,

- Anders
Reply all
Reply to author
Forward
0 new messages