outlet/clickhouse: ensure we don't cancel flushing when we don't need
Some checks failed
CI / 🤖 Check dependabot status (push) Has been cancelled
CI / 🐧 Test on Linux (${{ github.ref_type == 'tag' }}, misc) (push) Has been cancelled
CI / 🐧 Test on Linux (coverage) (push) Has been cancelled
CI / 🐧 Test on Linux (regular) (push) Has been cancelled
CI / ❄️ Build on Nix (push) Has been cancelled
CI / 🍏 Build and test on macOS (push) Has been cancelled
CI / 🧪 End-to-end testing (push) Has been cancelled
CI / 🔍 Upload code coverage (push) Has been cancelled
CI / 🔬 Test only Go (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 20) (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 22) (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 24) (push) Has been cancelled
CI / ⚖️ Check licenses (push) Has been cancelled
CI / 🐋 Build Docker images (push) Has been cancelled
CI / 🐋 Tag Docker images (push) Has been cancelled
CI / 🚀 Publish release (push) Has been cancelled

We really want to use max(current deadline, grace period timeout), but
this is not easy with contexts. So, we spawn a goroutine for that. We
need some extra care to ensure it does not leak. Maybe it would be
easier to just use `context.Background()`?
This commit is contained in:
Vincent Bernat
2025-11-10 17:03:32 +01:00
parent e8ad5411ac
commit b6bb6e4af1

View File

@@ -136,9 +136,32 @@ func (w *realWorker) Flush(ctx context.Context) {
return err
}
// Don't use the parent context, it may be too short.
chCtx, cancel := context.WithTimeout(context.Background(), w.c.config.GracePeriod)
defer cancel()
// Ensure the context lives for at least GracePeriod.
chCtx, cancel := context.WithCancel(context.Background())
defer cancel() // needed in case the operation completes before grace period and parent context
go func() {
gracePeriodTimer := time.NewTimer(w.c.config.GracePeriod)
defer gracePeriodTimer.Stop()
select {
case <-gracePeriodTimer.C:
// Grace period elapsed, now wait for parent or end of operation.
select {
case <-ctx.Done():
case <-chCtx.Done():
}
case <-ctx.Done():
// Parent done before grace period, wait for grace period or end of operation.
select {
case <-gracePeriodTimer.C:
w.logger.Info().Msg("grace period to flush batch expired")
case <-chCtx.Done():
}
case <-chCtx.Done():
// Operation done!
}
cancel()
}()
// Send to ClickHouse in flows_XXXXX_raw.
start := time.Now()