mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-09 05:18:23 +01:00
topology: list collections without nesting the collection map read lock (#12495)
* topology: list collections without nesting the collection map read lock Items() already takes the read lock and copies the values. Holding it around the call made ListCollections take the read lock twice, so a DeleteCollection waiting for the write lock in between blocked the second read lock and wedged the master. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * topology: test ListCollections against a concurrent collection delete Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4ab66fb76d
commit
5c910ad546
2 files changed
+34
-2
No files matched your search
@@ -813,11 +813,9 @@ func (t *Topology) ListCollections(includeNormalVolumes, includeEcVolumes bool)
|
||||
found := make(map[string]bool)
|
||||
|
||||
if includeNormalVolumes {
|
||||
t.collectionMap.RLock()
|
||||
for _, c := range t.collectionMap.Items() {
|
||||
found[c.(*Collection).Name] = true
|
||||
}
|
||||
t.collectionMap.RUnlock()
|
||||
}
|
||||
|
||||
if includeEcVolumes {
|
||||
|
||||
@@ -641,6 +641,40 @@ func TestListCollections(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// A collection delete that queues for the write lock while ListCollections
|
||||
// reads the collections must not wedge both.
|
||||
func TestListCollectionsWithConcurrentCollectionDelete(t *testing.T) {
|
||||
rp, _ := super_block.NewReplicaPlacementFromString("000")
|
||||
topo := NewTopology("weedfs", sequence.NewMemorySequencer(), 32*1024, 5, false)
|
||||
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-stop:
|
||||
return
|
||||
default:
|
||||
}
|
||||
topo.GetVolumeLayout("churn", rp, needle.EMPTY_TTL, types.HardDriveType)
|
||||
topo.DeleteCollection("churn")
|
||||
}
|
||||
}()
|
||||
|
||||
listed := make(chan struct{})
|
||||
go func() {
|
||||
defer close(listed)
|
||||
for i := 0; i < 100000; i++ {
|
||||
topo.ListCollections(true, false)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case <-listed:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("ListCollections deadlocked with a concurrent DeleteCollection")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataNodeIdBasedIdentification(t *testing.T) {
|
||||
topo := NewTopology("weedfs", sequence.NewMemorySequencer(), 32*1024, 5, false)
|
||||
dc := topo.GetOrCreateDataCenter("dc1")
|
||||
|
||||
Reference in new issue
Block a user