Skip to content

Latest commit

 

History

History
84 lines (66 loc) · 5.77 KB

README.md

File metadata and controls

84 lines (66 loc) · 5.77 KB

Домашнее задание №5 «Параллельное исполнение»

Необходимо написать функцию для параллельного выполнения заданий в n параллельных горутинах:

  • количество создаваемых горутин не должно зависеть от числа заданий, т.е. функция должна запускать n горутин для конкурентной обработки заданий и, возможно, еще несколько вспомогательных горутин;
  • функция должна останавливать свою работу, если произошло m ошибок;
  • после завершения работы функции (успешного или из-за превышения m) не должно оставаться работающих горутин.

Нужно учесть, что задания могут выполняться разное время, а длина списка задач len(tasks) может быть больше или меньше n.

Значение m <= 0 трактуется на усмотрение программиста:

  • или это знак игнорировать ошибки в принципе;
  • или считать это как "максимум 0 ошибок", значит функция всегда будет возвращать ErrErrorsLimitExceeded;
  • на эту логику следует написать юнит-тест.

Граничные случаи:

  • если задачи работают без ошибок, то выполнятся len(tasks) задач, т.е. все задачи;
  • если в первых выполненных m задачах (или вообще всех) происходят ошибки, то всего выполнится не более n+m задач.

(*) Дополнительное задание: написать тест на concurrency без time.Sleep

Придумайте тест, который проверит concurrency другим способом.

Текущий тест "tasks without errors" использует time.Sleep и подсчет времени выполнения, чтобы сделать вывод о конкурентности использования. Проблема тестов на слипчиках в том, что на CI часто не хватает CPU и подобные тесты работают нестабильно.

Подсказка: используйте require.Eventually.


Пример

Имеем 10 задач, n=4 воркера, m=2 ошибки.

  • Запускаем:
--------------ok (узнал, что лимит превышен и остановился)
-----------err
-------err
--------------------ok

Выполнится 4 задачи (2 успешно) <= 4 + 2, остальные задачи  не берем.

  • Другая ситуация, работающие воркеры успели еще взять задач:
------ok--------ok (узнал, что лимит превышен и остановился)
-----------err
---err
--------ok-------ok

Выполнится 6 задач (4 успешно) <= 4 + 2, остальные задачи не берем.

  • Ошибок не было:
-------ok-----ok-----ok-----ok  (1 воркер выполнил 4 задачи)
-----------ok-------------ok    (2 воркер выполнил 2 задачи)
-----ok---------ok---------ok   (3 воркер выполнил 3 задачи)
--------------------ok          (4 воркер выполнил 1 задачу)

Выполнится 10 задач (10 успешно): задач не осталось, воркеры остановились.


При необходимости можно выделять дополнительные функции / ошибки.

Критерии оценки

  • Пайплайн зелёный - 4 балла
  • Добавлены новые юнит-тесты - до 4 баллов
  • Понятность и чистота кода - до 2 баллов

Зачёт от 7 баллов

Подсказки

Частые ошибки

  1. racedetector ругается на строчку с ассертом в тестах:
  • простой случай: после выхода из Run остаются висячие горутины, отсюда и получаем data race - ассерт в тестах неатомарно обращается к runTasksCount, в то время как зомби-горутины атомарно пытаюся её поменять.
  • случай посложнее: один тест завершается успешно, но висячие горутины, им порожденные, аффектят ассерты в последующих тестах.
  1. Запускаются лишние горутины (инструкции go). Их количество за все время работы Run должно быть n (плюс, возможно, еще одна-две, если по другому не получается). В некоторых решениях ошибочно контроллируется количество одновременно работающих, а не общее количество.

Решение: внимательно посмотреть места выхода из функции и гарантировать, что все порождённые вами горутины завершились к этому моменту.