Nothing to be done here. This is the expected behavior and has been that way since the start of Unix.
You can get around this by piping to an intermediate process that spools to disk and reads from that - until you run out of disk space. Honestly you probably should fix the consumer. > On Dec 5, 2019, at 11:27 AM, peter.juhas...@gmail.com wrote: > > > I've run into an insidious issue. > > The log package writes to the standard error. However, at least on linux, if > stderr is redirected to a pipe and the other end of that pipe is not drained, > then the kernel buffer associated with that pipe eventually gets full, and > once that happens, subsequent write calls to stderr will block indefinitely. > The problem is exacerbated by the fact that the log package uses a mutex to > ensure that messages don't get mixed up on output - but because the of the > blocked write call the mutex is never unlocked, so any subsequent call to any > output function of the log package, from anywhere in the program, will block. > > Demonstration: the following program, when ran in itself, prints several > dummy strings to stderr then exits with a panic message. > > ////////////////////// > package main > > import ( > "log" > "time" > ) > > func spam(id int) { > max := 10000 > for i := 0; i < max; i++ { > log.Printf("%d\t%06d\t%10s", id, i, "") > } > } > > func main() { > go spam(1) > go spam(2) > time.Sleep(1 * time.Second) > panic("exiting") > } > ////////////////////////// > > However, when ran through the following script, which redirects the standard > error of its child process but purposely doesn't read from it, the program > hangs. > > ######################## > #!/usr/bin/perl > > use strict; > use warnings; > use IPC::Open3; > use Symbol 'gensym'; > > my($wtr, $rdr, $err); > $err = gensym; > my $pid = open3($wtr, $rdr, $err, @ARGV); > > waitpid( $pid, 0 ); > ########################## > > (Compile the above go program as `child`, save this script as runner.pl, then > run it as `perl runner.pl ./child`.) > If you run it with strace, you can see that it can't even panic, because it > blocks on one of the many write calls that produce the panic message. > > > The question of "but why would you do that" may arise - of course I would not > *want* to do this. The issue came up in an environment where a go program > somewhat more complex than the one above is run by supervisord, and I use > supervisord's output redirection facility to forward the go program's stderr > to a remote syslog sink. And, for some reason I don't yet understand, > supervisord stopped reading the stderr pipe mid-run. > So I don't say that this is a bug in go, I'm not sure that you could even do > anything about it, I just find the issue particularly annoying, because it's > hard to detect and hard to work around. > Perhaps a note in the log package's documentation about possible dangers of > redirecting stderr may be useful. > > best regards, > Peter Juhasz > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/83a396b3-41c1-453d-b604-3640ba58bdb0%40googlegroups.com. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/8CABDBE5-11C5-48EC-A4EA-864C3B924B70%40ix.netcom.com.