/
writer.go
57 lines (48 loc) · 1.22 KB
/
writer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package readwhilewrite
import (
"errors"
"io"
)
// Writer is a writer which notifies readers of writes.
type Writer struct {
io.WriteCloser
err error
notifier notifier
}
// WriteAborted is an error which is returned to Read of readers
// when Abort and then Close is called for a writer.
var WriteAborted = errors.New("write aborted")
// NewWriter creates a notifying writer.
func NewWriter(w io.WriteCloser) *Writer {
return &Writer{WriteCloser: w}
}
// Write implements the io.Writer interface.
// Write notify readers if n > 0.
func (w *Writer) Write(p []byte) (n int, err error) {
n, err = w.WriteCloser.Write(p)
if err != nil {
return
}
if n > 0 {
w.notifier.Notify()
}
return
}
// Close closes the underlying writer.
// When readers got EOF after Close is called, it is the real EOF.
func (w *Writer) Close() error {
err := w.WriteCloser.Close()
w.notifier.Close()
return err
}
// Abort is used to make readers stop reading when some error
// happens in the Writer. You must call Close after Abort.
func (w *Writer) Abort() {
w.err = WriteAborted
}
func (w *Writer) subscribe() <-chan struct{} {
return w.notifier.Subscribe()
}
func (w *Writer) unsubscribe(c <-chan struct{}) {
w.notifier.Unsubscribe(c)
}