-
Notifications
You must be signed in to change notification settings - Fork 627
Distributor write path: put httpgrpc.Errorf() calls at the topmost level #6191
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
Merged
Merged
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
d04d395
Distributor write path: put httpgrpc.Errorf() calls at the topmost level
duricanikolic dc32aae
Implementing review findings
duricanikolic b00249b
Get rid of replicasNotMatchError and tooManyClustersError
duricanikolic 944082e
Remove wrapping from req.WriteRequest() and tenant.TenantID() errors
duricanikolic 728d47c
Get rid of distrbutorerror.Error interface
duricanikolic 5bcd840
Get rid of push.getHTTPStatusAndMessage()
duricanikolic 0f784ce
Revert validate.CleanAndValidateMetadata signature change
duricanikolic b05f212
Make DistributorPushError private
duricanikolic d05e965
Rename errors by removing the Error suffix
duricanikolic 4f1bdf6
Handle service overloaded error correctly
duricanikolic 3c6ede5
Fixing review findings
duricanikolic 34c1913
Ensure errors.As and erros.Is work correctly
duricanikolic 5c2a168
Revert distributor_test.go
duricanikolic 96c82a0
Fix wrong status code 429 instead of 400 in case of TooManyCluster error
duricanikolic 592c6d4
Some refactorings
duricanikolic ac43e20
Fixing review findings
duricanikolic 8218c4e
Adding TestToHTTPStatus
duricanikolic 430144d
Update pkg/distributor/distributorerror/errors.go
duricanikolic c1d2212
Re-declare ReplicasNotMatch and TooManyClusters errors
duricanikolic 10480cd
Fixing Validation error
duricanikolic 865a7f3
Get rid of most of the methods from validation/errors.go
duricanikolic a179533
Get rid of remaining methods in validation/errors
duricanikolic 55f3944
Rename all distributorerr constructors
duricanikolic c055c8d
Fixing review findings
duricanikolic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
package distributorerror | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
const ( | ||
// 529 is non-standard status code used by some services to signal that "The service is overloaded". | ||
StatusServiceOverloaded = 529 | ||
) | ||
|
||
// ReplicasNotMatch is an error stating that replicas do not match. | ||
type ReplicasNotMatch struct { | ||
duricanikolic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
replica, elected, format string | ||
} | ||
|
||
// ReplicasNotMatchErrorf formats and returns a ReplicasNotMatch error. | ||
// The error message is formatted according to the given format specifier, replica and elected. | ||
// In order to print the limit and the burst, the format specifier must contain two %s verbs. | ||
func ReplicasNotMatchErrorf(format, replica, elected string) ReplicasNotMatch { | ||
return ReplicasNotMatch{ | ||
replica: replica, | ||
elected: elected, | ||
format: format, | ||
} | ||
} | ||
duricanikolic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
func (e ReplicasNotMatch) Error() string { | ||
return fmt.Sprintf(e.format, e.replica, e.elected) | ||
} | ||
|
||
// TooManyClusters is an error stating that there are too many HA clusters. | ||
type TooManyClusters struct { | ||
limit int | ||
format string | ||
duricanikolic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// TooManyClustersErrorf formats and returns a TooManyClusters error. | ||
// The error message is formatted according to the given format specifier and limit. | ||
// In order to print the limit, the format specifier must contain a %d verb. | ||
func TooManyClustersErrorf(format string, limit int) TooManyClusters { | ||
return TooManyClusters{limit: limit, format: format} | ||
} | ||
|
||
func (e TooManyClusters) Error() string { | ||
return fmt.Sprintf(e.format, e.limit) | ||
} | ||
|
||
// Validation is an error, used to represent all validation errors from the validation package. | ||
type Validation struct { | ||
error | ||
} | ||
|
||
// ValidationErrorf formats and returns a Validation error. | ||
// The error message is formatted according to the given format specifier and arguments. | ||
// The new error does not retain any of the passed parameters. | ||
func ValidationErrorf(format string, args ...any) Validation { | ||
// In order to ensure that no label is retained, we first create a string out of the | ||
// given format and args, and then create an error containing that message. | ||
msg := fmt.Sprintf(format, args...) | ||
return Validation{error: errors.New(msg)} | ||
} | ||
|
||
// IngestionRateLimited is an error used to represent the ingestion rate limited error. | ||
type IngestionRateLimited struct { | ||
format string | ||
limit float64 | ||
burst int | ||
} | ||
|
||
// IngestionRateLimitedErrorf formats and returns a IngestionRateLimited error. | ||
// The error message is formatted according to the given format specifier, limit and burst. | ||
// In order to print the limit and the burst, the format specifier must contain %v and %d verbs. | ||
func IngestionRateLimitedErrorf(format string, limit float64, burst int) IngestionRateLimited { | ||
return IngestionRateLimited{ | ||
format: format, | ||
limit: limit, | ||
burst: burst, | ||
} | ||
} | ||
|
||
func (e IngestionRateLimited) Error() string { | ||
return fmt.Sprintf(e.format, e.limit, e.burst) | ||
} | ||
|
||
// RequestRateLimited is an error used to represent the request rate limited error. | ||
type RequestRateLimited struct { | ||
format string | ||
limit float64 | ||
burst int | ||
} | ||
|
||
// RequestRateLimitedErrorf formats and returns a RequestRateLimited error. | ||
// The error message is formatted according to the given format specifier, limit and burst. | ||
// In order to print the limit and the burst, the format specifier must contain %v and %d verbs. | ||
func RequestRateLimitedErrorf(format string, limit float64, burst int) RequestRateLimited { | ||
return RequestRateLimited{ | ||
format: format, | ||
limit: limit, | ||
burst: burst, | ||
} | ||
} | ||
|
||
func (e RequestRateLimited) Error() string { | ||
return fmt.Sprintf(e.format, e.limit, e.burst) | ||
} | ||
|
||
// ToHTTPStatus converts the given error into an appropriate HTTP status corresponding | ||
// to that error, if the error is one of the errors from this package. In that case, | ||
// the resulting HTTP status is returned with status true. Otherwise, -1 and the status | ||
// false are returned. | ||
// TODO Remove this method once HTTP status codes are removed from distributor.Push. | ||
// TODO This method should be moved into the push package. | ||
func ToHTTPStatus(pushErr error, serviceOverloadErrorEnabled bool) (int, bool) { | ||
var ( | ||
replicasNotMatchErr ReplicasNotMatch | ||
tooManyClustersErr TooManyClusters | ||
validationErr Validation | ||
ingestionRateErr IngestionRateLimited | ||
requestRateErr RequestRateLimited | ||
) | ||
|
||
switch { | ||
case errors.As(pushErr, &replicasNotMatchErr): | ||
return http.StatusAccepted, true | ||
case errors.As(pushErr, &tooManyClustersErr): | ||
return http.StatusBadRequest, true | ||
case errors.As(pushErr, &validationErr): | ||
return http.StatusBadRequest, true | ||
case errors.As(pushErr, &ingestionRateErr): | ||
// Return a 429 here to tell the client it is going too fast. | ||
// Client may discard the data or slow down and re-send. | ||
// Prometheus v2.26 added a remote-write option 'retry_on_http_429'. | ||
return http.StatusTooManyRequests, true | ||
case errors.As(pushErr, &requestRateErr): | ||
// Return a 429 or a 529 here depending on configuration to tell the client it is going too fast. | ||
// Client may discard the data or slow down and re-send. | ||
// Prometheus v2.26 added a remote-write option 'retry_on_http_429'. | ||
if serviceOverloadErrorEnabled { | ||
return StatusServiceOverloaded, true | ||
} | ||
return http.StatusTooManyRequests, true | ||
default: | ||
return -1, false | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.