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

feat: remote graphite retries #1085

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

AleksandrMatsko
Copy link
Member

@AleksandrMatsko AleksandrMatsko commented Sep 19, 2024

Add retry logic for graphite remote

The retry logic is configured with fields:

retry_seconds: 1 1 1  // means there will be 4 retries with an interval of 1 second between them
health_check_timeout: 6s // time for request in IsAvailable method
health_check_retry_seconds: 1 1 1 // retries for IsAvailable method

Also added new error: ErrRemoteUnavailable to signal user about graphite unavailability.

script.sh Outdated
@@ -0,0 +1,5 @@
while [ true ]; do
Copy link
Member

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) {
Copy link
Member

Choose a reason for hiding this comment

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

я пока не поняла :(
зачем буль возвращать... помечу себе как подозрительное место

Copy link
Member Author

@AleksandrMatsko AleksandrMatsko Oct 1, 2024

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 прокидывается обратно по вызовам. И нужен он для того, чтобы "вышестоящие" функции понимали, что нам делать, с ошибкой, например:

Короче говоря, вместо того, чтобы пытаться понять по ошибке, доступен ли источник, мы это понимаем по этому булю.

Ещё стоит обратить внимание, что в отличие от prometheus, в этой реализации для graphite-remote ретраятся лишь некоторые запросы, а не все. Т.е. в случае некорректного запроса:

  • для текущей реализации prometheus мы сделаем его Retries раз;
  • для этой реализации ретраев graphite-remote мы вернём первую полученную ошибку.

Copy link
Member

@kissken kissken Oct 4, 2024

Choose a reason for hiding this comment

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

Почему мы не можем определять по возвращаемой ошибке, что делать дальше? Таким образом мы поднимаем наверх и ошибку (в которой уже явно сказано доступен он или нет) и рядом булев параметр

Copy link
Member

@Tetrergeru Tetrergeru Oct 4, 2024

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? Типа что код ошибки не обрабатывается?

Copy link
Member Author

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
	}
        ...
}

Copy link
Member

Choose a reason for hiding this comment

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

Может вместо буля заведём перечислимый тип? Чтобы по сигнатуре функции было более понятно, что это значение значит?

@AleksandrMatsko AleksandrMatsko marked this pull request as ready for review October 4, 2024 10:44
@AleksandrMatsko AleksandrMatsko requested a review from a team as a code owner October 4, 2024 10:44
}

func isRemoteUnavailableStatusCode(statusCode int) bool {
_, isUnavailableCode := remoteUnavailableStatusCodes[statusCode]
Copy link
Contributor

Choose a reason for hiding this comment

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

Может лучше просто неравенством проверять, что это 5хх код?

Copy link
Member Author

@AleksandrMatsko AleksandrMatsko Oct 4, 2024

Choose a reason for hiding this comment

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

А там есть ещё 401 в списке

Copy link
Contributor

Choose a reason for hiding this comment

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

А, увидел. Ну мне кажется все равно лучше это условием делать, чем мапу проверять. Нам ведь все остальные 5хх нужны тоже, правильно понимаю?

Copy link
Member

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.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// 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"`
Copy link
Member

Choose a reason for hiding this comment

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

Кажется, договорились щзаменить на массив строк, каждая из которых парсится как временной промежуток

Copy link
Member

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)
Copy link
Member

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 {
Copy link
Member

Choose a reason for hiding this comment

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

Ух, это сравнение читается странно, я бы может быть инвертировал условие

Типа если ремоут недоступен, возвращаем специфическую ошибку, инчае, по стандартному маршруту

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.

4 participants