diff --git a/fs/accounting/transfer.go b/fs/accounting/transfer.go index b18723921..7703345cb 100644 --- a/fs/accounting/transfer.go +++ b/fs/accounting/transfer.go @@ -66,6 +66,7 @@ type Transfer struct { acc *Account err error completedAt time.Time + doneBytes int64 } // newCheckingTransfer instantiates new checking of the object. @@ -116,12 +117,20 @@ func (tr *Transfer) Done(ctx context.Context, err error) { } // Signal done with accounting acc.Done() - // free the account since we may keep the transfer - acc = nil + } + + var doneBytes int64 + if acc != nil { + doneBytes, _ = acc.progress() } tr.mu.Lock() tr.completedAt = time.Now() + if acc != nil { + tr.doneBytes = doneBytes + } + // free the account since we may keep the transfer + tr.acc = nil tr.mu.Unlock() if tr.checking { @@ -181,7 +190,7 @@ func (tr *Transfer) Snapshot() TransferSnapshot { tr.mu.RLock() defer tr.mu.RUnlock() - var s, b int64 = tr.size, 0 + b, s := tr.doneBytes, tr.size if tr.acc != nil { b, s = tr.acc.progress() } diff --git a/fs/accounting/transfer_test.go b/fs/accounting/transfer_test.go index 2aaa3d2c9..a90858ceb 100644 --- a/fs/accounting/transfer_test.go +++ b/fs/accounting/transfer_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "io" + "strings" "testing" "github.com/rclone/rclone/fs/rc" @@ -56,6 +57,26 @@ func TestTransfer(t *testing.T) { assert.Equal(t, "dstFs:dstFs", snap.DstFs) }) + t.Run("DoneReleasesAccount", func(t *testing.T) { + content := "hello world" + o := mockobject.New("obj").WithContent([]byte(content), mockobject.SeekModeNone) + tr := newTransfer(s, o, srcFs, dstFs) + in := tr.Account(ctx, io.NopCloser(strings.NewReader(content))) + _, err := io.Copy(io.Discard, in) + require.NoError(t, err) + + tr.Done(ctx, nil) + + tr.mu.RLock() + acc := tr.acc + tr.mu.RUnlock() + assert.Nil(t, acc) + + snap := tr.Snapshot() + assert.Equal(t, int64(len(content)), snap.Bytes) + assert.Equal(t, int64(len(content)), snap.Size) + }) + t.Run("rcStats", func(t *testing.T) { out := tr.rcStats() assert.Equal(t, rc.Params{