Skip to content

Commit 2a7590f

Browse files
authored
Cache labels and series results (#3315)
* cache labels and series results Signed-off-by: Ben Ye <[email protected]> * add changelog Signed-off-by: Ben Ye <[email protected]> * fix style Signed-off-by: Ben Ye <[email protected]> * update changelog Signed-off-by: Ben Ye <[email protected]> * rebase Signed-off-by: Ben Ye <[email protected]>
1 parent f494a99 commit 2a7590f

15 files changed

+696
-53
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re
1212
## Unreleased
1313
- [#3259](https://github.com/thanos-io/thanos/pull/3259) Thanos BlockViewer: Added a button in the blockviewer that allows users to download the metadata of a block.
1414
- [#3261](https://github.com/thanos-io/thanos/pull/3261) Thanos Store: Use segment files specified in meta.json file, if present. If not present, Store does the LIST operation as before.
15-
- [#3276](https://github.com/thanos-io/thanos/pull/3276) Query Frontend: Support query splitting and retry for labels and series requests.
15+
- [#3276](https://github.com/thanos-io/thanos/pull/3276) Query Frontend: Support query splitting and retry for label names, label values and series requests.
16+
- [#3315](https://github.com/thanos-io/thanos/pull/3315) Query Frontend: Support results caching for label names, label values and series requests.
1617

1718
### Fixed
1819
- [#3257](https://github.com/thanos-io/thanos/pull/3257) Ruler: Prevent Ruler from crashing when using default DNS to lookup hosts that results in "No such hosts" errors.

cmd/thanos/query_frontend.go

+17
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ func registerQueryFrontend(app *extkingpin.App) {
9696
cmd.Flag("labels.default-time-range", "The default metadata time range duration for retrieving labels through Labels and Series API when the range parameters are not specified.").
9797
Default("24h").DurationVar(&cfg.DefaultTimeRange)
9898

99+
cfg.LabelsConfig.CachePathOrContent = *extflag.RegisterPathOrContent(cmd, "labels.response-cache-config", "YAML file that contains response cache configuration.", false)
100+
99101
cmd.Flag("cache-compression-type", "Use compression in results cache. Supported values are: 'snappy' and '' (disable compression).").
100102
Default("").StringVar(&cfg.CacheCompression)
101103

@@ -138,6 +140,21 @@ func runQueryFrontend(
138140
}
139141
}
140142

143+
labelsCacheConfContentYaml, err := cfg.LabelsConfig.CachePathOrContent.Content()
144+
if err != nil {
145+
return err
146+
}
147+
if len(labelsCacheConfContentYaml) > 0 {
148+
cacheConfig, err := queryfrontend.NewCacheConfig(logger, queryRangeCacheConfContentYaml)
149+
if err != nil {
150+
return errors.Wrap(err, "initializing the labels cache config")
151+
}
152+
cfg.LabelsConfig.ResultsCacheConfig = &queryrange.ResultsCacheConfig{
153+
Compression: cfg.CacheCompression,
154+
CacheConfig: *cacheConfig,
155+
}
156+
}
157+
141158
if err := cfg.Validate(); err != nil {
142159
return errors.Wrap(err, "error validating the config")
143160
}

docs/components/query-frontend.md

+8
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ Flags:
181181
The default metadata time range duration for
182182
retrieving labels through Labels and Series API
183183
when the range parameters are not specified.
184+
--labels.response-cache-config-file=<file-path>
185+
Path to YAML file that contains response cache
186+
configuration.
187+
--labels.response-cache-config=<content>
188+
Alternative to
189+
'labels.response-cache-config-file' flag (lower
190+
priority). Content of YAML file that contains
191+
response cache configuration.
184192
--cache-compression-type=""
185193
Use compression in results cache. Supported
186194
values are: 'snappy' and ” (disable

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
github.com/cespare/xxhash v1.1.0
1414
github.com/chromedp/cdproto v0.0.0-20200424080200-0de008e41fa0
1515
github.com/chromedp/chromedp v0.5.3
16-
github.com/cortexproject/cortex v1.3.1-0.20200923145333-8587ea61fe17
16+
github.com/cortexproject/cortex v1.4.1-0.20201013144911-21bad57b346c
1717
github.com/davecgh/go-spew v1.1.1
1818
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb
1919
github.com/fatih/structtag v1.1.0

go.sum

+11-9
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,9 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbp
206206
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
207207
github.com/cortexproject/cortex v0.6.1-0.20200228110116-92ab6cbe0995/go.mod h1:3Xa3DjJxtpXqxcMGdk850lcIRb81M0fyY1MQ6udY134=
208208
github.com/cortexproject/cortex v1.2.1-0.20200805064754-d8edc95e2c91/go.mod h1:PVPxNLrxKH+yc8asaJOxuz7TiRmMizFfnSMOnRzM6oM=
209-
github.com/cortexproject/cortex v1.3.1-0.20200923145333-8587ea61fe17 h1:69LF7OuwaAS/h3GGJUBcI1Y9ZAFEcUpBZSpbHLK1eyc=
210-
github.com/cortexproject/cortex v1.3.1-0.20200923145333-8587ea61fe17/go.mod h1:dJ9gpW7dzQ7z09cKtNN9PfebumgyO4dtNdFQ6eQEed0=
209+
github.com/cortexproject/cortex v1.3.1-0.20200901115931-255ff3306960/go.mod h1:ub8BpRZrRa02BOM8NJTnI2YklxW/mGhEkJDrhsDfcfg=
210+
github.com/cortexproject/cortex v1.4.1-0.20201013144911-21bad57b346c h1:4Qcgdgk3cFAFKufkcRQBn82ngaij97+M+C7jBifPt/A=
211+
github.com/cortexproject/cortex v1.4.1-0.20201013144911-21bad57b346c/go.mod h1:bDhuzYyoL2kC0taY6nMdfv13kKYlUVoiQuy6QnkAIZw=
211212
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
212213
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
213214
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
@@ -375,8 +376,8 @@ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2K
375376
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
376377
github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys=
377378
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
378-
github.com/go-redis/redis/v8 v8.0.0-beta.10.0.20200905143926-df7fe4e2ce72 h1:HJkWCywZsCtt//EFYNtHAOQglik0kzonhiilQCrQEgs=
379-
github.com/go-redis/redis/v8 v8.0.0-beta.10.0.20200905143926-df7fe4e2ce72/go.mod h1:CJP1ZIHwhosNYwIdaHPZK9vHsM3+roNBaZ7U9Of1DXc=
379+
github.com/go-redis/redis/v8 v8.2.3 h1:eNesND+DWt/sjQOtPFxAbQkTIXaXX00qNLxjVWkZ70k=
380+
github.com/go-redis/redis/v8 v8.2.3/go.mod h1:ysgGY09J/QeDYbu3HikWEIPCwaeOkuNoTgKayTEaEOw=
380381
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
381382
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
382383
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -809,14 +810,15 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
809810
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
810811
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
811812
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
812-
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
813-
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
813+
github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
814+
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
814815
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
815816
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
816817
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
817818
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
818-
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
819819
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
820+
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
821+
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
820822
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
821823
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
822824
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -1002,6 +1004,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
10021004
github.com/thanos-io/thanos v0.8.1-0.20200109203923-552ffa4c1a0d/go.mod h1:usT/TxtJQ7DzinTt+G9kinDQmRS5sxwu0unVKZ9vdcw=
10031005
github.com/thanos-io/thanos v0.13.1-0.20200731083140-69b87607decf/go.mod h1:G8caR6G7pSDreRDvFm9wFuyjEBztmr8Ag3kBYpa/fEc=
10041006
github.com/thanos-io/thanos v0.13.1-0.20200807203500-9b578afb4763/go.mod h1:KyW0a93tsh7v4hXAwo2CVAIRYuZT1Kkf4e04gisQjAg=
1007+
github.com/thanos-io/thanos v0.13.1-0.20200923175059-57035bf8f843/go.mod h1:U7HVxfAHYptOk9xCuxr8WoILGL1wWdXVqZD3t6JifNA=
10051008
github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab h1:7ZR3hmisBWw77ZpO1/o86g+JV3VKlk3d48jopJxzTjU=
10061009
github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab/go.mod h1:eheTFp954zcWZXCU8d0AT76ftsQOTo4DTqkN/h3k1MY=
10071010
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
@@ -1025,6 +1028,7 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
10251028
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
10261029
github.com/weaveworks/common v0.0.0-20200206153930-760e36ae819a/go.mod h1:6enWAqfQBFrE8X/XdJwZr8IKgh1chStuFR0mjU/UOUw=
10271030
github.com/weaveworks/common v0.0.0-20200625145055-4b1847531bc9/go.mod h1:c98fKi5B9u8OsKGiWHLRKus6ToQ1Tubeow44ECO1uxY=
1031+
github.com/weaveworks/common v0.0.0-20200820123129-280614068c5e/go.mod h1:hz10LOsAdzC3K/iXaKoFxOKTDRgxJl+BTGX1GY+TzO4=
10281032
github.com/weaveworks/common v0.0.0-20200914083218-61ffdd448099 h1:MS5M2antM8wzMUqVxIfAi+yb6yjXvDINRFvLnmNXeIw=
10291033
github.com/weaveworks/common v0.0.0-20200914083218-61ffdd448099/go.mod h1:hz10LOsAdzC3K/iXaKoFxOKTDRgxJl+BTGX1GY+TzO4=
10301034
github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M=
@@ -1135,8 +1139,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
11351139
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
11361140
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
11371141
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
1138-
golang.org/x/exp v0.0.0-20200821190819-94841d0725da h1:vfV2BR+q1+/jmgJR30Ms3RHbryruQ3Yd83lLAAue9cs=
1139-
golang.org/x/exp v0.0.0-20200821190819-94841d0725da/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
11401142
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
11411143
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
11421144
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=

pkg/queryfrontend/cache_splitter.go renamed to pkg/queryfrontend/cache.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,16 @@ func newThanosCacheKeyGenerator(interval time.Duration) thanosCacheKeyGenerator
2929
// GenerateCacheKey generates a cache key based on the Request and interval.
3030
func (t thanosCacheKeyGenerator) GenerateCacheKey(_ string, r queryrange.Request) string {
3131
currentInterval := r.GetStart() / t.interval.Milliseconds()
32-
if tr, ok := r.(*ThanosQueryRangeRequest); ok {
32+
switch tr := r.(type) {
33+
case *ThanosQueryRangeRequest:
3334
i := 0
3435
for ; i < len(t.resolutions) && t.resolutions[i] > tr.MaxSourceResolution; i++ {
3536
}
3637
return fmt.Sprintf("%s:%d:%d:%d", tr.Query, tr.Step, currentInterval, i)
38+
case *ThanosLabelsRequest:
39+
return fmt.Sprintf("%s:%d", tr.Label, currentInterval)
40+
case *ThanosSeriesRequest:
41+
return fmt.Sprintf("%s:%d", tr.Matchers, currentInterval)
3742
}
3843
return fmt.Sprintf("%s:%d:%d", r.GetQuery(), r.GetStep(), currentInterval)
3944
}

pkg/queryfrontend/config.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,19 @@ type LabelsConfig struct {
164164
func (cfg *Config) Validate() error {
165165
if cfg.QueryRangeConfig.ResultsCacheConfig != nil {
166166
if cfg.QueryRangeConfig.SplitQueriesByInterval <= 0 {
167-
return errors.New("split queries interval should be greater than 0")
167+
return errors.New("split queries interval should be greater than 0 when caching is enabled")
168168
}
169169
if err := cfg.QueryRangeConfig.ResultsCacheConfig.Validate(); err != nil {
170-
return errors.Wrap(err, "invalid ResultsCache config")
170+
return errors.Wrap(err, "invalid ResultsCache config for query_range tripperware")
171+
}
172+
}
173+
174+
if cfg.LabelsConfig.ResultsCacheConfig != nil {
175+
if cfg.LabelsConfig.SplitQueriesByInterval <= 0 {
176+
return errors.New("split queries interval should be greater than 0 when caching is enabled")
177+
}
178+
if err := cfg.LabelsConfig.ResultsCacheConfig.Validate(); err != nil {
179+
return errors.Wrap(err, "invalid ResultsCache config for labels tripperware")
171180
}
172181
}
173182

pkg/queryfrontend/labels_codec.go

+6
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,18 @@ func (c labelsCodec) DecodeResponse(ctx context.Context, r *http.Response, req q
204204
if err := json.Unmarshal(buf, &resp); err != nil {
205205
return nil, httpgrpc.Errorf(http.StatusInternalServerError, "error decoding response: %v", err)
206206
}
207+
for h, hv := range r.Header {
208+
resp.Headers = append(resp.Headers, &ResponseHeader{Name: h, Values: hv})
209+
}
207210
return &resp, nil
208211
case *ThanosSeriesRequest:
209212
var resp ThanosSeriesResponse
210213
if err := json.Unmarshal(buf, &resp); err != nil {
211214
return nil, httpgrpc.Errorf(http.StatusInternalServerError, "error decoding response: %v", err)
212215
}
216+
for h, hv := range r.Header {
217+
resp.Headers = append(resp.Headers, &ResponseHeader{Name: h, Values: hv})
218+
}
213219
return &resp, nil
214220
default:
215221
return nil, httpgrpc.Errorf(http.StatusInternalServerError, "invalid request type")

pkg/queryfrontend/request.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ func (r *ThanosLabelsRequest) GetStart() int64 { return r.Start }
114114
// GetEnd returns the end timestamp of the request in milliseconds.
115115
func (r *ThanosLabelsRequest) GetEnd() int64 { return r.End }
116116

117-
// GetStep returns the step of the request in milliseconds.
118-
func (r *ThanosLabelsRequest) GetStep() int64 { return 0 }
117+
// GetStep returns the step of the request in milliseconds. Returns 1 is a trick to avoid panic in
118+
// https://github.com/cortexproject/cortex/blob/master/pkg/querier/queryrange/results_cache.go#L447.
119+
func (r *ThanosLabelsRequest) GetStep() int64 { return 1 }
119120

120121
// GetQuery returns the query of the request.
121122
func (r *ThanosLabelsRequest) GetQuery() string { return "" }
@@ -183,8 +184,9 @@ func (r *ThanosSeriesRequest) GetStart() int64 { return r.Start }
183184
// GetEnd returns the end timestamp of the request in milliseconds.
184185
func (r *ThanosSeriesRequest) GetEnd() int64 { return r.End }
185186

186-
// GetStep returns the step of the request in milliseconds.
187-
func (r *ThanosSeriesRequest) GetStep() int64 { return 0 }
187+
// GetStep returns the step of the request in milliseconds. Returns 1 is a trick to avoid panic in
188+
// https://github.com/cortexproject/cortex/blob/master/pkg/querier/queryrange/results_cache.go#L447.
189+
func (r *ThanosSeriesRequest) GetStep() int64 { return 1 }
188190

189191
// GetQuery returns the query of the request.
190192
func (r *ThanosSeriesRequest) GetQuery() string { return "" }

pkg/queryfrontend/response.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) The Thanos Authors.
2+
// Licensed under the Apache License 2.0.
3+
4+
package queryfrontend
5+
6+
import (
7+
"unsafe"
8+
9+
"github.com/cortexproject/cortex/pkg/querier/queryrange"
10+
)
11+
12+
// ThanosResponseExtractor helps extracting specific info from Query Response.
13+
type ThanosResponseExtractor struct{}
14+
15+
// Extract extracts response for specific a range from a response.
16+
// This interface is not used for labels and series responses.
17+
func (ThanosResponseExtractor) Extract(_, _ int64, resp queryrange.Response) queryrange.Response {
18+
return resp
19+
}
20+
21+
// ResponseWithoutHeaders returns the response without HTTP headers.
22+
func (ThanosResponseExtractor) ResponseWithoutHeaders(resp queryrange.Response) queryrange.Response {
23+
switch tr := resp.(type) {
24+
case *ThanosLabelsResponse:
25+
return &ThanosLabelsResponse{Status: queryrange.StatusSuccess, Data: tr.Data}
26+
case *ThanosSeriesResponse:
27+
return &ThanosSeriesResponse{Status: queryrange.StatusSuccess, Data: tr.Data}
28+
}
29+
return resp
30+
}
31+
32+
// headersToQueryRangeHeaders convert slice of ResponseHeader to Cortex queryrange.PrometheusResponseHeader in an
33+
// unsafe manner. It reuses the same memory.
34+
func headersToQueryRangeHeaders(headers []*ResponseHeader) []*queryrange.PrometheusResponseHeader {
35+
return *(*[]*queryrange.PrometheusResponseHeader)(unsafe.Pointer(&headers))
36+
}
37+
38+
// GetHeaders returns the HTTP headers in the response.
39+
func (m *ThanosLabelsResponse) GetHeaders() []*queryrange.PrometheusResponseHeader {
40+
return headersToQueryRangeHeaders(m.Headers)
41+
}
42+
43+
// GetHeaders returns the HTTP headers in the response.
44+
func (m *ThanosSeriesResponse) GetHeaders() []*queryrange.PrometheusResponseHeader {
45+
return headersToQueryRangeHeaders(m.Headers)
46+
}

0 commit comments

Comments
 (0)