Fix race conditions when printing current status of tasks
Created by: mrnugget
This fixes https://github.com/sourcegraph/sourcegraph/issues/16195 by doing two things:
- It threads every update and read of
*TaskStatus
inexecutor
through a mutex to provide a consistent view of all[]*TaskStatus
. While we had async.Map
in place it didn't protect us from race conditions, since we passed around pointers toTaskStatus
freely: theexecutor
goroutines would happily write to a*TaskStatus
and thecampaignProgressPrinter.PrintStatus
would read[]*TaskStatus
while they're being updated. Thesync.Map
was useless in practice. So instead of that, I added a mutex that's used when updating a*TaskStatus
and when reading all[]*TaskStatus
when printing the status. - It uses a 1-capacity semaphore to control access to the
campaignProgressPrinter
through thePrintStatuses
callback: only one execution at a time and if another execution is already in progress it returns.