mirror of
https://github.com/coder/coder.git
synced 2026-09-22 21:22:17 +08:00
Using `WaitGroup.Go` must be synchronized with `WaitGroup.Wait` according to [go docs](https://pkg.go.dev/sync#WaitGroup.Go): > If the WaitGroup is empty, Go must happen before a [WaitGroup.Wait](https://pkg.go.dev/sync#WaitGroup.Wait). There were a couple of places in chatd that violated this principle. This was caught as a data race in https://github.com/coder/internal/issues/1599. This PR ensures that all functions that spawn inflight goroutines synchronize with each other. I also noticed that inflight goroutines may be spawned after the server is closed, which was surprising and looked like a bug. This PR therefore also introduces a mechanism that disallows spawning inflight goroutines after the server is closed, and ensures that any code that tries doing it logs an error. Closes https://github.com/coder/internal/issues/1599.
20 lines
577 B
Go
20 lines
577 B
Go
package chatd
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// WaitUntilIdleForTest waits for background chat work tracked by the server to
|
|
// finish without shutting the server down. Tests use this to assert final
|
|
// database state only after asynchronous chat processing has completed.
|
|
// Close waits for the same tracked work, but also stops the server.
|
|
func WaitUntilIdleForTest(server *Server) {
|
|
if server.chatWorker != nil {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
_ = server.chatWorker.WaitIdle(ctx)
|
|
}
|
|
server.drainInflight()
|
|
}
|