Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[query] Add a limit exceeded header if too many series are returned #1838

Merged
merged 15 commits into from
Oct 11, 2019

Conversation

arnikola
Copy link
Collaborator

What this PR does / why we need it:
Adds a limit exceeded header to requests that go over the m3db limit

Does this PR introduce a user-facing and/or backwards incompatible change?:

None

Does this PR require updating code package or user-facing documentation?:

None

@@ -200,6 +209,10 @@ func (h *renderHandler) serveHTTP(
SortApplied: true,
}

if !exhaustive {
w.Header().Set(handler.LimitHeader, "true")
Copy link
Collaborator

@robskillington robskillington Jul 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should we make this a constant? i.e. w.Header().Set(handler.LimitHeader, handler.LimitHeaderSeriesLimitApplied)?

In the future if we limit the results due to a datacenter/remote region being down, we can concat these together perhaps.

ie.

w.Header().Set(handler.LimitHeader, handler.LimitHeaderSeriesLimitApplied)

// in handler pkg
const LimitHeaderSeriesLimitApplied = "max_fetch_series_limit_applied"

Then in future if we have another type:

w.Header().Set(handler.LimitHeader, 
  handler.LimitHeaderValue(handler.LimitHeaderSeriesLimitApplied,
    handler.LimitHeaderRegionUnavailableLimitApplied))

// in handler pkg
func LimitHeaderValues(str ...string) string {
  return strings.Join(str..., ",")
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The future is now!

@robskillington robskillington changed the title [query] add a limit exceeded header if too many series are returned [query] Add a limit exceeded header if too many series are returned Jul 28, 2019
@robskillington
Copy link
Collaborator

robskillington commented Sep 12, 2019

Adding a note here, if #1938 lands first then need to search for "pull/1838" in the source code and explicitly add the limit exceed header if any warnings.

# Conflicts:
#	src/query/generated/proto/rpcpb/query.pb.go
#	src/query/storage/fanout/storage.go
#	src/query/storage/m3/m3_mock.go
@codecov
Copy link

codecov bot commented Sep 15, 2019

Codecov Report

Merging #1838 into master will increase coverage by 4.8%.
The diff coverage is 72.2%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #1838     +/-   ##
=========================================
+ Coverage    58.6%    63.4%   +4.8%     
=========================================
  Files        1087     1114     +27     
  Lines       99076   105919   +6843     
=========================================
+ Hits        58073    67254   +9181     
+ Misses      36900    34338   -2562     
- Partials     4103     4327    +224
Flag Coverage Δ
#aggregator 64.8% <ø> (-9.8%) ⬇️
#cluster 55.8% <ø> (+0.1%) ⬆️
#collector 63.7% <ø> (ø) ⬆️
#dbnode 47.4% <0.7%> (-19.1%) ⬇️
#m3em 53.3% <ø> (+6.8%) ⬆️
#m3ninx 58.1% <ø> (+3.9%) ⬆️
#m3nsch 60% <ø> (-18.1%) ⬇️
#metrics 27.9% <ø> (+10.1%) ⬆️
#msg 74.7% <ø> (ø) ⬆️
#query 68.7% <72.2%> (+19.9%) ⬆️
#x 74.6% <ø> (+14.6%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 81744f2...32cc7e2. Read the comment docs.

@@ -40,6 +40,11 @@ import (
opentracinglog "github.com/opentracing/opentracing-go/log"
)

type readResult struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, good pattern

@@ -1,5 +1,5 @@
// Copyright (c) 2019 Uber Technologies, Inc.
//
//c
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Remove this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops


// NewResultMetadata creates a new result metadata.
// NB: capacity for warning is initialized to 1, since it is unlikely that more
// than one warning will exist.
Copy link
Collaborator

@robskillington robskillington Sep 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth even just leaving it nil? Only because I assume most queries won't cause a warning, and it will unfortunately almost definitely be a heap allocation (since it's a slice and pointer type of which the life time is hard to reason about, since not contained to use in a single method).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call


// CombineMetadata combines two result metadatas.
func (m ResultMetadata) CombineMetadata(other ResultMetadata) ResultMetadata {
combinedWarnings := make([]Warning, 0, len(m.Warnings)+len(other.Warnings))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe only allocate if len(m.Warnings)+len(other.Warnings) is greater than zero?

// Update constituent blocks with combined resultMetadata if it has been
// changed.
if !resultMeta.IsDefault() {
bl = block.NewLazyBlock(bl, lazyOpts)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah, this is kind of cool. Nice.

mu.Unlock()
results[i] = targetSeries
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the results[i] = targetSeries remain inside the mu.Lock() and mu.Unlock()? I guess it's inserting into unique index so doesn't necessarily need to be...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's the latter, but moved it into the lock just to be safe; doubt there are any perf implications here

}

if len(r.seenIters) == 0 {
return encoding.EmptySeriesIterators, nil
return result, nil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does result.SeriesIterators = encoding.EmptySeriesIterators need to be set here before returning?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, nice catch

import (
"testing"

"github.com/golang/mock/gomock"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to group gomock with the testify/assert.

@@ -351,8 +381,8 @@ func (s *m3storage) SearchSeries(
return nil, err
}

metrics := make(models.Metrics, len(tagResult))
for i, result := range tagResult {
metrics := make(models.Metrics, len(tagResult.Tags))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this into a length zero with append calls while here nmaybe?

}

return rpc.FanoutOption_FORCE_ENABLED,
fmt.Errorf("Unknown fanout option for proto encoding: %v\n", opt)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm seems this one could be return 0, fmt.Errorf("unknown ...") as pinged about elsewhere

Copy link
Collaborator

@robskillington robskillington left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than the minor comments I left

@arnikola arnikola merged commit 57eba0c into master Oct 11, 2019
@arnikola arnikola deleted the arnikola/propagate-limit branch October 11, 2019 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants