Code in question:

// Flush writes any buffered data to the underlying io.Writer.
func (b *Writer) Flush() error {
        if b.err != nil {
                return b.err
        }
        if b.n == 0 {
                return nil
        }
        n, err := b.wr.Write(b.buf[0:b.n])
        if n < b.n && err == nil {
                err = io.ErrShortWrite
        }
        if err != nil {
                if n > 0 && n < b.n {
                        copy(b.buf[0:b.n-n], b.buf[n:b.n])
                }
                b.n -= n
                b.err = err
                return err
        }
        b.n = 0
        return nil
}

Consider that underlying io.Writer is a TCP socket.  Under system load, 
partial write can occur and write() system call does not consider partial 
write as an error (see man 2 write).  In other words, if n < b.n, only some 
data got written to the underlying io.Writer and this in itself is not an 
erro.  bufio is expected to handle this by keep the bytes not yet written 
in the buffer so that those bytes will get written in future (code above 
does this: copy(b.buf[0:b.n-n], b.buf[n:b.n]).  However,  the Flush() code 
is buggy (unless I am missing something).  It sets b.err to 
io.ErrShortWrite if n < b.n and any further Flush() call by client to 
continue to write to the underlying io.Writer bails out as the first line 
of this function checks for b.err.  b.err never gets cleared, and as a 
result no further writes can occur.   

I don't see anything else in bufio that would clear b.err.  How is this 
supposed to work when underlying io.Writer only write partial data.

Regards,
Bhupesh

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to