Как стать автором
Обновить

Комментарии 8

Только вот предложенное решение задачки из примера порождает dangling routines.

То есть если заменить код main на такой:

timeout := 5 * time.Second
err := executeTaskWithTimeout(context.Background(), timeout)
if err != nil {
    log.Print(err)
}

runtime.Goexit()

Будет видно, что рутина с задачей не завершается. Не то чтобы был вариант этого избежать, но лучше иметь в виду, что без контекста (и его правильной обработки) по-настоящему завершить «зависшую» задачу не выйдет, лишь создать видимость того, что программа прогрессирует.

Спасибо за замечание

go func() {
  executeTask()
  done <- struct{}{}
  close(done)
}()

Интересный материал, но посылать структуру в канал тут лишнее, достаточно просто его закрыть.

Да, можно так. Тогда и буферизированный канал не нужен.

хороший материал, спасибо! больше статей по внутрянкам golang

Я не понимаю зачем в вашем примере вообще использовать контекст. Без него всё гораздо проще. Я написал аналог на таймауте. Объясните, пожалуйста.

func executeTaskWithTimeout(timeout time.Duration) error {
    timer1 := time.timer(timeout)

	done := make(chan struct{}, 1)

	go func() {
		executeTask()
		close(done)
	}()

	select {
	case <-done:
		return nil
	case <-timer1.C:
		return errors.New("Timeout fired!")
	}
}

Спасибо за вопрос.

Это не пример. Это задание на закрепление материала. В задании предлагается реализовать функцию с использованием context.WithTimeout().

Если вопрос в том, зачем использовать контекст, то в реальном приложении его использование имеет ряд преимуществ.

Например, в случае контекста отмена произойдет по всему конвейеру (по всей глубине стека вызовов).

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

Второй вопрос: "Когда контекст отменяется в main(), отменяется и код в глубине стека вызовов."

То есть получается можно отменить контекст на самом низу или на самом верху. Разницы нет и всё будет корректно отработано?

Третий вопрос. Как осуществляется отмена контекста? Через канал, возвращаемый Done()?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий