diff --git a/.drone/drone.jsonnet b/.drone/drone.jsonnet index 25676aacb..664cdbd3b 100644 --- a/.drone/drone.jsonnet +++ b/.drone/drone.jsonnet @@ -1,6 +1,6 @@ local supported_golang_versions = [ - '1.20.10', - '1.21.3', + '1.21.12', + '1.22.5', ]; local images = { diff --git a/.drone/drone.yml b/.drone/drone.yml index 0bee7bc5d..a56ea1e16 100644 --- a/.drone/drone.yml +++ b/.drone/drone.yml @@ -7,7 +7,7 @@ "commands": [ "make mod-check" ], - "image": "golang:1.21.3", + "image": "golang:1.22.5", "name": "make-mod-check" }, { @@ -17,7 +17,7 @@ "depends_on": [ "make-mod-check" ], - "image": "golang:1.21.3", + "image": "golang:1.22.5", "name": "make-lint" }, { @@ -27,8 +27,8 @@ "depends_on": [ "make-lint" ], - "image": "golang:1.20.10", - "name": "make-test (go 1.20.10)" + "image": "golang:1.21.12", + "name": "make-test (go 1.21.12)" }, { "commands": [ @@ -37,8 +37,8 @@ "depends_on": [ "make-lint" ], - "image": "golang:1.21.3", - "name": "make-test (go 1.21.3)" + "image": "golang:1.22.5", + "name": "make-test (go 1.22.5)" }, { "commands": [ @@ -47,8 +47,8 @@ "depends_on": [ "make-lint" ], - "image": "golang:1.21.3", - "name": "make-test-benchmarks (go 1.21.3)" + "image": "golang:1.22.5", + "name": "make-test-benchmarks (go 1.22.5)" }, { "commands": [ @@ -59,13 +59,13 @@ "depends_on": [ "make-mod-check" ], - "image": "golang:1.21.3", + "image": "golang:1.22.5", "name": "make-check-protos" } ] } --- kind: signature -hmac: 2419eded398bf02c5da0040762394904d32600544b660d06378c1e75ec9432c4 +hmac: 4a0bc0860a88f942fc51521193425e8e3c09b4a6731d7b7458212919ce87a12c ... diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 7eb009059..0fc8a348b 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -41,7 +41,8 @@ jobs: matrix: # We want to make sure dskit can support multiple golang versions # by ensuring the test would pass using all these supported versions. - go-version: ['1.20.x', '1.21.x'] + go-version: ['1.21.x', '1.22.x'] + fail-fast: false steps: - uses: actions/checkout@v4 - name: Set up Go ${{ matrix.go-version }} diff --git a/CHANGELOG.md b/CHANGELOG.md index a95dbc37f..5756eeebe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ * [CHANGE] Removed unused `time.Duration` parameter from `ShouldLog()` function in `middleware.OptionalLogging` interface. #513 * [CHANGE] Changed `ShouldLog()` function signature in `middleware.OptionalLogging` interface to `ShouldLog(context.Context) (bool, string)`: the returned `string` contains an optional reason. When reason is valued, `GRPCServerLog` adds `()` suffix to the error. #514 * [CHANGE] Cache: Remove superfluous `cache.RemoteCacheClient` interface and unify all caches using the `cache.Cache` interface. #520 +* [CHANGE] Updated the minimum required Go version to 1.21. #540 * [FEATURE] Cache: Add support for configuring a Redis cache backend. #268 #271 #276 * [FEATURE] Add support for waiting on the rate limiter using the new `WaitN` method. #279 * [FEATURE] Add `log.BufferedLogger` type. #338 @@ -214,6 +215,7 @@ * [ENHANCEMENT] Log Middleware: if the trace is not sampled, log its ID as `trace_id_unsampled` instead of `trace_id`. #529 * [EHNANCEMENT] httpgrpc: httpgrpc Server can now use error message from special HTTP header when converting HTTP response to an error. This is useful when HTTP response body contains binary data that doesn't form valid utf-8 string, otherwise grpc would fail to marshal returned error. #531 * [EHNANCEMENT] Supporting reloading client certificates #549 +* [CHANGE] Backoff: added `Backoff.ErrCause()` which is like `Backoff.Err()` but returns the context cause if backoff is terminated because the context has been canceled. #538 * [BUGFIX] spanlogger: Support multiple tenant IDs. #59 * [BUGFIX] Memberlist: fixed corrupted packets when sending compound messages with more than 255 messages or messages bigger than 64KB. #85 * [BUGFIX] Ring: `ring_member_ownership_percent` and `ring_tokens_owned` metrics are not updated on scale down. #109 @@ -246,3 +248,4 @@ * [BUGFIX] middleware: fix issue where applications that used the httpgrpc tracing middleware would generate duplicate spans for incoming HTTP requests. #451 * [BUGFIX] httpgrpc: store headers in canonical form when converting from gRPC to HTTP. #518 * [BUGFIX] Memcached: Don't truncate sub-second TTLs to 0 which results in them being cached forever. #530 +* [BUGFIX] Cache: initialise the `operation_failures_total{reason="connect-timeout"}` metric to 0 for each cache operation type on startup. #545 diff --git a/backoff/backoff.go b/backoff/backoff.go index 7ce556472..419af80e1 100644 --- a/backoff/backoff.go +++ b/backoff/backoff.go @@ -54,7 +54,7 @@ func (b *Backoff) Ongoing() bool { return b.ctx.Err() == nil && (b.cfg.MaxRetries == 0 || b.numRetries < b.cfg.MaxRetries) } -// Err returns the reason for terminating the backoff, or nil if it didn't terminate +// Err returns the reason for terminating the backoff, or nil if it didn't terminate. func (b *Backoff) Err() error { if b.ctx.Err() != nil { return b.ctx.Err() @@ -65,6 +65,15 @@ func (b *Backoff) Err() error { return nil } +// ErrCause is like Err() but returns the context cause if backoff is terminated because the +// context has been canceled. +func (b *Backoff) ErrCause() error { + if b.ctx.Err() != nil { + return context.Cause(b.ctx) + } + return b.Err() +} + // NumRetries returns the number of retries so far func (b *Backoff) NumRetries() int { return b.numRetries diff --git a/backoff/backoff_test.go b/backoff/backoff_test.go index dff6432c0..586121415 100644 --- a/backoff/backoff_test.go +++ b/backoff/backoff_test.go @@ -4,6 +4,9 @@ import ( "context" "testing" "time" + + "github.com/pkg/errors" + "github.com/stretchr/testify/require" ) func TestBackoff_NextDelay(t *testing.T) { @@ -101,3 +104,68 @@ func TestBackoff_NextDelay(t *testing.T) { }) } } + +func TestBackoff_ErrAndErrCause(t *testing.T) { + cause := errors.New("my cause") + + tests := map[string]struct { + ctx func(*testing.T) context.Context + expectedErr error + expectedErrCause error + }{ + "context deadline exceeded without cause": { + ctx: func(t *testing.T) context.Context { + ctx, cancel := context.WithDeadline(context.Background(), time.Now()) + t.Cleanup(cancel) + + return ctx + }, + expectedErr: context.DeadlineExceeded, + expectedErrCause: context.DeadlineExceeded, + }, + "context deadline exceeded with cause": { + ctx: func(t *testing.T) context.Context { + ctx, cancel := context.WithDeadlineCause(context.Background(), time.Now(), cause) + t.Cleanup(cancel) + + return ctx + }, + expectedErr: context.DeadlineExceeded, + expectedErrCause: cause, + }, + "context is canceled without cause": { + ctx: func(_ *testing.T) context.Context { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + return ctx + }, + expectedErr: context.Canceled, + expectedErrCause: context.Canceled, + }, + "context is canceled with cause": { + ctx: func(_ *testing.T) context.Context { + ctx, cancel := context.WithCancelCause(context.Background()) + cancel(cause) + + return ctx + }, + expectedErr: context.Canceled, + expectedErrCause: cause, + }, + } + + for testName, testData := range tests { + t.Run(testName, func(t *testing.T) { + b := New(testData.ctx(t), Config{}) + + // Wait until the backoff returns error. + require.Eventually(t, func() bool { + return b.Err() != nil + }, time.Second, 10*time.Millisecond) + + require.Equal(t, testData.expectedErr, b.Err()) + require.Equal(t, testData.expectedErrCause, b.ErrCause()) + }) + } +} diff --git a/cache/client.go b/cache/client.go index 855518751..033d2add6 100644 --- a/cache/client.go +++ b/cache/client.go @@ -86,6 +86,7 @@ func newClientMetrics(reg prometheus.Registerer) *clientMetrics { Help: "Total number of operations against cache that failed.", }, []string{"operation", "reason"}) for _, op := range []string{opGetMulti, opSet, opDelete, opIncrement, opFlush, opTouch, opCompareAndSwap} { + cm.failures.WithLabelValues(op, reasonConnectTimeout) cm.failures.WithLabelValues(op, reasonTimeout) cm.failures.WithLabelValues(op, reasonMalformedKey) cm.failures.WithLabelValues(op, reasonServerError) diff --git a/go.mod b/go.mod index 2f4a7d289..1b84ceb98 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/grafana/dskit -go 1.20 +go 1.21 require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 diff --git a/go.sum b/go.sum index 404b5b72a..f06859899 100644 --- a/go.sum +++ b/go.sum @@ -134,6 +134,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= @@ -212,6 +213,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -253,7 +255,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= @@ -307,6 +311,7 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -539,7 +544,9 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/ring/example/local/go.mod b/ring/example/local/go.mod index 42af105fd..f944a8c69 100644 --- a/ring/example/local/go.mod +++ b/ring/example/local/go.mod @@ -1,6 +1,8 @@ module github.com/grafana/dskit/ring/example/local -go 1.20 +go 1.21 + +toolchain go1.22.4 require ( github.com/go-kit/log v0.2.1 diff --git a/ring/example/local/go.sum b/ring/example/local/go.sum index bee208452..8a4e91061 100644 --- a/ring/example/local/go.sum +++ b/ring/example/local/go.sum @@ -31,6 +31,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -105,6 +106,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grafana/memberlist v0.3.1-0.20220714140823-09ffed8adbbe h1:yIXAAbLswn7VNWBIvM71O2QsgfgW9fRXZNR0DXe6pDU= @@ -216,6 +218,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -255,12 +258,14 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber/jaeger-client-go v2.28.0+incompatible h1:G4QSBfvPKvg5ZM2j9MrJFdfI5iSljY/WnJqOGFao6HI= github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= @@ -279,6 +284,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= @@ -335,6 +341,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -443,9 +450,11 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/tenant/resolver.go b/tenant/resolver.go index 35e95b1c8..9a01d6322 100644 --- a/tenant/resolver.go +++ b/tenant/resolver.go @@ -16,7 +16,18 @@ import ( // //nolint:revive func TenantID(ctx context.Context) (string, error) { - orgIDs, err := TenantIDs(ctx) + //lint:ignore faillint wrapper around upstream method + orgID, err := user.ExtractOrgID(ctx) + if err != nil { + return "", err + } + if !strings.Contains(orgID, tenantIDsSeparator) { + if err := ValidTenantID(orgID); err != nil { + return "", err + } + return orgID, nil + } + orgIDs, err := tenantIDsFromString(orgID) if err != nil { return "", err } @@ -42,6 +53,10 @@ func TenantIDs(ctx context.Context) ([]string, error) { return nil, err } + return tenantIDsFromString(orgID) +} + +func tenantIDsFromString(orgID string) ([]string, error) { orgIDs := strings.Split(orgID, tenantIDsSeparator) for _, id := range orgIDs { if err := ValidTenantID(id); err != nil { diff --git a/tenant/tenant_test.go b/tenant/tenant_test.go index bc3a60b54..f0b6b9e15 100644 --- a/tenant/tenant_test.go +++ b/tenant/tenant_test.go @@ -1,9 +1,12 @@ package tenant import ( + "context" "strings" "testing" + "github.com/grafana/dskit/user" + "github.com/stretchr/testify/assert" ) @@ -48,3 +51,23 @@ func TestValidTenantIDs(t *testing.T) { }) } } + +func BenchmarkTenantID(b *testing.B) { + singleCtx := context.Background() + singleCtx = user.InjectOrgID(singleCtx, "tenant-a") + multiCtx := context.Background() + multiCtx = user.InjectOrgID(multiCtx, "tenant-a|tenant-b|tenant-c") + + b.ResetTimer() + b.ReportAllocs() + b.Run("single", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = TenantID(singleCtx) + } + }) + b.Run("multi", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = TenantID(multiCtx) + } + }) +}