## Домашнее задание №5 «Параллельное исполнение» Необходимо написать функцию для параллельного выполнения заданий в N параллельных горутинах: * функция должна останавливать свою работу, если произошло M ошибок; * после завершения работы функции (успешного или из-за превышения M) не должно оставаться работающих горутин; * если задачи работают без ошибок, то выполнятся `len(tasks)` задач (т.е. все задачи); * если в первых M задачах происходят ошибки, то всего выполнится не более N+M задач. Нужно учесть, что задания могут выполняться разное время, а длина списка задач `len(tasks)` может быть больше или меньше N. Значение M <= 0 трактуется на усмотрение программиста: - или это знак игнорировать ошибки в принципе; - или считать это как "максимум 0 ошибок", значит функция всегда будет возвращать `ErrErrorsLimitExceeded`; - на эту логику следует написать юнит-тест. При необходимости можно выделять дополнительные функции / ошибки. ### Критерии оценки - Пайплайн зелёный - 4 балла - Добавлены новые юнит-тесты - до 4 баллов - Понятность и чистота кода - до 2 баллов #### Зачёт от 7 баллов ### Подсказки - https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem - `sync.WaitGroup` - `go test -v -race -count=100 .` ### Частые ошибки 1) `racedetector` ругается на строчку с ассертом в тестах: - простой случай: после выхода из `Run` остаются висячие горутины, отсюда и получаем `data race` - ассерт в тестах неатомарно обращается к `runTasksCount`, в то время как зомби-горутины атомарно пытаюся её поменять. - случай посложнее: один тест завершается успешно, но висячие горутины, им порожденные, аффектят ассерты в последующих тестах. **Решение**: внимательно посмотреть места выхода из функции и гарантировать, что все порождённые вами горутины завершились к этому моменту.