github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/engine/runtimelog/reader.go (about)

     1  package runtimelog
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  // A reader that will stop returning data after its context has been canceled.
    11  //
    12  // If any data is read from the underlying stream after the cancel happens, throw the data out.
    13  type HardCancelReader struct {
    14  	ctx      context.Context
    15  	reader   io.Reader
    16  	Now      func() time.Time
    17  	mu       sync.Mutex
    18  	lastRead time.Time
    19  }
    20  
    21  func NewHardCancelReader(ctx context.Context, reader io.Reader) *HardCancelReader {
    22  	return &HardCancelReader{ctx: ctx, reader: reader, Now: time.Now}
    23  }
    24  
    25  func (r *HardCancelReader) LastReadTime() time.Time {
    26  	r.mu.Lock()
    27  	defer r.mu.Unlock()
    28  	return r.lastRead
    29  }
    30  
    31  func (r *HardCancelReader) Read(b []byte) (int, error) {
    32  	err := r.ctx.Err()
    33  	if err != nil {
    34  		return 0, err
    35  	}
    36  	n, err := r.reader.Read(b)
    37  	if r.ctx.Err() != nil {
    38  		return 0, r.ctx.Err()
    39  	}
    40  
    41  	r.mu.Lock()
    42  	defer r.mu.Unlock()
    43  	r.lastRead = r.Now()
    44  
    45  	return n, err
    46  }