From ccd206718a18a6b36198b3041cd69ca8ef33d97f Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Mon, 19 Feb 2024 23:49:22 +0200 Subject: [PATCH] Fix accidental deadlock in metrics --- .../subspace-farmer/commands/farm/metrics.rs | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs index 42d9180b82..4de52aa86a 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs @@ -298,14 +298,20 @@ impl FarmerMetrics { // Never called, doesn't make sense } SectorState::Plotted => { - let not_plotted_sectors = self.sectors_total.get_or_create(&vec![ - ("farm_id".to_string(), single_disk_farm_id.to_string()), - ("state".to_string(), SectorState::NotPlotted.to_string()), - ]); - if not_plotted_sectors.get() > 0 { - // Initial plotting - not_plotted_sectors.dec(); - } else { + // Separate blocks in because of mutex guard returned by `get_or_create` resulting + // in deadlock otherwise + { + let not_plotted_sectors = self.sectors_total.get_or_create(&vec![ + ("farm_id".to_string(), single_disk_farm_id.to_string()), + ("state".to_string(), SectorState::NotPlotted.to_string()), + ]); + if not_plotted_sectors.get() > 0 { + // Initial plotting + not_plotted_sectors.dec(); + return; + } + } + { let expired_sectors = self.sectors_total.get_or_create(&vec![ ("farm_id".to_string(), single_disk_farm_id.to_string()), ("state".to_string(), SectorState::Expired.to_string()), @@ -313,16 +319,16 @@ impl FarmerMetrics { if expired_sectors.get() > 0 { // Replaced expired sector expired_sectors.dec(); - } else { - // Replaced about to expire sector - self.sectors_total - .get_or_create(&vec![ - ("farm_id".to_string(), single_disk_farm_id.to_string()), - ("state".to_string(), SectorState::AboutToExpire.to_string()), - ]) - .dec(); + return; } } + // Replaced about to expire sector + self.sectors_total + .get_or_create(&vec![ + ("farm_id".to_string(), single_disk_farm_id.to_string()), + ("state".to_string(), SectorState::AboutToExpire.to_string()), + ]) + .dec(); } SectorState::AboutToExpire | SectorState::Expired => { self.sectors_total