1
mirror of https://github.com/rclone/rclone synced 2024-11-25 02:47:14 +01: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"
)
// Maximum number of completed transfers in startedTransfers list
const maxCompletedTransfers = 100
// StatsInfo accounts all transfers
type StatsInfo struct {
mu sync.RWMutex
@ -560,10 +563,11 @@ func (s *StatsInfo) AddTransfer(transfer *Transfer) {
s.mu.Unlock()
}
// RemoveTransfer removes a reference to the started transfer.
func (s *StatsInfo) RemoveTransfer(transfer *Transfer) {
s.mu.Lock()
// removeTransfer removes a reference to the started transfer in
// position i.
//
// Must be called with the lock held
func (s *StatsInfo) removeTransfer(transfer *Transfer, i int) {
// add finished transfer onto old time ranges
start, end := transfer.TimeRange()
if end.IsZero() {
@ -572,12 +576,33 @@ func (s *StatsInfo) RemoveTransfer(transfer *Transfer) {
s.oldTimeRanges = append(s.oldTimeRanges, timeRange{start, end})
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 {
if tr == transfer {
// remove the found entry
s.startedTransfers = append(s.startedTransfers[:i], s.startedTransfers[i+1:]...)
s.removeTransfer(tr, i)
break
}
}
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
returned.
Note only the last 100 completed transfers are returned.
Parameters
- group - name of the stats group (string)

View File

@ -7,6 +7,7 @@ import (
"time"
"github.com/pkg/errors"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/fserrors"
"github.com/stretchr/testify/assert"
"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, 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
acc.Done()
// free the account since we may keep the transfer
acc = nil
}
tr.mu.Lock()
@ -113,7 +115,7 @@ func (tr *Transfer) Done(err error) {
} else {
tr.stats.DoneTransferring(tr.remote, err == nil)
}
tr.stats.RemoveTransfer(tr)
tr.stats.PruneTransfers()
}
// Reset allows to switch the Account to another transfer method.