Skip to content

Commit c595c0f

Browse files
committed
Add hedged request to Store Gateway
Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
1 parent 020cc45 commit c595c0f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2165
-28
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* [FEATURE] Store Gateway: Add an in-memory chunk cache. #6245
1717
* [FEATURE] Chunk Cache: Support multi level cache and add metrics. #6249
1818
* [FEATURE] Distributor: Accept multiple HA Tracker pairs in the same request. #6256
19+
* [ENHANCEMENT] Store Gateway: Add a hedged request to reduce the tail latency. #6388
1920
* [ENHANCEMENT] Ingester: Add metrics to track succeed/failed native histograms. #6370
2021
* [ENHANCEMENT] Query Frontend/Querier: Add an experimental flag `-querier.enable-promql-experimental-functions` to enable experimental promQL functions. #6355
2122
* [ENHANCEMENT] OTLP: Add `-distributor.otlp-max-recv-msg-size` flag to limit OTLP request size in bytes. #6333

docs/blocks-storage/store-gateway.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,23 @@ store_gateway:
344344
# tenant(s) for processing will ignore them instead.
345345
# CLI flag: -store-gateway.disabled-tenants
346346
[disabled_tenants: <string> | default = ""]
347+
348+
hedged_request:
349+
# If true, hedged requests are applied to object store calls. It can help
350+
# with reducing tail latency.
351+
# CLI flag: -store-gateway.hedged-request.enabled
352+
[enabled: <boolean> | default = false]
353+
354+
# Maximum number of hedged requests allowed for each initial request. A high
355+
# number can reduce latency but increase internal calls.
356+
# CLI flag: -store-gateway.hedged-request.max-requests
357+
[max_requests: <int> | default = 3]
358+
359+
# It is used to calculate a latency threshold to trigger hedged requests.
360+
# For example, additional requests are triggered when the initial request
361+
# response time exceeds the 90th percentile.
362+
# CLI flag: -store-gateway.hedged-request.quantile
363+
[quantile: <float> | default = 0.9]
347364
```
348365
349366
### `blocks_storage_config`

docs/configuration/config-file-reference.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5661,6 +5661,23 @@ sharding_ring:
56615661
# tenant(s) for processing will ignore them instead.
56625662
# CLI flag: -store-gateway.disabled-tenants
56635663
[disabled_tenants: <string> | default = ""]
5664+
5665+
hedged_request:
5666+
# If true, hedged requests are applied to object store calls. It can help with
5667+
# reducing tail latency.
5668+
# CLI flag: -store-gateway.hedged-request.enabled
5669+
[enabled: <boolean> | default = false]
5670+
5671+
# Maximum number of hedged requests allowed for each initial request. A high
5672+
# number can reduce latency but increase internal calls.
5673+
# CLI flag: -store-gateway.hedged-request.max-requests
5674+
[max_requests: <int> | default = 3]
5675+
5676+
# It is used to calculate a latency threshold to trigger hedged requests. For
5677+
# example, additional requests are triggered when the initial request response
5678+
# time exceeds the 90th percentile.
5679+
# CLI flag: -store-gateway.hedged-request.quantile
5680+
[quantile: <float> | default = 0.9]
56645681
```
56655682

56665683
### `tracing_config`

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ require (
116116
github.com/benbjohnson/clock v1.3.5 // indirect
117117
github.com/beorn7/perks v1.0.1 // indirect
118118
github.com/blang/semver/v4 v4.0.0 // indirect
119+
github.com/caio/go-tdigest v3.1.0+incompatible // indirect
119120
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
120121
github.com/coreos/go-semver v0.3.0 // indirect
121122
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
123+
github.com/cristalhq/hedgedhttp v0.9.1 // indirect
122124
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
123125
github.com/dennwc/varint v1.0.0 // indirect
124126
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,8 @@ github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl
897897
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
898898
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
899899
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
900+
github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds=
901+
github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI=
900902
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
901903
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
902904
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -942,6 +944,8 @@ github.com/cortexproject/promqlsmith v0.0.0-20241121054008-8b48fe2471ef/go.mod h
942944
github.com/cortexproject/weaveworks-common v0.0.0-20241129212437-96019edf21f1 h1:UoSixdl0sBUhfEOMpIGxFnJjp3/y/+nkw6Du7su05FE=
943945
github.com/cortexproject/weaveworks-common v0.0.0-20241129212437-96019edf21f1/go.mod h1:7cl8fS/nivXe2DmBUUmr/3UGTJG2jVU2NRaIayR2Zjs=
944946
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
947+
github.com/cristalhq/hedgedhttp v0.9.1 h1:g68L9cf8uUyQKQJwciD0A1Vgbsz+QgCjuB1I8FAsCDs=
948+
github.com/cristalhq/hedgedhttp v0.9.1/go.mod h1:XkqWU6qVMutbhW68NnzjWrGtH8NUx1UfYqGYtHVKIsI=
945949
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
946950
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
947951
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -1390,6 +1394,8 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6Fm
13901394
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
13911395
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
13921396
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
1397+
github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353 h1:X/79QL0b4YJVO5+OsPH9rF2u428CIrGL/jLmPsoOQQ4=
1398+
github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353/go.mod h1:N0SVk0uhy+E1PZ3C9ctsPRlvOPAFPkCNlcPBDkt0N3U=
13931399
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
13941400
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
13951401
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=

integration/e2ecortex/storage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type S3Client struct {
2121
}
2222

2323
func NewS3Client(cfg s3.Config) (*S3Client, error) {
24-
writer, err := s3.NewBucketClient(cfg, "test", log.NewNopLogger())
24+
writer, err := s3.NewBucketClient(cfg, nil, "test", log.NewNopLogger())
2525
if err != nil {
2626
return nil, err
2727
}

pkg/alertmanager/alertstore/store.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func NewAlertStore(ctx context.Context, cfg Config, cfgProvider bucket.TenantCon
6262
return local.NewStore(cfg.Local)
6363
}
6464

65-
bucketClient, err := bucket.NewClient(ctx, cfg.Config, "alertmanager-storage", logger, reg)
65+
bucketClient, err := bucket.NewClient(ctx, cfg.Config, nil, "alertmanager-storage", logger, reg)
6666
if err != nil {
6767
return nil, err
6868
}

pkg/compactor/compactor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ type Compactor struct {
384384
// NewCompactor makes a new Compactor.
385385
func NewCompactor(compactorCfg Config, storageCfg cortex_tsdb.BlocksStorageConfig, logger log.Logger, registerer prometheus.Registerer, limits *validation.Overrides) (*Compactor, error) {
386386
bucketClientFactory := func(ctx context.Context) (objstore.InstrumentedBucket, error) {
387-
return bucket.NewClient(ctx, storageCfg.Bucket, "compactor", logger, registerer)
387+
return bucket.NewClient(ctx, storageCfg.Bucket, nil, "compactor", logger, registerer)
388388
}
389389

390390
blocksGrouperFactory := compactorCfg.BlocksGrouperFactory

pkg/cortex/modules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func (t *Cortex) initRuntimeConfig() (services.Service, error) {
176176
}
177177
}
178178
}
179-
return bucket.NewClient(ctx, t.Cfg.RuntimeConfig.StorageConfig, "runtime-config", logger, registerer)
179+
return bucket.NewClient(ctx, t.Cfg.RuntimeConfig.StorageConfig, nil, "runtime-config", logger, registerer)
180180
}
181181
serv, err := runtimeconfig.New(t.Cfg.RuntimeConfig, registerer, logger, bucketClientFactory)
182182
if err == nil {

pkg/ingester/ingester.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ func New(cfg Config, limits *validation.Overrides, registerer prometheus.Registe
693693
cfg.ingesterClientFactory = client.MakeIngesterClient
694694
}
695695

696-
bucketClient, err := bucket.NewClient(context.Background(), cfg.BlocksStorageConfig.Bucket, "ingester", logger, registerer)
696+
bucketClient, err := bucket.NewClient(context.Background(), cfg.BlocksStorageConfig.Bucket, nil, "ingester", logger, registerer)
697697
if err != nil {
698698
return nil, errors.Wrap(err, "failed to create the bucket client")
699699
}
@@ -769,7 +769,7 @@ func New(cfg Config, limits *validation.Overrides, registerer prometheus.Registe
769769
// this is a special version of ingester used by Flusher. This ingester is not ingesting anything, its only purpose is to react
770770
// on Flush method and flush all opened TSDBs when called.
771771
func NewForFlusher(cfg Config, limits *validation.Overrides, registerer prometheus.Registerer, logger log.Logger) (*Ingester, error) {
772-
bucketClient, err := bucket.NewClient(context.Background(), cfg.BlocksStorageConfig.Bucket, "ingester", logger, registerer)
772+
bucketClient, err := bucket.NewClient(context.Background(), cfg.BlocksStorageConfig.Bucket, nil, "ingester", logger, registerer)
773773
if err != nil {
774774
return nil, errors.Wrap(err, "failed to create the bucket client")
775775
}

pkg/purger/tenant_deletion_api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func (api *TenantDeletionAPI) isBlocksForUserDeleted(ctx context.Context, userID
119119
}
120120

121121
func createBucketClient(cfg cortex_tsdb.BlocksStorageConfig, logger log.Logger, reg prometheus.Registerer) (objstore.InstrumentedBucket, error) {
122-
bucketClient, err := bucket.NewClient(context.Background(), cfg.Bucket, "purger", logger, reg)
122+
bucketClient, err := bucket.NewClient(context.Background(), cfg.Bucket, nil, "purger", logger, reg)
123123
if err != nil {
124124
return nil, errors.Wrap(err, "create bucket client")
125125
}

pkg/querier/blocks_store_queryable.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func NewBlocksStoreQueryable(
185185
func NewBlocksStoreQueryableFromConfig(querierCfg Config, gatewayCfg storegateway.Config, storageCfg cortex_tsdb.BlocksStorageConfig, limits BlocksStoreLimits, logger log.Logger, reg prometheus.Registerer) (*BlocksStoreQueryable, error) {
186186
var stores BlocksStoreSet
187187

188-
bucketClient, err := bucket.NewClient(context.Background(), storageCfg.Bucket, "querier", logger, reg)
188+
bucketClient, err := bucket.NewClient(context.Background(), storageCfg.Bucket, gatewayCfg.HedgedRequest.GetHedgedRoundTripper(), "querier", logger, reg)
189189
if err != nil {
190190
return nil, errors.Wrap(err, "failed to create bucket client")
191191
}

pkg/ruler/storage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func NewRuleStore(ctx context.Context, cfg rulestore.Config, cfgProvider bucket.
3131
return local.NewLocalRulesClient(cfg.Local, loader)
3232
}
3333

34-
bucketClient, err := bucket.NewClient(ctx, cfg.Config, "ruler-storage", logger, reg)
34+
bucketClient, err := bucket.NewClient(ctx, cfg.Config, nil, "ruler-storage", logger, reg)
3535
if err != nil {
3636
return nil, err
3737
}

pkg/storage/bucket/azure/bucket_client.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package azure
22

33
import (
4+
"net/http"
5+
46
"github.com/go-kit/log"
57
"github.com/prometheus/common/model"
68
"github.com/thanos-io/objstore"
@@ -9,7 +11,7 @@ import (
911
yaml "gopkg.in/yaml.v2"
1012
)
1113

12-
func NewBucketClient(cfg Config, name string, logger log.Logger) (objstore.Bucket, error) {
14+
func NewBucketClient(cfg Config, hedgedRoundTripper func(rt http.RoundTripper) http.RoundTripper, name string, logger log.Logger) (objstore.Bucket, error) {
1315
bucketConfig := azure.Config{
1416
StorageAccountName: cfg.StorageAccountName,
1517
StorageAccountKey: cfg.StorageAccountKey.Value,
@@ -37,5 +39,5 @@ func NewBucketClient(cfg Config, name string, logger log.Logger) (objstore.Bucke
3739
return nil, err
3840
}
3941

40-
return azure.NewBucket(logger, serialized, name, nil)
42+
return azure.NewBucket(logger, serialized, name, hedgedRoundTripper)
4143
}

pkg/storage/bucket/client.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"flag"
77
"fmt"
8+
"net/http"
89
"strings"
910

1011
"github.com/go-kit/log"
@@ -103,17 +104,17 @@ func (cfg *Config) Validate() error {
103104
}
104105

105106
// NewClient creates a new bucket client based on the configured backend
106-
func NewClient(ctx context.Context, cfg Config, name string, logger log.Logger, reg prometheus.Registerer) (bucket objstore.InstrumentedBucket, err error) {
107+
func NewClient(ctx context.Context, cfg Config, hedgedRoundTripper func(rt http.RoundTripper) http.RoundTripper, name string, logger log.Logger, reg prometheus.Registerer) (bucket objstore.InstrumentedBucket, err error) {
107108
var client objstore.Bucket
108109
switch cfg.Backend {
109110
case S3:
110-
client, err = s3.NewBucketClient(cfg.S3, name, logger)
111+
client, err = s3.NewBucketClient(cfg.S3, hedgedRoundTripper, name, logger)
111112
case GCS:
112-
client, err = gcs.NewBucketClient(ctx, cfg.GCS, name, logger)
113+
client, err = gcs.NewBucketClient(ctx, cfg.GCS, hedgedRoundTripper, name, logger)
113114
case Azure:
114-
client, err = azure.NewBucketClient(cfg.Azure, name, logger)
115+
client, err = azure.NewBucketClient(cfg.Azure, hedgedRoundTripper, name, logger)
115116
case Swift:
116-
client, err = swift.NewBucketClient(cfg.Swift, name, logger)
117+
client, err = swift.NewBucketClient(cfg.Swift, hedgedRoundTripper, name, logger)
117118
case Filesystem:
118119
client, err = filesystem.NewBucketClient(cfg.Filesystem)
119120
default:

pkg/storage/bucket/client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func TestNewClient(t *testing.T) {
8787
require.NoError(t, err)
8888

8989
// Instance a new bucket client from the config
90-
bucketClient, err := NewClient(context.Background(), cfg, "test", util_log.Logger, nil)
90+
bucketClient, err := NewClient(context.Background(), cfg, nil, "test", util_log.Logger, nil)
9191
require.Equal(t, testData.expectedErr, err)
9292

9393
if testData.expectedErr == nil {

pkg/storage/bucket/gcs/bucket_client.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gcs
22

33
import (
44
"context"
5+
"net/http"
56

67
"github.com/go-kit/log"
78
"github.com/thanos-io/objstore"
@@ -10,7 +11,7 @@ import (
1011
)
1112

1213
// NewBucketClient creates a new GCS bucket client
13-
func NewBucketClient(ctx context.Context, cfg Config, name string, logger log.Logger) (objstore.Bucket, error) {
14+
func NewBucketClient(ctx context.Context, cfg Config, hedgedRoundTripper func(rt http.RoundTripper) http.RoundTripper, name string, logger log.Logger) (objstore.Bucket, error) {
1415
bucketConfig := gcs.Config{
1516
Bucket: cfg.BucketName,
1617
ServiceAccount: cfg.ServiceAccount.Value,
@@ -23,5 +24,5 @@ func NewBucketClient(ctx context.Context, cfg Config, name string, logger log.Lo
2324
return nil, err
2425
}
2526

26-
return gcs.NewBucket(ctx, logger, serialized, name, nil)
27+
return gcs.NewBucket(ctx, logger, serialized, name, hedgedRoundTripper)
2728
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package bucket
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestHedgedRequest_Validate(t *testing.T) {
10+
t.Parallel()
11+
tests := map[string]struct {
12+
cfg *HedgedRequestConfig
13+
expected error
14+
}{
15+
"should fail if hedged request quantile is less than 0": {
16+
cfg: &HedgedRequestConfig{
17+
Quantile: -0.1,
18+
},
19+
expected: errInvalidQuantile,
20+
},
21+
"should fail if hedged request quantile is more than 1": {
22+
cfg: &HedgedRequestConfig{
23+
Quantile: 1.1,
24+
},
25+
expected: errInvalidQuantile,
26+
},
27+
}
28+
29+
for testName, testData := range tests {
30+
t.Run(testName, func(t *testing.T) {
31+
err := testData.cfg.Validate()
32+
require.Equal(t, testData.expected, err)
33+
})
34+
}
35+
36+
}

pkg/storage/bucket/hedged_request.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package bucket
2+
3+
import (
4+
"errors"
5+
"flag"
6+
"net/http"
7+
8+
"github.com/thanos-io/thanos/pkg/exthttp"
9+
)
10+
11+
var (
12+
errInvalidQuantile = errors.New("invalid hedged request quantile, it must be between 0 and 1")
13+
)
14+
15+
type HedgedRequestConfig struct {
16+
Enabled bool `yaml:"enabled"`
17+
MaxRequests uint `yaml:"max_requests"`
18+
Quantile float64 `yaml:"quantile"`
19+
}
20+
21+
func (cfg *HedgedRequestConfig) RegisterFlagsWithPrefix(f *flag.FlagSet, prefix string) {
22+
f.BoolVar(&cfg.Enabled, prefix+"hedged-request.enabled", false, "If true, hedged requests are applied to object store calls. It can help with reducing tail latency.")
23+
f.UintVar(&cfg.MaxRequests, prefix+"hedged-request.max-requests", 3, "Maximum number of hedged requests allowed for each initial request. A high number can reduce latency but increase internal calls.")
24+
f.Float64Var(&cfg.Quantile, prefix+"hedged-request.quantile", 0.9, "It is used to calculate a latency threshold to trigger hedged requests. For example, additional requests are triggered when the initial request response time exceeds the 90th percentile.")
25+
}
26+
27+
func (cfg *HedgedRequestConfig) GetHedgedRoundTripper() func(rt http.RoundTripper) http.RoundTripper {
28+
return exthttp.CreateHedgedTransportWithConfig(exthttp.CustomBucketConfig{
29+
HedgingConfig: exthttp.HedgingConfig{
30+
Enabled: cfg.Enabled,
31+
UpTo: cfg.MaxRequests,
32+
Quantile: cfg.Quantile,
33+
},
34+
})
35+
}
36+
37+
func (cfg *HedgedRequestConfig) Validate() error {
38+
if cfg.Quantile > 1 || cfg.Quantile < 0 {
39+
return errInvalidQuantile
40+
}
41+
42+
return nil
43+
}

pkg/storage/bucket/s3/bucket_client.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"io"
7+
"net/http"
78
"time"
89

910
"github.com/go-kit/log"
@@ -21,13 +22,13 @@ var defaultRetryMinBackoff = 5 * time.Second
2122
var defaultRetryMaxBackoff = 1 * time.Minute
2223

2324
// NewBucketClient creates a new S3 bucket client
24-
func NewBucketClient(cfg Config, name string, logger log.Logger) (objstore.Bucket, error) {
25+
func NewBucketClient(cfg Config, hedgedRoundTripper func(rt http.RoundTripper) http.RoundTripper, name string, logger log.Logger) (objstore.Bucket, error) {
2526
s3Cfg, err := newS3Config(cfg)
2627
if err != nil {
2728
return nil, err
2829
}
2930

30-
bucket, err := s3.NewBucketWithConfig(logger, s3Cfg, name, nil)
31+
bucket, err := s3.NewBucketWithConfig(logger, s3Cfg, name, hedgedRoundTripper)
3132
if err != nil {
3233
return nil, err
3334
}

pkg/storage/bucket/sse_bucket_client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func TestSSEBucketClient_Upload_ShouldInjectCustomSSEConfig(t *testing.T) {
5757
BucketLookupType: s3.BucketPathLookup,
5858
}
5959

60-
s3Client, err := s3.NewBucketClient(s3Cfg, "test", log.NewNopLogger())
60+
s3Client, err := s3.NewBucketClient(s3Cfg, nil, "test", log.NewNopLogger())
6161
require.NoError(t, err)
6262

6363
// Configure the config provider with NO KMS key ID.

0 commit comments

Comments
 (0)