Skip to content

fix: lighten Resource History sampler, speed up loads, tidy shutdown#1156

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/resource-history-robustness
Jun 29, 2026
Merged

fix: lighten Resource History sampler, speed up loads, tidy shutdown#1156
laurentiu021 merged 1 commit into
mainfrom
fix/resource-history-robustness

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

What

Performance + robustness fixes for Resource History (#13), from the post-feature audit (Batch 3 of 6).

Fixes

  1. Always-on sampler no longer does per-poll disk WMI + SMART (perf, HIGH). The 10s sampler called TemperatureService.ReadAllAsync(), which on an elevated machine runs a Win32_DiskDrive WMI query plus a full DiskHealthService SMART enumeration just to name storage sensors — data the sampler discards (it stores only CPU/GPU temps). Added ReadAllAsync(includeStorage: false) that skips that; the sampler uses it. ~8,640 needless WMI/SMART enumerations/day eliminated on a tray-minimized session. The Dashboard keeps the full read (default true) — no behavior change there.
  2. LoadAsync parsed the whole file every time (perf, HIGH). Up to ~260k lines at 30-day retention, allocating a sample per line then discarding 99% for a "last hour" view. It now reads from the newest end and stops at the cutoff, bounding work to the requested window.
  3. Dispose race (robustness). Dispose disposed _fileLock without awaiting the sampler loop, so an in-flight Release() could hit a disposed semaphore at shutdown (caught+logged, but a real race). Dispose now waits (bounded 2s) for the loop to cancel first, guards Release with _disposed, and PruneAsync takes a cancellation token.
  4. Temperature EmptyState (UX). The temperature chart now shows a "no temperature data" message on sensorless machines instead of a blank chart.

Tests

Downsample boundary tests: maxPoints 0 (clamp), 1 (averages whole series), exactly-N (unchanged), partial-GPU-nulls (averages over present values only).

Docs

CHANGELOG 1.51.3, version bump to 1.51.3.

Part of the post-feature audit remediation (Batch 3 of 6).

- The always-on 10s sampler called TemperatureService.ReadAllAsync(), which on an
  elevated box runs a Win32_DiskDrive WMI query plus a full DiskHealthService SMART
  enumeration just to NAME storage sensors — data the sampler discards (it stores
  only CPU/GPU temps). Added a ReadAllAsync(includeStorage:false) fast path that
  skips the storage-name lookup and disk-temp read; the sampler now uses it, cutting
  ~8640 WMI/SMART enumerations/day on a tray-minimized session. Dashboard keeps the
  full read (default includeStorage:true) — no behavior change there.
- LoadAsync parsed the ENTIRE NDJSON file (up to ~260k lines at 30-day retention)
  on every range change/tab open, allocating a ResourceSample per line then
  discarding 99%. It now reads from the newest end and stops at the cutoff, bounding
  work to the requested window.
- Dispose disposed _fileLock without awaiting the sampler loop, so an in-flight
  Release() could hit a disposed semaphore at shutdown (caught+logged, but a real
  race). Dispose now waits (bounded 2s) for the loop to observe cancellation first,
  guards Release with _disposed, and PruneAsync takes a cancellation token.
- Temperature chart now shows an EmptyState on sensorless machines instead of a
  blank chart (HasTemperatureData).

Tests: Downsample boundaries (maxPoints 0/1/exactly-N, partial-GPU averaging).
@laurentiu021 laurentiu021 merged commit 99e3db3 into main Jun 29, 2026
5 of 6 checks passed
@laurentiu021 laurentiu021 deleted the fix/resource-history-robustness branch June 29, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant