вот у меня есть модель Pipeline.
Например мне надо напарсить с 4х разных источников инфу и потом после того как напарсил, выгрузить в гугл док. В пайплайне я прописываю всякие аргументы и другие данные, которые буду юзать дальше в Task-ах.
Task (belongs to Pipeline) у меня так же имеет поле для хранения разных аргументов и так же имеет поле где указан пхп класс, который надо вызвать. И еще у Task есть поле sort, для того чтобы понять в какой последовательности их выполнять в пайплайне.
Вот для описанной ситуации у меня есть 5 пхп классов, каждый делает своё. 4 класса парсят, 5й класс выгружает.
Я создаю 5 тасков, где указываю эти классы и разные аргументы.
И все таски у меня в одном пайплайне с сортировками 100, 100, 100, 100, 200, например. То есть 4 парсера парсят параллельно, а потом, после завершения, выполняется Таск по выгрузке данных.
Так же есть модельки PipelineExecution и TaskExecution. Это конкретно единичный запуск выполнения пайплайна и тасков. И у них есть стейты с описанными транзакциями.