Skip to content

Instantly share code, notes, and snippets.

@em1nx
Last active November 6, 2023 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save em1nx/d46f2fc11723a848ae167afa5ee062ce to your computer and use it in GitHub Desktop.
Save em1nx/d46f2fc11723a848ae167afa5ee062ce to your computer and use it in GitHub Desktop.
Temporal php-sdk generators explained
<?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