github.com/Cloud-Foundations/Dominator@v0.3.4/lib/bufwriter/impl.go (about)

     1  package bufwriter
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"time"
     7  )
     8  
     9  type autoFlushWriter struct {
    10  	writer FlushWriter
    11  }
    12  
    13  func newAutoFlushWriter(w FlushWriter) io.Writer {
    14  	return &autoFlushWriter{w}
    15  }
    16  
    17  func (w *autoFlushWriter) Write(p []byte) (int, error) {
    18  	n, err := w.writer.Write(p)
    19  	if err != nil {
    20  		return n, err
    21  	}
    22  	return n, w.writer.Flush()
    23  }
    24  
    25  func newWriter(writer io.Writer, flushDelay time.Duration) *Writer {
    26  	b := &Writer{flushDelay: flushDelay}
    27  	if bufWriter, ok := writer.(FlushWriter); ok {
    28  		b.flushingWriter = bufWriter
    29  	} else {
    30  		b.flushingWriter = bufio.NewWriter(writer)
    31  	}
    32  	return b
    33  }
    34  
    35  func (b *Writer) delayedFlush() {
    36  	time.Sleep(b.flushDelay)
    37  	b.flush()
    38  }
    39  
    40  func (b *Writer) flush() error {
    41  	b.mutex.Lock()
    42  	defer b.mutex.Unlock()
    43  	flushPending := b.flushPending
    44  	b.flushPending = false
    45  	if b.err != nil {
    46  		return b.err
    47  	}
    48  	if flushPending {
    49  		b.err = b.flushingWriter.Flush()
    50  		return b.err
    51  	}
    52  	return nil
    53  }
    54  
    55  func (b *Writer) lockAndScheduleFlush() {
    56  	b.mutex.Lock()
    57  	if b.flushPending {
    58  		return
    59  	}
    60  	b.flushPending = true
    61  	go b.delayedFlush()
    62  }
    63  
    64  func (b *Writer) write(p []byte) (int, error) {
    65  	if b.flushDelay <= 0 {
    66  		n, err := b.flushingWriter.Write(p)
    67  		if err != nil {
    68  			return n, err
    69  		}
    70  		return n, b.flushingWriter.Flush()
    71  	}
    72  	b.lockAndScheduleFlush()
    73  	defer b.mutex.Unlock()
    74  	if b.err != nil {
    75  		return 0, b.err
    76  	}
    77  	nWritten, err := b.flushingWriter.Write(p)
    78  	b.err = err
    79  	return nWritten, err
    80  }