mirror of
https://github.com/fosrl/newt.git
synced 2026-07-16 11:53:33 -05:00
[PR #412] fix(healthcheck): guard target status fields against data race #8992
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/fosrl/newt/pull/412
Author: @lafoush
Created: 7/14/2026
Status: 🔄 Open
Base:
main← Head:fix/healthcheck-status-data-race📝 Commits (1)
a4017befix(healthcheck): guard target status fields against data race📊 Changes
2 files changed (+117 additions, -4 deletions)
View changed files
📝
healthcheck/healthcheck.go(+34 -4)➕
healthcheck/healthcheck_test.go(+83 -0)📄 Description
Problem
monitorTarget/performHealthCheckmutate aTarget'sStatus,LastError,LastCheck,CheckCount, and consecutive-success/failure counters from the target's monitor goroutine. MeanwhilegetAllTargetsUnsafe(called byGetTargets, used for status reporting to the server) copied the whole struct withtargetCopy := *target.The monitor mutex protects the
targetsmap, not the contents of eachTarget, so these accesses overlap without synchronization. The race detector flags it on any concurrent monitor +GetTargetsworkload — e.g. the reconnect path, where the status reporter snapshots targets while their monitor goroutines are updating status.Fix
Targetsync.Mutexguarding the mutable status fields.snapshot()taken under that lock, copying only the reported fields (Config,Status,LastCheck,LastError,CheckCount). Runtime-only fields (timer/ctx/cancel/client) are intentionally omitted — callers ofGetTargetsonly read the reported fields, and this also avoids copying async.Mutex.DisableTarget'sStatuswrite is guarded too.Test
Adds
healthcheck_test.gowith a regression test that exercises concurrent monitoring + snapshotting. It fails under-racewithout the fix and passes with it:go build,go vet ./healthcheck/, andgofmtare clean.No functional/behavioral change to health checking — this is purely a concurrency-safety fix.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.