утечка goroutine с тайм-аутом контекста? - PullRequest
0 голосов
/ 06 июня 2018

В приведенном ниже коде клиент помещает строку во входной канал службы и прослушивает ответ на выходе или на канале ошибки.

Контекст устанавливается с тайм-аутом 5 мс.

func (s service) run() {
    <-s.input

    go func() {
        select {
        case <-s.ctx.Done():
            s.errs <- errors.New("ctx done")
            return
        }
    }()

    time.Sleep(10 * time.Millisecond)
    s.output <- 42
    fmt.Println("run exit")
}

Код истекает правильно (из-за ожидания 10 мс) и выводит

error:  ctx done

Однако «запуск выхода» никогда не печатается.

Вопрос : Есть ли утечка рутины с процессами, застрявшими на

s.output <- 42

Go Playground пример

1 Ответ

0 голосов
/ 28 июня 2018

Контекст имеет тайм-аут 5 миллисекунд, и вы спите в течение 10 миллисекунд до запуска этой строки s.output <-42.Таким образом, контекст является тайм-аутом в первую очередь, и возникает ошибка, это правильно, но взгляните на main function:

select {
    case o := <-s.output:
        fmt.Println("output: ", o)
    case err := <-s.errs:
        fmt.Println("error: ", err)
    }

Оператор select достиг значения case err := <-s.errs, поэтому он прервет выбор иперейти к концу main function => выход из программы. Даже если s.output <- 42 является вызовом одновременно с s.errs <- errors.New("ctx done"), в операторе select достигнут только один случай, если вам нужно достичь второго случая, поместите цикл вокруг оператора select

...