github.com/oarkflow/log@v1.0.78/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)