-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Overview:
Currently, bufio.Writer does not provide a way to retrieve data that has not been successfully written. If a Flush() call fails, data in the buffer cannot be written to the underlying io.Writer.
Even if flush is called continuously, it will always fail.
func (b *Writer) Flush() error {
if b.err != nil {
return b.err
}
//....
}We propose adding an UnwrittenData() method to allow users to retrieve data that has not been successfully written in case of a failed Flush(), enabling additional processing or retrying.
Motivation:
In some cases, Flush() may fail, for example, due to a network interruption or the underlying io.Writer closing. This could result in some data in the buffer not being written to the underlying io.Writer and being lost, which could cause inconsistencies in the application state or data loss. Therefore, users need a way to retrieve data in the buffer that has not been successfully written.
Proposal:
We propose adding an UnwrittenData() method that returns data in the buffer that has not been successfully written.
type Writer struct {
// ...
}
func (w *Writer) UnwrittenData() []byte {
return w.buf[:w.n]
}If the data in the buffer has been successfully written to the underlying io.Writer before Flush() is called, UnwrittenData() returns an empty byte slice.
Compatibility:
This proposal has no impact on compatibility with existing code, as the new method does not modify existing interfaces or behavior.
Implementation:
The proposed method only needs to return data in the buffer that has not been successfully written, and does not need to modify any existing code or behavior.
Example:
Here is an example of how the UnwrittenData() method could be used:
w := bufio.NewWriter(conn)
// Write some data to the buffer
w.WriteString("hello")
w.WriteString("world")
// Try to write to the underlying io.Writer, retrieve any unwritten data on failure and handle it
if err := w.Flush(); err != nil {
unwrittenData := w.UnwrittenData()
log.Printf("Unwritten data: %v\n", unwrittenData)
// Try to rewrite unwritten data by conn
if _, err := conn.Write(unwrittenData); err != nil {
log.Printf("Write unwritten data failed: %v\n", err)
}
}