github.com/Microsoft/azure-vhd-utils@v0.0.0-20230613175315-7c30a3748a1b/upload/progress/readerWithProgress.go (about) 1 package progress 2 3 import ( 4 "io" 5 "time" 6 ) 7 8 // ReaderWithProgress wraps an io.ReadCloser, it track and report the read progress. 9 // 10 type ReaderWithProgress struct { 11 ProgressChan <-chan *Record 12 innerReadCloser io.ReadCloser 13 progressStatus *Status 14 } 15 16 // NewReaderWithProgress creates a new instance of ReaderWithProgress. The parameter inner is the inner stream whose 17 // read progress needs to be tracked, sizeInBytes is the total size of the inner stream in bytes, 18 // progressIntervalInSeconds is the interval at which the read progress needs to be send to ProgressChan channel. 19 // After using the this reader, it must be closed by calling Close method to avoid goroutine leak. 20 // 21 func NewReaderWithProgress(inner io.ReadCloser, sizeInBytes int64, progressIntervalInSeconds time.Duration) *ReaderWithProgress { 22 r := &ReaderWithProgress{} 23 r.innerReadCloser = inner 24 r.progressStatus = NewStatus(0, 0, sizeInBytes, NewComputestateDefaultSize()) 25 r.ProgressChan = r.progressStatus.Run() 26 return r 27 } 28 29 // Read reads up to len(b) bytes from the inner stream. It returns the number of bytes read and an error, if any. 30 // EOF is signaled when no more data to read and n will set to 0. 31 // 32 func (r *ReaderWithProgress) Read(p []byte) (n int, err error) { 33 n, err = r.innerReadCloser.Read(p) 34 if err == nil { 35 r.progressStatus.ReportBytesProcessedCount(int64(n)) 36 } 37 return 38 } 39 40 // Close closes the inner stream and stop reporting read progress in the ProgressChan chan. 41 // 42 func (r *ReaderWithProgress) Close() error { 43 err := r.innerReadCloser.Close() 44 r.progressStatus.Close() 45 return err 46 }