Last active
November 6, 2023 19:11
-
-
Save em1nx/d46f2fc11723a848ae167afa5ee062ce to your computer and use it in GitHub Desktop.
Temporal php-sdk generators explained
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Иллюстрация работы конструкции $foo = yield bar() в php-sdk для Temporal. | |
* @author Chernov Emin <em1nx@yandex.ru> | |
*/ | |
// Создаём activity1 и activity2 в виде генераторов, которые позволяют передать управление работой функции во внешний код. | |
// Если просто вызвать activity1() или activity2(), то ничего не произойдёт, но функция вернёт объект-генератор. | |
function activity1(): Generator { | |
yield; | |
echo "execute activity1\n"; | |
return "activity1"; | |
} | |
function activity2(): Generator { | |
yield; | |
echo "execute activity2\n"; | |
return "activity2"; | |
} | |
// Далее создаём workflow опять же в виде генератора по аналогичным причинам — нам нужна возможность управлять работой функции снаружи. | |
// Здесь как раз и появляется весёлая конструкция $a1 = yield activity1(). | |
// Чтобы понять её смысл, нужно вспомнить, что генераторы могут не только передавать значения наружу, но и получать их извне через вызов Generator::send($value). | |
// При этом значение $value будет установлено в $a1 через = yield. | |
function workflow(): Generator { | |
$a1 = yield activity1(); | |
$a2 = yield activity2(); | |
return [$a1, $a2]; | |
} | |
// Итак, запускаем workflow() и получаем workflow-генератор по которому мы можем итерироваться т.к. генератор реализует интерфейс Iterator. | |
// Последовательно запускаем все activity-функции, каждая из которых возвращает activity-генератор... | |
// Activity-генератор нам нужен для того, чтобы выполнить функцию только один раз, а второй раз просто "вернуть" значение через Generator::send() | |
$workflowGenerator = workflow(); | |
$activityResults = []; | |
foreach ($workflowGenerator as $activityGenerator) { | |
// Стартуём выполнение activity | |
$activityGenerator->send(null); | |
// Сохраняем результат выполнения activity, здесь это строки "activity1" или "activity2" | |
$results[] = $activityGenerator->getReturn(); | |
} | |
// Опять получаем workflow-генератор, но на этот раз мы не запускаем activity-функции, а просто "устанавливаем" их значения через Generator::send() | |
$workflowGenerator = workflow(); | |
foreach ($results as $result) { | |
$workflowGenerator->send($result); | |
} | |
// В итоге получаем оба наших значения из workflow-генератора | |
var_dump($workflowGenerator->getReturn()); | |
// Понятное дело, что это не код Temporal и в реальном кейсе там не два цикла, а один, но с кешированием — если activity уже был выполнен, | |
// то он отправляется через $workflowGeneraotr->send(), а если не был, то запускается через $activityGenerator->send(null) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment