When the events channel passed to IngestChannel is closed (e.g., on adapter shutdown via Close()), IngestChannel enters this branch at axiom/datasets.go:687 (post-#425 line numbers):
case event, ok := <-events:
if !ok {
// Channel is closed.
err := flush()
return &ingestStatus, spanError(span, err)
}
It performs a single final flush and returns, regardless of whether the flush succeeded. If the final flush fails transiently (network error, server 5xx, anything), the in-flight batch is lost with no retry, no log, and no metric.
#425 added a 3-strike retry budget to the main-loop flush paths but deliberately did not touch this shutdown path. It should get the same treatment, or at minimum emit a drop log with the abandoned batch size.
Proposal
Option A: apply the same maxConsecutiveErrors budget to the shutdown flush before giving up.
Option B: accept that shutdown is best-effort but emit a drop log with len(batch) so users can observe the loss.
Option A is more correct. Option B is simpler. Option A is probably the right call, since shutdown is the exact moment where "we have events in memory, please try hard to deliver them" matters most.
Impact
Small but real data-loss window on graceful shutdown. More noticeable in short-lived processes (serverless functions, cron jobs, CLIs) that rely on Close() being called at the end of their lifecycle to flush buffered logs.
Related: #425.
When the events channel passed to
IngestChannelis closed (e.g., on adapter shutdown viaClose()),IngestChannelenters this branch ataxiom/datasets.go:687(post-#425 line numbers):It performs a single final flush and returns, regardless of whether the flush succeeded. If the final flush fails transiently (network error, server 5xx, anything), the in-flight batch is lost with no retry, no log, and no metric.
#425 added a 3-strike retry budget to the main-loop flush paths but deliberately did not touch this shutdown path. It should get the same treatment, or at minimum emit a drop log with the abandoned batch size.
Proposal
Option A: apply the same
maxConsecutiveErrorsbudget to the shutdown flush before giving up.Option B: accept that shutdown is best-effort but emit a drop log with
len(batch)so users can observe the loss.Option A is more correct. Option B is simpler. Option A is probably the right call, since shutdown is the exact moment where "we have events in memory, please try hard to deliver them" matters most.
Impact
Small but real data-loss window on graceful shutdown. More noticeable in short-lived processes (serverless functions, cron jobs, CLIs) that rely on
Close()being called at the end of their lifecycle to flush buffered logs.Related: #425.