1
0
mirror of https://github.com/rclone/rclone.git synced 2025-01-24 12:56:36 +02:00

accounting: allow up to 100 completed transfers in the accounting list

This fixes the core/transfers rc so it shows items again.
This commit is contained in:
Nick Craig-Wood 2019-10-16 20:11:11 +01:00
parent b002ff8d54
commit d40972bf1a
4 changed files with 64 additions and 7 deletions

View File

@ -13,6 +13,9 @@ import (
"github.com/rclone/rclone/fs/rc" "github.com/rclone/rclone/fs/rc"
) )
// Maximum number of completed transfers in startedTransfers list
const maxCompletedTransfers = 100
// StatsInfo accounts all transfers // StatsInfo accounts all transfers
type StatsInfo struct { type StatsInfo struct {
mu sync.RWMutex mu sync.RWMutex
@ -560,10 +563,11 @@ func (s *StatsInfo) AddTransfer(transfer *Transfer) {
s.mu.Unlock() s.mu.Unlock()
} }
// RemoveTransfer removes a reference to the started transfer. // removeTransfer removes a reference to the started transfer in
func (s *StatsInfo) RemoveTransfer(transfer *Transfer) { // position i.
s.mu.Lock() //
// Must be called with the lock held
func (s *StatsInfo) removeTransfer(transfer *Transfer, i int) {
// add finished transfer onto old time ranges // add finished transfer onto old time ranges
start, end := transfer.TimeRange() start, end := transfer.TimeRange()
if end.IsZero() { if end.IsZero() {
@ -572,12 +576,33 @@ func (s *StatsInfo) RemoveTransfer(transfer *Transfer) {
s.oldTimeRanges = append(s.oldTimeRanges, timeRange{start, end}) s.oldTimeRanges = append(s.oldTimeRanges, timeRange{start, end})
s.oldTimeRanges.merge() s.oldTimeRanges.merge()
// remove the found entry
s.startedTransfers = append(s.startedTransfers[:i], s.startedTransfers[i+1:]...)
}
// RemoveTransfer removes a reference to the started transfer.
func (s *StatsInfo) RemoveTransfer(transfer *Transfer) {
s.mu.Lock()
for i, tr := range s.startedTransfers { for i, tr := range s.startedTransfers {
if tr == transfer { if tr == transfer {
// remove the found entry s.removeTransfer(tr, i)
s.startedTransfers = append(s.startedTransfers[:i], s.startedTransfers[i+1:]...)
break break
} }
} }
s.mu.Unlock() s.mu.Unlock()
} }
// PruneTransfers makes sure there aren't too many old transfers
func (s *StatsInfo) PruneTransfers() {
s.mu.Lock()
// remove a transfer from the start if we are over quota
if len(s.startedTransfers) > maxCompletedTransfers+fs.Config.Transfers {
for i, tr := range s.startedTransfers {
if tr.IsDone() {
s.removeTransfer(tr, i)
break
}
}
}
s.mu.Unlock()
}

View File

@ -137,6 +137,8 @@ This returns stats about completed transfers:
If group is not provided then completed transfers for all groups will be If group is not provided then completed transfers for all groups will be
returned. returned.
Note only the last 100 completed transfers are returned.
Parameters Parameters
- group - name of the stats group (string) - group - name of the stats group (string)

View File

@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/fserrors"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -306,3 +307,30 @@ func TestTimeRangeDuration(t *testing.T) {
assert.Equal(t, 1*time.Second, makeTimeRanges(t, []string{"1-2"}).total()) assert.Equal(t, 1*time.Second, makeTimeRanges(t, []string{"1-2"}).total())
assert.Equal(t, 91*time.Second, makeTimeRanges(t, []string{"1-2", "10-100"}).total()) assert.Equal(t, 91*time.Second, makeTimeRanges(t, []string{"1-2", "10-100"}).total())
} }
func TestPruneTransfers(t *testing.T) {
max := maxCompletedTransfers + fs.Config.Transfers
s := NewStats()
for i := int64(1); i <= int64(max+100); i++ {
s.AddTransfer(&Transfer{
startedAt: time.Unix(i, 0),
completedAt: time.Unix(i+1, 0),
})
}
s.mu.Lock()
assert.Equal(t, time.Duration(max+100)*time.Second, s.totalDuration())
assert.Equal(t, max+100, len(s.startedTransfers))
s.mu.Unlock()
for i := 0; i < 200; i++ {
s.PruneTransfers()
}
s.mu.Lock()
assert.Equal(t, time.Duration(max+100)*time.Second, s.totalDuration())
assert.Equal(t, max, len(s.startedTransfers))
s.mu.Unlock()
}

View File

@ -102,6 +102,8 @@ func (tr *Transfer) Done(err error) {
} }
// Signal done with accounting // Signal done with accounting
acc.Done() acc.Done()
// free the account since we may keep the transfer
acc = nil
} }
tr.mu.Lock() tr.mu.Lock()
@ -113,7 +115,7 @@ func (tr *Transfer) Done(err error) {
} else { } else {
tr.stats.DoneTransferring(tr.remote, err == nil) tr.stats.DoneTransferring(tr.remote, err == nil)
} }
tr.stats.RemoveTransfer(tr) tr.stats.PruneTransfers()
} }
// Reset allows to switch the Account to another transfer method. // Reset allows to switch the Account to another transfer method.