Последние пару лет мне приходилось работать над инструментами, сабмиттерами и прочими скриптами для рендерферм. Я с нетерпением ждал выхода ТОПов для гудини с момента их анонса, и уже составил свои личные ожидания от них. Но, как позже оказалось, некоторые решения в ТОПах были сделаны совсем не так, как я ожидал. И хотя было ясно понятно, почему эти решения были сделаны именно так, всё же мысль мысль "а что было бы если..." засела у меня в голове, где-то на задворках.
Наконец, с месяц назад я таки решил попробовать. Ну и уж если пробовать - зачем привязываться к какому-то конкретному софту - всё делалось с нуля, ни к чему не привязано - прототип, тест идей
И папка с кодом на скорую руку получила название Taskflow
И папка с кодом на скорую руку получила название Taskflow
Итак, Таскфлоу - это очередной распределенный менеджер задач, оперирующий набором локальных и удалённых рабочих машин, собственно выполняющих тяжелую работу. Так что это, по сути, менеджер для рендер фермы, но на самом деле - более общее решение, как и ТОПы (PDG)
Основная идея тут в том, что носителями информации являются таски (task), таски обрабатываются нодами, которые, в свою очередь, связаны в направленный граф (не ациклический). Заметьте, это не граф зависимостей, в том смысле, что обычно вкладывают в этот термин - здесь не происходит никакого "вычисления графа"
Итак, таски переходят от ноды к ноде, можно сказать, "перетекают" от ноды к ноде (flow) - task flow - наконец пазл сложился...
В отличии от ТОПов (PDG) - таски полностью динамические, они постоянно двигаются по графу, тогда как в ТОПах таски привязаны к конкретной ноде, и могут создавать новые таски лишь на нодах ниже. Очевидным недостатоком такого подхода является отсутствие возможности "статической генерации" тасков, как это делает ТОП - это и юзер-френдли, и позволяет оценить масштаб работ перед тем, как эти работы собственно начинать. Также в таскфлоу нет особенного состояния начала и конца вычислений - таски будут гулять по графу, пока не упрутся в тупик, или не будут помечены "завершенными" одной из нод. Это как те бесполезные машины на ютубе, катающие шарики через ряд замысловатых препятствий. закидывай в неё шарики, и они будут там крутиться. Если в машине задуман выход для шариков - шарики выйдут из машины, если нет, то они будут ходить по кругу до посинения.
Сам термин таск (task = задача) - довольно абстрактный на самом деле. Это просто некоторая сущность с аттрибутами и метадатой. ноды решают, что делать с таском на основании этих аттрибутов. Таски могут разделяться и соединяться назад, таски могут создавать новые таски, и умирать, достигая "завершенного" состояния.
Нода обрабатывает пришедшие ей таски: она может решить изменить аттрибуты, и создать некоторую работу (payload) на таске. работа - это то, что исполняется рабочим в данной системе. Таскфлоу раздаёт работу рабочим
Рабочий - это просто процесс, запущенный на этой или другой машине в сети. рабочий исполняет работу и возвращает результаты
Работа - это просто информация, что выполнить и как, какие файлы передать туда, сюда и как их мапить, если нужно.
Далее нода, создавшая работу может проанализировать её результат и решить опять поменять аттрибуты на таске, возможно даже решить создать новую работу.
У нод может быть внутреннее состояние, но они не сами являются рабочими процессами. Например, нода может решить запоминать id обработанных ей тасков, чтобы не обрабатывать их второй раз, если те каким-то образом снова вернуться в эту ноду. Или нода может следить за иерархией тасков, и не пропускать детей до родителей, или наоборот.
Вцелом, Таскфлоу задумывался довольно амбициозно: поддержка машин локальной сети и удалённых (облачных), подключающихся и отключающихся по необходимости, простая конфигурация, легкое развертывание в одной действие... Так что реализация всего этого займет некоторое время...
базовый концепт выглядит примерно так:
Несмотря на то, что в первую очередь этот прототип - площадка для теста некоторых идей лично для меня, - я думаю потенциально это может пригодиться в реальном мире. Например, группе фрилансеров, организующих рендер и пайплайн на машинах друг друга, или даже может быть для небольших студий.
Теперь давайте вернёмся в реальный мир: что собственно готово? На данный момент - почти ничего, я в стадии активнего вечернего девелопмента, пока что нету прототипа на публичный показ, но этим постом я отмечаю важное событие - я наконец набросал прототипы всех компонент и таки запустил пример реальной задачи!
Это пример работы текущего прототипа - он выполняет простейшую задачу по рендеру сцены мантрой. Интерфейс еще очень сырой (да и должен быть заменён веб интерфейсом), так что мне придется объяснить происходящее:
Один таск добавляется в ноду#7
нода#7 - имеет типа разделителя фреймренджа - она ищет аттрибут "frames" на таске и разделяет список кадров в этом аттрибуте на блоки заданной величины (в данном случае 10), для каждого нового блока создается новый таск. таким образом если входящий таск имел фрейм рендж 0-29, то после обработки он станет 0-9, и две новых копии таска будут созданы: с фреймами 10-19 и 20-29 соответственно. Эти таски перейдут к ноде#6
нода#6 - это генератор ifd. она ищет аттрибуты "hipname", "hipdriver" и "frames" на таске и создает работу для выполнения рабочими. эта работа состоит из скрипта для гудини, генерящего ifd из указанной сцены, указанной мантра нодой, в указанных кадрах. скрипт будет сообщать таскфлоу о каждом готовом кадре и добавлять новый таск, с аттрибутом ifdpath.
нода#8 - это рендерер ifd. она как раз ищет аттрибут "ifdpath" и создает работу по рендеру заданного ifd мантрой.
В данном примере запущено 2 рабочих: на видео таски, обрабатываемые рабочими отмечаются жёлтым. пока один рабочий генерит ifd, второй уже начинает рендерить кадры, произведённые первым.
Я буду постить обновления по разработке таскфлоу сюда
прототип будет доступен как только система будет доведена до минимально юзерфрендли состояния
прототип будет доступен как только система будет доведена до минимально юзерфрендли состояния
если хотите поддержать проект - https://www.patreon.com/xapkohheh