From d392f9fcd8e1403916a741f58278e59281241ab0 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 4 Jan 2024 11:39:51 +0000 Subject: [PATCH] accounting: fix stats to show server side transfers Before this fix we were not counting transferred files nor transferred bytes for server side moves/copies. If the server side move/copy has been marked as a transfer and not a checker then this accounts transferred files and transferred bytes. The transferred bytes are not accounted to the network though so this should not affect the network stats. --- fs/accounting/accounting.go | 33 ++++++++++++++++++++++----------- fs/accounting/stats.go | 7 +++++++ fs/accounting/transfer.go | 1 + 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/fs/accounting/accounting.go b/fs/accounting/accounting.go index 29681b604..41eb71225 100644 --- a/fs/accounting/accounting.go +++ b/fs/accounting/accounting.go @@ -49,17 +49,18 @@ type Account struct { // in http transport calls Read() after Do() returns on // CancelRequest so this race can happen when it apparently // shouldn't. - mu sync.Mutex // mutex protects these values - in io.Reader - ctx context.Context // current context for transfer - may change - ci *fs.ConfigInfo - origIn io.ReadCloser - close io.Closer - size int64 - name string - closed bool // set if the file is closed - exit chan struct{} // channel that will be closed when transfer is finished - withBuf bool // is using a buffered in + mu sync.Mutex // mutex protects these values + in io.Reader + ctx context.Context // current context for transfer - may change + ci *fs.ConfigInfo + origIn io.ReadCloser + close io.Closer + size int64 + name string + closed bool // set if the file is closed + exit chan struct{} // channel that will be closed when transfer is finished + withBuf bool // is using a buffered in + checking bool // set if attached transfer is checking tokenBucket buckets // per file bandwidth limiter (may be nil) @@ -295,14 +296,24 @@ func (acc *Account) ServerSideTransferEnd(n int64) { acc.stats.Bytes(n) } +// serverSideEnd accounts for non specific server side data +func (acc *Account) serverSideEnd(n int64) { + // Account for bytes unless we are checking + if !acc.checking { + acc.stats.BytesNoNetwork(n) + } +} + // ServerSideCopyEnd accounts for a read of n bytes in a sever side copy func (acc *Account) ServerSideCopyEnd(n int64) { acc.stats.AddServerSideCopy(n) + acc.serverSideEnd(n) } // ServerSideMoveEnd accounts for a read of n bytes in a sever side move func (acc *Account) ServerSideMoveEnd(n int64) { acc.stats.AddServerSideMove(n) + acc.serverSideEnd(n) } // DryRun accounts for statistics without running the operation diff --git a/fs/accounting/stats.go b/fs/accounting/stats.go index 24c9bcda1..665f03451 100644 --- a/fs/accounting/stats.go +++ b/fs/accounting/stats.go @@ -527,6 +527,13 @@ func (s *StatsInfo) Bytes(bytes int64) { s.bytes += bytes } +// BytesNoNetwork updates the stats for bytes bytes but doesn't include the transfer stats +func (s *StatsInfo) BytesNoNetwork(bytes int64) { + s.mu.Lock() + defer s.mu.Unlock() + s.bytes += bytes +} + // GetBytes returns the number of bytes transferred so far func (s *StatsInfo) GetBytes() int64 { s.mu.RLock() diff --git a/fs/accounting/transfer.go b/fs/accounting/transfer.go index d4515e201..5860eefb2 100644 --- a/fs/accounting/transfer.go +++ b/fs/accounting/transfer.go @@ -149,6 +149,7 @@ func (tr *Transfer) Account(ctx context.Context, in io.ReadCloser) *Account { } else { tr.acc.UpdateReader(ctx, in) } + tr.acc.checking = tr.checking tr.mu.Unlock() return tr.acc }