Files
cloudpods/pkg/multicloud/azure/progress/readerWithProgress.go

61 lines
2.1 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package progress
import (
"io"
"time"
)
// ReaderWithProgress wraps an io.ReadCloser, it track and report the read progress.
//
type ReaderWithProgress struct {
ProgressChan <-chan *Record
innerReadCloser io.ReadCloser
progressStatus *Status
}
// NewReaderWithProgress creates a new instance of ReaderWithProgress. The parameter inner is the inner stream whose
// read progress needs to be tracked, sizeInBytes is the total size of the inner stream in bytes,
// progressIntervalInSeconds is the interval at which the read progress needs to be send to ProgressChan channel.
// After using the this reader, it must be closed by calling Close method to avoid goroutine leak.
//
func NewReaderWithProgress(inner io.ReadCloser, sizeInBytes int64, progressIntervalInSeconds time.Duration) *ReaderWithProgress {
r := &ReaderWithProgress{}
r.innerReadCloser = inner
r.progressStatus = NewStatus(0, 0, sizeInBytes, NewComputestateDefaultSize())
r.ProgressChan = r.progressStatus.Run()
return r
}
// Read reads up to len(b) bytes from the inner stream. It returns the number of bytes read and an error, if any.
// EOF is signaled when no more data to read and n will set to 0.
//
func (r *ReaderWithProgress) Read(p []byte) (n int, err error) {
n, err = r.innerReadCloser.Read(p)
if err == nil {
r.progressStatus.ReportBytesProcessedCount(int64(n))
}
return
}
// Close closes the inner stream and stop reporting read progress in the ProgressChan chan.
//
func (r *ReaderWithProgress) Close() error {
err := r.innerReadCloser.Close()
r.progressStatus.Close()
return err
}