1) вариант с асинками
Простейший -
https://amphp.org/artax/
Чуть больше контроля -
https://amphp.org/parallel-functions/
Еще чуть больше контроля -
https://github.com/amphp/parallel
Нюанс в том, что это не самая простая штука в плане дебага и поддержка у нее так себе. Да, она работает, да, она покрыта тестами, да, она поддерживается, но любая нестандартная херня и самостоятельно ничего фиксануть вы не сможете.
2) вариант с подготовкой данных до юзерского реквеста - если это возможно
3) говно-вариант - ваше решение. Загнать в базу/редис и там считать сколько осталось, дергая статус каждые 500мс.
Не совсем понял в чем там проблема с окончанием воркеров - засуньте все в job chain, либо лочьте по нужным ключам redis::funnel'ом, либо лочьте базой. Не совсем ясно, какая конкретно стоит задача, вместе со всеми ее нюансами.