[PR #187] [MERGED] fix: prevent concurrent RefreshDataAsync calls with SemaphoreSlim #178

Closed
opened 2026-02-26 17:37:38 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Corsinvest/cv4pve-admin/pull/187
Author: @franklupo
Created: 2/21/2026
Status: Merged
Merged: 2/21/2026
Merged by: @franklupo

Base: mainHead: fix/refreshdata-semaphore-concurrency


📝 Commits (1)

  • 9899c3a fix: prevent concurrent RefreshDataAsync calls with SemaphoreSlim

📊 Changes

22 files changed (+285 additions, -146 deletions)

View changed files

📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Cluster/Replication.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Cluster/ResourcesEx.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Common/Tasks.razor.cs (+30 -13)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Charts.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Disks.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Replication.razor.cs (+38 -21)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Summary.razor.cs (+23 -4)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Storage/Charts.razor.cs (+21 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Vm/Charts.razor.cs (+26 -8)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Vm/Snapshot/Manager.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Vm/Summary.razor.cs (+22 -4)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetDonutBase.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetInfoBase.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetSparklineBase.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetThumbDetailsBase.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Module.AutoSnap/Components/Status.razor.cs (+45 -32)
📝 src/Corsinvest.ProxmoxVE.Admin.Module.AutoSnap/Components/Timeline.razor.cs (+45 -31)
📝 src/Corsinvest.ProxmoxVE.Admin.Module.Resources/Components/Widgets/ClusterUsage/Gauge.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Module.Resources/Components/Widgets/ClusterUsage/GaugeStacked.razor.cs (+1 -2)
📝 src/Corsinvest.ProxmoxVE.Admin.Module.Resources/Components/Widgets/ClusterUsage/Grid.razor.cs (+1 -2)

...and 2 more files

📄 Description

Summary

  • Add SemaphoreSlim(1,1) protection to components called from background Timer threads (every 2s) to prevent overlapping async executions
  • Compact the existing double-guard pattern (if (_disposed) { return; } + if (!await _refreshLock.WaitAsync(0)) { return; }) into a single short-circuit expression across all already-protected components

Components receiving new SemaphoreSlim + IDisposable

  • ProxmoxVE/Common/Tasks — called by Vm/Nodes Manager timer
  • ProxmoxVE/Nodes/Replication, Summary — called by Nodes Manager timer (2s)
  • ProxmoxVE/Storage/Charts — called by Storage Manager timer (30s)
  • ProxmoxVE/Vm/Charts, Summary — called by Vm Manager timer (2s)
  • AutoSnap/Status, Timeline — called via event notifications
  • Updater/Scans — called via event notifications

Components with compacted if-guard only (no logic change)

  • ProxmoxVE/Cluster/Replication, ResourcesEx
  • ProxmoxVE/Nodes/Charts, Disks
  • ProxmoxVE/Vm/Snapshot/Manager
  • Widgets/WidgetDonutBase, WidgetInfoBase, WidgetSparklineBase, WidgetThumbDetailsBase
  • Resources/Widgets/ClusterUsage/Gauge, GaugeStacked, Grid
  • Resources/Widgets/Maps/Render

Test plan

  • Open a Node manager and verify Summary/Charts tabs refresh without errors
  • Open a VM manager and verify Summary/Charts tabs refresh without errors
  • Open a Storage manager and verify Charts tab refreshes without errors
  • Open AutoSnap Status and Timeline — verify data loads correctly
  • Open Updater Scans — verify data loads correctly
  • Navigate away from components and verify no ObjectDisposedException in logs

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Corsinvest/cv4pve-admin/pull/187 **Author:** [@franklupo](https://github.com/franklupo) **Created:** 2/21/2026 **Status:** ✅ Merged **Merged:** 2/21/2026 **Merged by:** [@franklupo](https://github.com/franklupo) **Base:** `main` ← **Head:** `fix/refreshdata-semaphore-concurrency` --- ### 📝 Commits (1) - [`9899c3a`](https://github.com/Corsinvest/cv4pve-admin/commit/9899c3aa7036975209ee241e4720827c104d13a4) fix: prevent concurrent RefreshDataAsync calls with SemaphoreSlim ### 📊 Changes **22 files changed** (+285 additions, -146 deletions) <details> <summary>View changed files</summary> 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Cluster/Replication.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Cluster/ResourcesEx.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Common/Tasks.razor.cs` (+30 -13) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Charts.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Disks.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Replication.razor.cs` (+38 -21) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Nodes/Summary.razor.cs` (+23 -4) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Storage/Charts.razor.cs` (+21 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Vm/Charts.razor.cs` (+26 -8) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Vm/Snapshot/Manager.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/ProxmoxVE/Vm/Summary.razor.cs` (+22 -4) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetDonutBase.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetInfoBase.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetSparklineBase.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Core/Components/Widgets/WidgetThumbDetailsBase.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Module.AutoSnap/Components/Status.razor.cs` (+45 -32) 📝 `src/Corsinvest.ProxmoxVE.Admin.Module.AutoSnap/Components/Timeline.razor.cs` (+45 -31) 📝 `src/Corsinvest.ProxmoxVE.Admin.Module.Resources/Components/Widgets/ClusterUsage/Gauge.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Module.Resources/Components/Widgets/ClusterUsage/GaugeStacked.razor.cs` (+1 -2) 📝 `src/Corsinvest.ProxmoxVE.Admin.Module.Resources/Components/Widgets/ClusterUsage/Grid.razor.cs` (+1 -2) _...and 2 more files_ </details> ### 📄 Description ## Summary - Add `SemaphoreSlim(1,1)` protection to components called from background Timer threads (every 2s) to prevent overlapping async executions - Compact the existing double-guard pattern (`if (_disposed) { return; }` + `if (!await _refreshLock.WaitAsync(0)) { return; }`) into a single short-circuit expression across all already-protected components ## Components receiving new SemaphoreSlim + IDisposable - `ProxmoxVE/Common/Tasks` — called by Vm/Nodes Manager timer - `ProxmoxVE/Nodes/Replication`, `Summary` — called by Nodes Manager timer (2s) - `ProxmoxVE/Storage/Charts` — called by Storage Manager timer (30s) - `ProxmoxVE/Vm/Charts`, `Summary` — called by Vm Manager timer (2s) - `AutoSnap/Status`, `Timeline` — called via event notifications - `Updater/Scans` — called via event notifications ## Components with compacted if-guard only (no logic change) - `ProxmoxVE/Cluster/Replication`, `ResourcesEx` - `ProxmoxVE/Nodes/Charts`, `Disks` - `ProxmoxVE/Vm/Snapshot/Manager` - `Widgets/WidgetDonutBase`, `WidgetInfoBase`, `WidgetSparklineBase`, `WidgetThumbDetailsBase` - `Resources/Widgets/ClusterUsage/Gauge`, `GaugeStacked`, `Grid` - `Resources/Widgets/Maps/Render` ## Test plan - [ ] Open a Node manager and verify Summary/Charts tabs refresh without errors - [ ] Open a VM manager and verify Summary/Charts tabs refresh without errors - [ ] Open a Storage manager and verify Charts tab refreshes without errors - [ ] Open AutoSnap Status and Timeline — verify data loads correctly - [ ] Open Updater Scans — verify data loads correctly - [ ] Navigate away from components and verify no ObjectDisposedException in logs --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-26 17:37:38 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/cv4pve-admin#178
No description provided.