mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-23 22:48:06 +08:00
61 lines
2.1 KiB
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
|
|
}
|