github.com/sujit-baniya/log@v1.0.73/async.go (about) 1 package log 2 3 import ( 4 "io" 5 "sync" 6 ) 7 8 // AsyncWriter is an Writer that writes asynchronously. 9 type AsyncWriter struct { 10 // ChannelSize is the size of the data channel, the default size is 1. 11 ChannelSize uint 12 13 // Writer specifies the writer of output. 14 Writer Writer 15 16 once sync.Once 17 ch chan *Entry 18 chClose chan error 19 } 20 21 // Close implements io.Closer, and closes the underlying Writer. 22 func (w *AsyncWriter) Close() (err error) { 23 w.ch <- nil 24 err = <-w.chClose 25 if closer, ok := w.Writer.(io.Closer); ok { 26 if err1 := closer.Close(); err1 != nil { 27 err = err1 28 } 29 } 30 return 31 } 32 33 // WriteEntry implements Writer. 34 func (w *AsyncWriter) WriteEntry(e *Entry) (int, error) { 35 w.once.Do(func() { 36 // channels 37 w.ch = make(chan *Entry, w.ChannelSize) 38 w.chClose = make(chan error) 39 go func() { 40 var err error 41 for entry := range w.ch { 42 if entry == nil { 43 break 44 } 45 _, err = w.Writer.WriteEntry(entry) 46 epool.Put(entry) 47 } 48 w.chClose <- err 49 }() 50 }) 51 52 // cheating to logger pool 53 entry := epool.Get().(*Entry) 54 entry.Level = e.Level 55 entry.buf, e.buf = e.buf, entry.buf 56 57 w.ch <- entry 58 return len(entry.buf), nil 59 } 60 61 var _ Writer = (*AsyncWriter)(nil)