Pull to refresh

Comments 6

Какой-то неполноценный гайд, семафор есть в виде конкретной реализации с весами - https://pkg.go.dev/golang.org/x/sync/semaphore, равно как есть готовый рейт-лимитер с управлением всплесками и прочим - https://pkg.go.dev/golang.org/x/time/rate

В реальности без burst-control в RL и без весов в семафоре почти не обходится

Я согласен с тем, что изложенные в этой статье паттерны не так эффективны как уже готовые компоненты из пакетов go.

Эта статья в первую очередь показывает:
1) Базовую реализацию
2) Use-Case

Ну это слабо похоже на базовую реализацию.

Вы же разрешите покритиковать?

Воркерпул ужасен. Прям пример "как не надо делать".

Зачем воркеру вообще знать, что он в вейтгруппе работает? Воркер - это тупая штука, которая, просто берет по одному значению из канала и что-то с ним делает, пока канал не закроется. Зачем ему при этом знать, что он в вейтгруппе живет? Просто чтобы нельзя было без вейтгруппы его использовать?

Fan-In/Fan-Out - это же вот отсюда скопипащено? https://habr.com/ru/companies/otus/articles/886740/
Ну там плохому учат. Давайте начнем с того, что fan-in и fan-out (как и мультиплексор/демультиплексор) две достаточно разные, не зависящие друг от друга штуки. "По классике" в Go все обычно сводится к сбору N каналов в 1 или распределению данных из одного канала в N других.

В вашем примере просто еще один воркерпул. Вот прям идентичный алгоритм с новыми названиями функций и переменных.

Да и вот это вы зачем сделали,

	input := make(chan int, 10)
	output := make(chan int, 10)

Зачем буфер у канала? Не разобрались просто, как тут правильно с вейтгруппой работать? Ну вот эталонно-плохой код получился...

Пайплайн получился достаточно опасный. Каждый пионер Go-разработчик в курсе, что запускать запись в канал до гарантии чтения из него - достаточно печальная идея. Поэтому методы вашего "пайплайна" лучше инвертировать. Да и конструкторы можно будет "зачейнить", и потом быть уверенным, что достаточно закрыть последний вернувшийся канал, и все само схлопнется.

В PubSub'е отлично бы смотрелся Fan-Out на выходе, как пример того, что паттерны отлично реализуются поверх других паттернов. Ну и от неприятия defer'ов пора бы уже избавляться - 2025 год на дворе.

Select-с-таймаутом вообще не паттерн. Ну и демонстрировать на этом молодежи работу с таймаутами, утверждая, что это для сценариев "Сетевой клиент, который пытается подключиться к серверу и останавливается, если сервер не отвечает вовремя." - форменная бессовестность. Покажите людям контекст.

Семафор... Ну давайте будем с собой честными, в примере - просто еще один воркерпул.... Вы бы хотя бы up/down вне воркера делали, в этом был бы смысл. А так - оно ж даже количество горутин не ограничивает...

Рейтлимитер... Ну, с тикером работаем странно. Вот здесь как раз select { case <- ticker.C: } отлично зайдет. Закрыли неаккуратно, так память течет. Да и в сценарии, если fmt.Println("Обработка запроса", req)завершился позже тикера - будем ждать следующего тика зачем-то... Он тоже плохой.

Базовая реализация воркерпула над каналом выглядит, все же, вот так:

func RunWorkerPool[T any](workerCount int, in <-chan T, fn func(T)) {
	var wg sync.WaitGroup
	defer wg.Wait()
	for range workerCount {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for item := range in {
              fn(item)
            }
		}()
	}
}

Можете ещё для пайплайна написать, как в нём что инвертировать? Я не смог представить, как передавать на чтение канал, в который ещё не начали писать, но при этом каналы же создаются в процессе вызова функции, поэтому всё равно их нужно вызывать в таком порядке. Или создавать каналы вне функций? А где их закрывать?

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

// Я пока не знаю, что такое семафоры, и что там у них за веса. Если бы автор начал сразу с этого, я бы не понял вообще ничего. Очень надеюсь, что у меня в учебниках об этом напишут.

Спасибо! Это то, что нужно для новичка. Я только начал изучать Go после 5 лет питона. Было очень интересно и сразу стало понятно, с чего можно начать, и что гуглить, чтобы сделать лучше.

Sign up to leave a comment.

Articles