Какой правильный подход при записи в закрытый канал в Go?

Есть 2 и более генераторов данных, пишущих в общий канал. Необходимо закрыть канал со стороны потребителя данных так, чтобы приложение на запаниковало.
Наиболее простой вариант: через panic + recover. Но, как мне кажется, это идейно не верно.
Есть типовые подходы к решению такой проблемы?

Пример:
Run on playground
package main

import "time"

func generator(v int, ch chan<- int) {
	for {
		ch <- v
	}
}

func main() {
	ch := make(chan int)
	go generator(0, ch)
	go generator(1, ch)
	go generator(2, ch)

	<-ch

	close(ch)
	time.Sleep(1 * time.Second)
	// BOOM!
}
  • Вопрос задан
  • 375 просмотров
Решения вопроса 1
@FireGM
Создайте ещё 1 канал для отправки закрытия. В отправляющих, внтури for, сделайте select из канала закрытия с веткой default, где и отправляются данные.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
mututunus
@mututunus
Backend developer (Python, Golang)
В Go нет возможности проверить состояние канала при записи в него. Закрытие канала со стороны получателя довольно редкий случай, скорее всего логику приложения можно переделать без этого.
Ответ написан
@mantyr
Пишу много Golang кода с удовольствием:)
Что бы "потушить" генератор - надо отправить ему сообщение "хватит работать". Он сможет его прочитать между итерациями и принять решение "работать ли дальше" или "не работать дальше".
Что бы это сделать посмотри на реализацию GetCommand и GetLastCommand в файле https://github.com/mantyr/runner/blob/master/chan.go

Это всего лишь один из вариантов реализации. Можно как-то упростить, отправлять не текст, а bool или иногда вместо "next" команды используется чтение другого канала (например time.After()) для равномерного выполнения команд по времени. Пример использования GetCommand есть в Readme https://github.com/mantyr/runner/ , GetLastCommand делает тоже самое, только пропускает все имеющиеся сообщения и отдаёт только последнее (иными словами ждёт когда все задачи в очереди выплеснуться и канал станет не занятым и только тогда возвращает последнее значение).

Гуглить можно по теме "Golang start stop goroutines"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы