[erlang-questions] Re: how do I get escript to emit all output before exiting?

Matthias Lang matthias@REDACTED
Thu Apr 7 14:49:33 CEST 2011


On Monday, April 04, Scott Lystig Fritchie wrote:

> IIRC the stuff scribbled to the console via io:format() is actually done
> by sending messages to the group leader process.  You're at the
> scheduler's whim to decide whether the group leader gets executed &
> processes the I/O requests before the VM halts.

> Having said that, I've been bitten by this same concurrency feature.
> C/Ruby/Python folks don't expect the feature.  Even never-touched-
> another-language Erlang hackers may not expect it.
...
> io:format() is **not** a thin wrapper around the syscall/stdlib calls:

I'm still not sure whether there's something I'm missing.

Currently, I can't see how to implement, say, 'cat' in Erlang (and
Escript). I know no way to make sure that all output gets emitted. I
know some ways which don't work:

  - calling halt() loses output more often than not
  - calling init:stop() loses output, but not as often (my idea)
  - calling init:stop(), receive after infinity -> ok end, also loses
      output, but even less often (Håkan's idea)
  - timer:sleep(500), pretty much always works, but no guarantee, obviously

There are some kludges that can make it work, e.g. doing IO via TCP and
using netcat to display it, or writing to a file in /tmp and wrapping
the escript invocation in a shell script which 'cat's the temporary file.

There are some ambitious ideas to make it work, such as modifying
'init' to treat group-leaders specially. (Mike suggested it, Scott
pointed out that it trickier than it seems at first.)

I had a less ambitious idea: give a process a way to wait, with an
optional timeout, until its output has been flushed, i.e. an
io:flush(Timeout) function. I think that lets me write 'cat' and
also behaves sensibly at least for non-distributed erlang.

(Do it by adding 'flush' message to the IO protocol, say {flush, pid(),
ref()}. The 'receive' loop in user (or is it the one in user_drv? I
can't remember) replies, so then we know that no requests are still in
the message queue. Is that sufficient?  Can the emulator shut down
cleanly with data still buffered in a port?  I haven't investigated.)

Comments? Robert must have something to add here.

Matthias



More information about the erlang-questions mailing list