From 7256f7b22f2fcca28aeb6f0bc38953d33402e9e8 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Fri, 5 Dec 2025 11:53:09 -0800 Subject: [PATCH] Check ctx prior to delaying retry Fix #7673 Do not rely on non-deterministic `select` statement to catch ended context prior to waiting for a retry delay. Explicitly check the context prior to entering the wait. --- exporters/otlp/otlplog/otlploggrpc/internal/retry/retry.go | 5 +++++ exporters/otlp/otlplog/otlploghttp/internal/retry/retry.go | 5 +++++ .../otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go | 5 +++++ .../otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go | 5 +++++ .../otlp/otlptrace/otlptracegrpc/internal/retry/retry.go | 5 +++++ .../otlp/otlptrace/otlptracehttp/internal/retry/retry.go | 5 +++++ internal/shared/otlp/retry/retry.go.tmpl | 5 +++++ 7 files changed, 35 insertions(+) diff --git a/exporters/otlp/otlplog/otlploggrpc/internal/retry/retry.go b/exporters/otlp/otlplog/otlploggrpc/internal/retry/retry.go index fa59467747f..1a5684d6e87 100644 --- a/exporters/otlp/otlplog/otlploggrpc/internal/retry/retry.go +++ b/exporters/otlp/otlplog/otlploggrpc/internal/retry/retry.go @@ -94,6 +94,11 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { return err } + // Check if context is canceled before attempting to wait and retry. + if ctx.Err() != nil { + return fmt.Errorf("%w: %w", ctx.Err(), err) + } + if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { return fmt.Errorf("max retry time elapsed: %w", err) } diff --git a/exporters/otlp/otlplog/otlploghttp/internal/retry/retry.go b/exporters/otlp/otlplog/otlploghttp/internal/retry/retry.go index a0a9dc1334a..46e545bee4b 100644 --- a/exporters/otlp/otlplog/otlploghttp/internal/retry/retry.go +++ b/exporters/otlp/otlplog/otlploghttp/internal/retry/retry.go @@ -94,6 +94,11 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { return err } + // Check if context is canceled before attempting to wait and retry. + if ctx.Err() != nil { + return fmt.Errorf("%w: %w", ctx.Err(), err) + } + if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { return fmt.Errorf("max retry time elapsed: %w", err) } diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go index 80691ac3a9f..c14e5ae78a0 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go @@ -94,6 +94,11 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { return err } + // Check if context is canceled before attempting to wait and retry. + if ctx.Err() != nil { + return fmt.Errorf("%w: %w", ctx.Err(), err) + } + if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { return fmt.Errorf("max retry time elapsed: %w", err) } diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go index 8a5fa80eac6..b4b5c013d4c 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go @@ -94,6 +94,11 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { return err } + // Check if context is canceled before attempting to wait and retry. + if ctx.Err() != nil { + return fmt.Errorf("%w: %w", ctx.Err(), err) + } + if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { return fmt.Errorf("max retry time elapsed: %w", err) } diff --git a/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go b/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go index 259a898ae77..a7b8e81a786 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go +++ b/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go @@ -94,6 +94,11 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { return err } + // Check if context is canceled before attempting to wait and retry. + if ctx.Err() != nil { + return fmt.Errorf("%w: %w", ctx.Err(), err) + } + if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { return fmt.Errorf("max retry time elapsed: %w", err) } diff --git a/exporters/otlp/otlptrace/otlptracehttp/internal/retry/retry.go b/exporters/otlp/otlptrace/otlptracehttp/internal/retry/retry.go index 107428fa6cf..bf39808254f 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/internal/retry/retry.go +++ b/exporters/otlp/otlptrace/otlptracehttp/internal/retry/retry.go @@ -94,6 +94,11 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { return err } + // Check if context is canceled before attempting to wait and retry. + if ctx.Err() != nil { + return fmt.Errorf("%w: %w", ctx.Err(), err) + } + if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { return fmt.Errorf("max retry time elapsed: %w", err) } diff --git a/internal/shared/otlp/retry/retry.go.tmpl b/internal/shared/otlp/retry/retry.go.tmpl index fa59467747f..1a5684d6e87 100644 --- a/internal/shared/otlp/retry/retry.go.tmpl +++ b/internal/shared/otlp/retry/retry.go.tmpl @@ -94,6 +94,11 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { return err } + // Check if context is canceled before attempting to wait and retry. + if ctx.Err() != nil { + return fmt.Errorf("%w: %w", ctx.Err(), err) + } + if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { return fmt.Errorf("max retry time elapsed: %w", err) }