Понимание времени ожидания Golang Context - PullRequest
0 голосов
/ 08 декабря 2018

У меня возникают проблемы с пониманием того, как я могу проверить, превышен ли контекст, установленный тайм-аутом, или нужно ли вообще проверять?

Это фрагмент из mongo-go-driver:

client, err := NewClient("mongodb://foo:bar@localhost:27017")
if err != nil { return err }
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil { return err }

Читая этот код, как я узнаю, что контекст превышен крайним сроком?Из того, что я наивно понимаю (или не понимаю), строка err = client.Connect(ctx) выдаст мне ошибку, включая превышение крайнего срока (если он будет превышен), поэтому я думаю, что мне даже не нужно явно проверять?

Но затем, просматривая Интернет, чтобы лучше понять, как работают контексты, я сталкиваюсь с вариантами выбора, которые явно проверяют контексты, как показано ниже (фрагмент кода из http://p.agnihotry.com/post/understanding_the_context_package_in_golang/):

//Use a select statement to exit out if context expires
  select {
  case <-ctx.Done():
    fmt.Println("sleepRandomContext: Time to return")
  case sleeptime := <-sleeptimeChan:
    //This case is selected when processing finishes before the context is cancelled
    fmt.Println("Slept for ", sleeptime, "ms")
  }

СледуетЯ буду явно проверять это? Если нет, то когда я должен использовать явные проверки? Спасибо за ваше время и помощь!

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

A context лучше всего использовать для управления жизненным циклом чего-либо.Поэтому, если вы что-то делаете (например, обрабатываете файл), вы должны проверить контекст, чтобы убедиться, что процесс не был обработан.

Есть два способа проверить, был ли contextотменено или истекло время ожидания:

  1. Context.Done() - возвращает канал, который будет закрыт при отмене контекста.
  2. Context.Err() - возвращает контекст, если контекстотменяется.

Выберите тот, который наилучшим образом соответствует вашим потребностям.Если вы делаете что-то с каналами, то использование context.Done() в select работает хорошо.Если вы используете цикл for при чтении io.Reader, тогда проверка context.Err() проще.

При этом, если вы запускаете что-то, что также имеет контекст, вы всегда должны использоватьконтекст, который у вас уже есть, если вы хотите, чтобы эта новая «вещь» была отменена, если вы были отменены.

0 голосов
/ 08 декабря 2018

Код select во второй части вашего вопроса - это как может выглядеть код в методе Connect.Там он проверяет, готов ли ctx.Done() к отправке.Если это так, то контекст был отменен либо из-за истечения времени ожидания, либо из-за того, что был вызван cancel().

ошибки - это значения.Относитесь к ним как к таковым.Если для вас важно понять причину ошибки (отключение сети? Неожиданные данные? Тайм-аут?), Вам следует выполнить проверку и действовать соответственно.Если восстановление после ошибки независимо от причины одинаково, то проверка ошибки не , как важно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...