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 }