From 1baf0d48d8139f67aedc431f053297eee21ae0af Mon Sep 17 00:00:00 2001 From: pipiland2612 Date: Fri, 17 Oct 2025 11:21:35 +0300 Subject: [PATCH 1/2] public_backoff_config Signed-off-by: pipiland2612 --- exp/api/remote/remote_api.go | 23 +++++++++++++++++------ exp/api/remote/remote_api_test.go | 5 ++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/exp/api/remote/remote_api.go b/exp/api/remote/remote_api.go index abe533db1..509ae2d5a 100644 --- a/exp/api/remote/remote_api.go +++ b/exp/api/remote/remote_api.go @@ -35,6 +35,13 @@ import ( "github.com/prometheus/client_golang/exp/internal/github.com/efficientgo/core/backoff" ) +// BackoffConfig configures exponential backoff with jitter for retry operations. +type BackoffConfig struct { + Min time.Duration `yaml:"min_period"` // Start backoff at this level + Max time.Duration `yaml:"max_period"` // Increase exponentially to this level + MaxRetries int `yaml:"max_retries"` // Give up after this many; zero means infinite retries +} + // API is a client for Prometheus Remote Protocols. // NOTE(bwplotka): Only https://prometheus.io/docs/specs/remote_write_spec_2_0/ is currently implemented, // read protocols to be implemented if there will be a demand. @@ -56,14 +63,14 @@ type RetryCallback func(err error) type apiOpts struct { logger *slog.Logger client *http.Client - backoff backoff.Config + backoffConfig BackoffConfig compression Compression path string retryOnRateLimit bool } var defaultAPIOpts = &apiOpts{ - backoff: backoff.Config{ + backoffConfig: BackoffConfig{ Min: 1 * time.Second, Max: 10 * time.Second, MaxRetries: 10, @@ -107,10 +114,10 @@ func WithAPINoRetryOnRateLimit() APIOption { } } -// WithAPIBackoff returns APIOption that allows overriding backoff configuration. -func WithAPIBackoff(backoff backoff.Config) APIOption { +// WithAPIBackoffConfig returns APIOption that allows overriding backoff configuration. +func WithAPIBackoffConfig(cfg BackoffConfig) APIOption { return func(o *apiOpts) error { - o.backoff = backoff + o.backoffConfig = cfg return nil } } @@ -259,7 +266,11 @@ func (r *API) Write(ctx context.Context, msgType WriteMessageType, msg any, opts // across the various attempts. accumulatedStats := WriteResponseStats{} - b := backoff.New(ctx, r.opts.backoff) + b := backoff.New(ctx, backoff.Config{ + Min: r.opts.backoffConfig.Min, + Max: r.opts.backoffConfig.Max, + MaxRetries: r.opts.backoffConfig.MaxRetries, + }) for { rs, err := r.attemptWrite(ctx, r.opts.compression, msgType, payload, b.NumRetries()) accumulatedStats.Add(rs) diff --git a/exp/api/remote/remote_api_test.go b/exp/api/remote/remote_api_test.go index f39913308..ec7289fa5 100644 --- a/exp/api/remote/remote_api_test.go +++ b/exp/api/remote/remote_api_test.go @@ -31,7 +31,6 @@ import ( "google.golang.org/protobuf/testing/protocmp" writev2 "github.com/prometheus/client_golang/exp/api/remote/genproto/v2" - "github.com/prometheus/client_golang/exp/internal/github.com/efficientgo/core/backoff" ) func TestRetryAfterDuration(t *testing.T) { @@ -189,7 +188,7 @@ func TestRemoteAPI_Write_WithHandler(t *testing.T) { WithAPIHTTPClient(srv.Client()), WithAPILogger(tLogger), WithAPIPath("api/v1/write"), - WithAPIBackoff(backoff.Config{ + WithAPIBackoffConfig(BackoffConfig{ Min: 1 * time.Second, Max: 1 * time.Second, MaxRetries: 2, @@ -226,7 +225,7 @@ func TestRemoteAPI_Write_WithHandler(t *testing.T) { WithAPIHTTPClient(srv.Client()), WithAPILogger(tLogger), WithAPIPath("api/v1/write"), - WithAPIBackoff(backoff.Config{ + WithAPIBackoffConfig(BackoffConfig{ Min: 1 * time.Millisecond, Max: 1 * time.Millisecond, MaxRetries: 3, From 68ea185eaeae89ed085cd2f11a886c3b22b7e01b Mon Sep 17 00:00:00 2001 From: pipiland2612 Date: Fri, 17 Oct 2025 14:50:56 +0300 Subject: [PATCH 2/2] nit_fixing Signed-off-by: pipiland2612 --- exp/api/remote/remote_api.go | 5 +++-- exp/api/remote/remote_api_test.go | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/exp/api/remote/remote_api.go b/exp/api/remote/remote_api.go index 509ae2d5a..10996b03d 100644 --- a/exp/api/remote/remote_api.go +++ b/exp/api/remote/remote_api.go @@ -114,8 +114,9 @@ func WithAPINoRetryOnRateLimit() APIOption { } } -// WithAPIBackoffConfig returns APIOption that allows overriding backoff configuration. -func WithAPIBackoffConfig(cfg BackoffConfig) APIOption { +// WithAPIBackoff returns APIOption that allows configuring backoff. +// By default, exponential backoff with jitter is used (see defaultAPIOpts). +func WithAPIBackoff(cfg BackoffConfig) APIOption { return func(o *apiOpts) error { o.backoffConfig = cfg return nil diff --git a/exp/api/remote/remote_api_test.go b/exp/api/remote/remote_api_test.go index ec7289fa5..8445b1ed5 100644 --- a/exp/api/remote/remote_api_test.go +++ b/exp/api/remote/remote_api_test.go @@ -188,7 +188,7 @@ func TestRemoteAPI_Write_WithHandler(t *testing.T) { WithAPIHTTPClient(srv.Client()), WithAPILogger(tLogger), WithAPIPath("api/v1/write"), - WithAPIBackoffConfig(BackoffConfig{ + WithAPIBackoff(BackoffConfig{ Min: 1 * time.Second, Max: 1 * time.Second, MaxRetries: 2, @@ -225,7 +225,7 @@ func TestRemoteAPI_Write_WithHandler(t *testing.T) { WithAPIHTTPClient(srv.Client()), WithAPILogger(tLogger), WithAPIPath("api/v1/write"), - WithAPIBackoffConfig(BackoffConfig{ + WithAPIBackoff(BackoffConfig{ Min: 1 * time.Millisecond, Max: 1 * time.Millisecond, MaxRetries: 3,