-
Notifications
You must be signed in to change notification settings - Fork 67
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
feat: remote graphite retries #1085
base: master
Are you sure you want to change the base?
Conversation
script.sh
Outdated
@@ -0,0 +1,5 @@ | |||
while [ true ]; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
пум пум пум
func (remote *Remote) makeRequest(req *http.Request) ([]byte, error) { | ||
var body []byte | ||
|
||
func (remote *Remote) makeRequest(req *http.Request) (body []byte, isRemoteAvailable bool, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
я пока не поняла :(
зачем буль возвращать... помечу себе как подозрительное место
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Перед тем, как читать дальше прошу обратить внимание, на то, что почти все ошибки, возвращаемые из функции makeRequest
, созданы с помощью fmt.Errorf
, т.к. в них кладутся некоторые параметры (например, статус коды, url запроса, тело ответа).
Буль isRemoteAvailable
прокидывается обратно по вызовам. И нужен он для того, чтобы "вышестоящие" функции понимали, что нам делать, с ошибкой, например:
- функция
makeRequestWithRetries
поisRemoteAvailable
, принимает решение: попытаться ли снова? - функция
Fetch
поisRemoteAvailable
понимает какого типа ошибку отдавать:ErrRemoteTriggerResponse
илиErrRemoteUnavailable
. - функция
IsAvailable
возвращаетIsRemoteAvailable
и полученную ошибку.
Короче говоря, вместо того, чтобы пытаться понять по ошибке, доступен ли источник, мы это понимаем по этому булю.
Ещё стоит обратить внимание, что в отличие от prometheus, в этой реализации для graphite-remote ретраятся лишь некоторые запросы, а не все. Т.е. в случае некорректного запроса:
- для текущей реализации prometheus мы сделаем его
Retries
раз; - для этой реализации ретраев graphite-remote мы вернём первую полученную ошибку.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Почему мы не можем определять по возвращаемой ошибке, что делать дальше? Таким образом мы поднимаем наверх и ошибку (в которой уже явно сказано доступен он или нет) и рядом булев параметр
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
в отличие от prometheus, в этой реализации для graphite-remote ретраятся лишь некоторые запросы, а не все
А какие все запросы ретраятся в реализации prometheus remote? Типа что код ошибки не обрабатывается?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А какие все запросы ретраятся в реализации prometheus remote? Типа что код ошибки не обрабатывается?
Да. Я имел в виду, что если нам прилетает ошибка от prometheus api, то ретраи продолжаются независимо от ошибки.
фрагмент кода
for i := 1; ; i++ {
var res metricSource.FetchResult
res, err = prometheus.fetch(target, from, until, allowRealTimeAlerting)
if err == nil {
return res, nil
}
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Может вместо буля заведём перечислимый тип? Чтобы по сигнатуре функции было более понятно, что это значение значит?
} | ||
|
||
func isRemoteUnavailableStatusCode(statusCode int) bool { | ||
_, isUnavailableCode := remoteUnavailableStatusCodes[statusCode] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Может лучше просто неравенством проверять, что это 5хх код?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А там есть ещё 401 в списке
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А, увидел. Ну мне кажется все равно лучше это условием делать, чем мапу проверять. Нам ведь все остальные 5хх нужны тоже, правильно понимаю?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А какая у нас стратегия ретраев? Если unavailable — ретраим, если получили условную 400 — нет?
time.Sleep(duration) | ||
} | ||
|
||
// NowUnix returns now time.Time as a Unix time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// NowUnix returns now time.Time as a Unix time. | |
// NowUnix returns current time in a Unix time format. |
@@ -239,21 +241,45 @@ type GraphiteRemoteConfig struct { | |||
User string `yaml:"user"` | |||
// Password for basic auth | |||
Password string `yaml:"password"` | |||
// Retry seconds for remote requests divided by spaces | |||
RetrySeconds string `yaml:"retry_seconds"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Кажется, договорились щзаменить на массив строк, каждая из которых парсится как временной промежуток
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Может стоит вытащить ретраи в отдельную структуру? Кажется, мы потом сможем её переиспользовать в прометее и других ремоут источниках
@@ -229,5 +229,6 @@ type PlotTheme interface { | |||
// Clock is an interface to work with Time. | |||
type Clock interface { | |||
NowUTC() time.Time | |||
Sleep(duration time.Duration) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А зачем в интерфейс вытаскивать эту функцию?
if err != nil { | ||
return nil, ErrRemoteTriggerResponse{ | ||
if isRemoteAvailable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ух, это сравнение читается странно, я бы может быть инвертировал условие
Типа если ремоут недоступен, возвращаем специфическую ошибку, инчае, по стандартному маршруту
Add retry logic for graphite remote
The retry logic is configured with fields:
Also added new error:
ErrRemoteUnavailable
to signal user about graphite unavailability.