From b2261dc15bf6cc7857e9ff7b182bdcc2de57f357 Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Tue, 2 Dec 2025 15:05:16 -0500 Subject: [PATCH] avoid data race when writing task states In #31 we fixed a panic when adding a task event, but the fix was incomplete and just panicked again later under heavy concurrent use. This PR fixes the follow-up panic but also fixes a data race that popped up when testing the fix with a build that used `-race`. --- allocrunnersim/allocrunnersim.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/allocrunnersim/allocrunnersim.go b/allocrunnersim/allocrunnersim.go index d4b48e0..44bcf4e 100644 --- a/allocrunnersim/allocrunnersim.go +++ b/allocrunnersim/allocrunnersim.go @@ -15,6 +15,7 @@ import ( cinterfaces "github.com/hashicorp/nomad/client/interfaces" "github.com/hashicorp/nomad/client/pluginmanager/drivermanager" cstructs "github.com/hashicorp/nomad/client/structs" + "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/helper/pointer" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/device" @@ -160,7 +161,6 @@ func (ar *simulatedAllocRunner) Run() { } event.PopulateEventDisplayMessage() taskStates[task.Name].Events = append(taskStates[task.Name].Events, event) - taskStates[task.Name].StartedAt = time.Now() taskStates[task.Name].State = structs.TaskStateRunning } @@ -213,6 +213,7 @@ func (ar *simulatedAllocRunner) clientAlloc(taskStates map[string]*structs.TaskS defer ar.allocStateLock.Unlock() // store task states for AllocState to expose + taskStates = helper.DeepCopyMap(taskStates) ar.allocState.TaskStates = taskStates a := &structs.Allocation{ @@ -345,7 +346,7 @@ func (ar *simulatedAllocRunner) stopAll() { // Ensure we have a current copy of the task states, so that we append and // create a correct and full list. ar.allocStateLock.RLock() - taskStates := ar.allocState.TaskStates + taskStates := helper.DeepCopyMap(ar.allocState.TaskStates) ar.allocStateLock.RUnlock() // Perform the task kill, which essentially is the shutdown notification. @@ -375,11 +376,8 @@ func (ar *simulatedAllocRunner) stopAll() { } event.PopulateEventDisplayMessage() taskStates[task.Name].Events = append(taskStates[task.Name].Events, event) - - ar.allocStateLock.Lock() - ar.allocState.TaskStates[task.Name].FinishedAt = time.Now() - ar.allocState.TaskStates[task.Name].State = structs.TaskStateDead - ar.allocStateLock.Unlock() + taskStates[task.Name].FinishedAt = time.Now() + taskStates[task.Name].State = structs.TaskStateDead } ar.updateAllocAndSendUpdate(taskStates)