be0464f5f1
This is done to make clear ownership over accounting object and prepare for removing global stats object. Stats elapsed time calculation has been altered to account for actual transfer time instead of stats creation time.
72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
package accounting
|
|
|
|
import (
|
|
"io"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/ncw/rclone/fs"
|
|
)
|
|
|
|
// Transfer keeps track of initiated transfers and provides access to
|
|
// accounting functions.
|
|
// Transfer needs to be closed on completion.
|
|
type Transfer struct {
|
|
stats *StatsInfo
|
|
acc *Account
|
|
remote string
|
|
size int64
|
|
|
|
mu sync.Mutex
|
|
startedAt time.Time
|
|
completedAt time.Time
|
|
}
|
|
|
|
// newTransfer instantiates new transfer
|
|
func newTransfer(stats *StatsInfo, obj fs.Object) *Transfer {
|
|
return newTransferRemoteSize(stats, obj.Remote(), obj.Size())
|
|
}
|
|
|
|
func newTransferRemoteSize(stats *StatsInfo, remote string, size int64) *Transfer {
|
|
tr := &Transfer{
|
|
stats: stats,
|
|
remote: remote,
|
|
size: size,
|
|
startedAt: time.Now(),
|
|
}
|
|
stats.AddTransfer(tr)
|
|
return tr
|
|
}
|
|
|
|
// Done ends the transfer.
|
|
// Must be called after transfer is finished to run proper cleanups.
|
|
func (tr *Transfer) Done(err error) {
|
|
if err != nil {
|
|
tr.stats.Error(err)
|
|
}
|
|
if tr.acc != nil {
|
|
if err := tr.acc.Close(); err != nil {
|
|
fs.LogLevelPrintf(fs.Config.StatsLogLevel, nil, "can't close account: %+v\n", err)
|
|
}
|
|
}
|
|
tr.stats.DoneTransferring(tr.remote, err == nil)
|
|
tr.mu.Lock()
|
|
tr.completedAt = time.Now()
|
|
tr.mu.Unlock()
|
|
}
|
|
|
|
// Account returns reader that knows how to keep track of transfer progress.
|
|
func (tr *Transfer) Account(in io.ReadCloser) *Account {
|
|
if tr.acc != nil {
|
|
return tr.acc
|
|
}
|
|
return newAccountSizeName(tr.stats, in, tr.size, tr.remote)
|
|
}
|
|
|
|
// TimeRange returns the time transfer started and ended at. If not completed
|
|
// it will return zero time for end time.
|
|
func (tr *Transfer) TimeRange() (time.Time, time.Time) {
|
|
tr.mu.Lock()
|
|
defer tr.mu.Unlock()
|
|
return tr.startedAt, tr.completedAt
|
|
}
|