mirror of
https://github.com/ollama/ollama.git
synced 2026-10-21 19:11:17 +00:00
app/updater: drain background update-check goroutine before returning (#17446)
DownloadNewRelease spawned a background checkForUpdate loop that read package-level knobs (UpdateCheckInterval et al.) and returned without waiting for it, so under -race the next test rewrote those globals while the orphaned goroutine was still reading them. waitDownloadIdle (from Cancel and WaitGroup-drain the loop before DownloadNewRelease returns, and have TestCancelOngoingDownload join its download goroutine so the drain is observable before the test exits.
This commit is contained in:
parent
4f9d09ef52
commit
b63eed94b6
2 changed files with 15 additions and 3 deletions
|
|
@ -153,10 +153,12 @@ func (u *Updater) DownloadNewRelease(ctx context.Context, updateResp UpdateRespo
|
|||
return err
|
||||
}
|
||||
|
||||
// In case of slow downloads, continue the update check in the background
|
||||
// In case of slow downloads, continue the update check in the background.
|
||||
// Drain the goroutine before returning: it reads package-level knobs
|
||||
// (e.g. UpdateCheckInterval), which callers may mutate once we return.
|
||||
bgctx, bgcancel := context.WithCancel(downloadCtx)
|
||||
defer bgcancel()
|
||||
go func() {
|
||||
var bgwg sync.WaitGroup
|
||||
bgwg.Go(func() {
|
||||
for {
|
||||
select {
|
||||
case <-bgctx.Done():
|
||||
|
|
@ -165,6 +167,10 @@ func (u *Updater) DownloadNewRelease(ctx context.Context, updateResp UpdateRespo
|
|||
u.checkForUpdate(bgctx)
|
||||
}
|
||||
}
|
||||
})
|
||||
defer func() {
|
||||
bgcancel()
|
||||
bgwg.Wait()
|
||||
}()
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
|
|
|
|||
|
|
@ -577,7 +577,9 @@ func TestCancelOngoingDownload(t *testing.T) {
|
|||
_, resp := updater.checkForUpdate(ctx)
|
||||
|
||||
// Start download in goroutine
|
||||
downloadDone := make(chan struct{})
|
||||
go func() {
|
||||
defer close(downloadDone)
|
||||
_ = updater.DownloadNewRelease(ctx, resp)
|
||||
}()
|
||||
|
||||
|
|
@ -598,6 +600,10 @@ func TestCancelOngoingDownload(t *testing.T) {
|
|||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("download cancellation was not received by server")
|
||||
}
|
||||
|
||||
// Wait for the download goroutine to unwind: it drags along a background
|
||||
// update-check loop that reads package-level knobs the next test rewrites.
|
||||
<-downloadDone
|
||||
}
|
||||
|
||||
func TestTriggerImmediateCheck(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue