...
1
2 package syncwriter
3
4 import (
5 "errors"
6 "fmt"
7 "io"
8 "os"
9 "sync"
10 "syscall"
11 )
12
13
14 type Writer struct {
15 mu sync.Mutex
16 w io.Writer
17
18 errorf func(f string, v ...interface{})
19 }
20
21
22 func New(w io.Writer) *Writer {
23 return &Writer{
24 w: w,
25
26 errorf: func(f string, v ...interface{}) {
27 println(fmt.Sprintf(f, v...))
28 },
29 }
30 }
31
32 func (w *Writer) Write(name string, p []byte) {
33 w.mu.Lock()
34 defer w.mu.Unlock()
35 _, err := w.w.Write(p)
36 if err != nil {
37 w.errorf("%v: failed to write entry: %+v", name, err)
38 }
39 }
40
41 type syncer interface {
42 Sync() error
43 }
44
45 var _ syncer = &os.File{}
46
47
48
49 func (w *Writer) Sync(sinkName string) {
50 w.mu.Lock()
51 defer w.mu.Unlock()
52
53 s, ok := w.w.(syncer)
54 if !ok {
55 return
56 }
57 err := s.Sync()
58 if _, ok := w.w.(*os.File); ok {
59
60
61
62
63
64 if errorsIsAny(err, syscall.EINVAL, syscall.ENOTTY, syscall.EBADF) {
65 return
66 }
67 }
68
69 w.errorf("failed to sync %v: %+v", sinkName, err)
70 }
71
72 func errorsIsAny(err error, errs ...error) bool {
73 for _, e := range errs {
74 if errors.Is(err, e) {
75 return true
76 }
77 }
78 return false
79 }
80
View as plain text