fix(filersink): return lock-free snapshot from ActiveTransfers (#9604)

ChunkTransferStatus embeds a sync.RWMutex, so returning a slice of it
made callers copy the lock when ranging. Split out a copyable
ChunkTransferSnapshot holding the data fields and return that instead.
This commit is contained in:
Chris Lu
2026-05-21 02:40:04 -07:00
committed by GitHub
parent 2c2b2d4d3e
commit eae8f33db5
2 changed files with 20 additions and 18 deletions
@@ -242,9 +242,11 @@ func (fs *FilerSink) fetchAndWrite(sourceChunk *filer_pb.FileChunk, path string,
}
transferStatus := &ChunkTransferStatus{
ChunkFileId: sourceChunk.GetFileIdString(),
Path: path,
Status: "downloading",
ChunkTransferSnapshot: ChunkTransferSnapshot{
ChunkFileId: sourceChunk.GetFileIdString(),
Path: path,
Status: "downloading",
},
}
fs.activeTransfers.Store(sourceChunk.GetFileIdString(), transferStatus)
defer fs.activeTransfers.Delete(sourceChunk.GetFileIdString())
+15 -15
View File
@@ -22,12 +22,9 @@ import (
"github.com/seaweedfs/seaweedfs/weed/util"
)
// ChunkTransferStatus tracks the progress of a single chunk being replicated.
// Fields are guarded by mu: ChunkFileId and Path are immutable after creation,
// while BytesReceived, Status, and LastErr are updated by fetchAndWrite and
// read by ActiveTransfers.
type ChunkTransferStatus struct {
mu sync.RWMutex
// ChunkTransferSnapshot is a lock-free, copyable view of a chunk transfer's
// progress, returned by ActiveTransfers.
type ChunkTransferSnapshot struct {
ChunkFileId string
Path string
BytesReceived int64
@@ -35,6 +32,15 @@ type ChunkTransferStatus struct {
LastErr string
}
// ChunkTransferStatus tracks the progress of a single chunk being replicated.
// Fields are guarded by mu: ChunkFileId and Path are immutable after creation,
// while BytesReceived, Status, and LastErr are updated by fetchAndWrite and
// read by ActiveTransfers.
type ChunkTransferStatus struct {
mu sync.RWMutex
ChunkTransferSnapshot
}
type FilerSink struct {
filerSource *source.FilerSource
grpcAddress string
@@ -134,18 +140,12 @@ func (fs *FilerSink) SetChunkConcurrency(concurrency int) {
}
// ActiveTransfers returns an immutable snapshot of all in-progress chunk transfers.
func (fs *FilerSink) ActiveTransfers() []ChunkTransferStatus {
var transfers []ChunkTransferStatus
func (fs *FilerSink) ActiveTransfers() []ChunkTransferSnapshot {
var transfers []ChunkTransferSnapshot
fs.activeTransfers.Range(func(key, value any) bool {
t := value.(*ChunkTransferStatus)
t.mu.RLock()
transfers = append(transfers, ChunkTransferStatus{
ChunkFileId: t.ChunkFileId,
Path: t.Path,
BytesReceived: t.BytesReceived,
Status: t.Status,
LastErr: t.LastErr,
})
transfers = append(transfers, t.ChunkTransferSnapshot)
t.mu.RUnlock()
return true
})