[b/docs/gitfame_review_comments.md] Add note on goroutines.

This commit is contained in:
Arseny Balobanov 2023-03-12 20:47:51 +03:00
parent 7bc0c1f9b9
commit 2495017852

View file

@ -118,7 +118,7 @@ js := fmt.Sprintf("{\"name\":\"%s\",\"lines\":%d,\"commits\":%d,\"files\":%d}",
```
Правильно:
```
```golang
import "encoding/json"
js, err := json.Marshal(info)
@ -246,7 +246,7 @@ var (
## Вывод результатов
Вместо
```
```golang
os.Stdout.Write(bytes)
fmt.Println()
```
@ -261,3 +261,26 @@ os.Stdout.Write(fmt.Sprintf("%s\n"), string(bytes))
```golang
fmt.Println(string(bytes))
```
## Работа с горутинами
Часто встречается подобная конструкция с бесконтрольной параллелизацией:
```golang
ch := make(chan struct{}, len(files))
for _, file := range files {
go blame(file, ch)
}
```
На большом репозитории одновременно будет зашущено неопределённое количество горутин и подпроцессов.
Во-первых, каждая горутина требует сколько-то килобайт на стэк и потенциально может закончиться память.
Во-вторых, в OS есть ограничение на количество процессов + каждый процесс потребляет сколько-то системных ресурсов (ram, cpu) и суммарное потребление может оказаться неопределённо большим.
Вместо этого стоит явно ограничить количество одновременно запущенных горутин-воркеров, обрабатывающих blame, константой с небольшим дефолтом (8), либо дополнительно можно вынести степень параллелизации за флаг.
Прочитайте [пост в go блоге](https://go.dev/blog/pipelines) про типичные pipeline паттерны.
Можно сделать одного producer'а workload'а, который будет писать файлы для обработки в канал фиксированного размера, а `n` worker'ов будут читать из этого общего канала и обрабатывать файлы.