You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
package main
import (
"bufio"
"log"
"os"
"strings"
"time"
)
var buf = make([]byte, 1024*1024)
func main() {
fh, err := os.OpenFile("bufio.file", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0777)
if err != nil {
log.Fatal(err)
}
bw := bufio.NewWriterSize(fh, 16*1024)
var cnt int64
for {
n, err := bw.Write(buf)
if err != nil {
if strings.Contains(err.Error(), "no space") {
time.Sleep(time.Second)
log.Println("no space, sleep 1 second")
if err := bw.Flush(); err != nil {
log.Println(err)
} else {
log.Println("recovered")
}
continue
}
log.Println(err)
}
cnt += int64(n)
if cnt%(1024*1024*1024) == 0 {
log.Printf("%v written\n", cnt)
}
}
}
I run program built from codes above on a file system with little size left. Soon, the program logs error write bufio.file: no space left on device. Then I clear some disk files and make room for the program writes, but the program still gets error write bufio.file: no space left on device.
I dig into the golang source code and get the reason: the Writer's err is set at the first time when the no space left on device returned. Moreover, there's no method to clear the error unless call Writer.Reset(), which would also clear the data that the Writer buffed.
What did you expect to see?
When the file system capacity is OK, retry to calling Writer.Write()/Flush() and the failure would recover.
What did you see instead?
The failure exists forever even if the file system capacity is OK.
The text was updated successfully, but these errors were encountered:
It is common case to handle temporary failure in IO. Is it better to try to do write every time the Writer.Write()/Flush() is called than just to return the stale error simply ?
rickif
changed the title
bufio: Writer failures forever even if enviroment's temporary error is recoverd
bufio: Writer failures forever even if the temporary error is recoverd
Feb 5, 2021
The way that the bufio package handles write errors is by design, so that it is not necessary for callers to check the error result on every call to Write. This is documented at https://golang.org/pkg/bufio/#Writer. There is no general way to address this, as the current library doesn't provide a way to distinguish between permanent and temporary errors on Write.
The result of these decisions is that the bufio package is not suitable for your purpose. You should either use your own buffering package instead of bufio, or you should use your own io.Writer that handles temporary errors in the Write method called by bufio.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I run program built from codes above on a file system with little size left. Soon, the program logs error
write bufio.file: no space left on device
. Then I clear some disk files and make room for the program writes, but the program still gets errorwrite bufio.file: no space left on device
.go/src/bufio/bufio.go
Lines 633 to 655 in 8869086
go/src/bufio/bufio.go
Lines 600 to 621 in 8869086
I dig into the golang source code and get the reason: the Writer's err is set at the first time when the
no space left on device
returned. Moreover, there's no method to clear the error unless callWriter.Reset()
, which would also clear the data that the Writer buffed.What did you expect to see?
When the file system capacity is OK, retry to calling
Writer.Write()/Flush()
and the failure would recover.What did you see instead?
The failure exists forever even if the file system capacity is OK.
The text was updated successfully, but these errors were encountered: