Memo
Memo — це неіндексовані метадані у вигляді пар ключ–значення, які workflow може читати й оновлювати в будь-який момент виконання. На відміну від атрибутів пошуку, які індексуються й підтримують фільтрування, memo призначені для складніших структурованих метаданих. Вони відображаються в детальному перегляді та експорті історії, але за контрактом не беруть участі у фільтруванні й сортуванні всіх запусків.
Додавання й оновлення memo
upsertMemo() — це стійкий допоміжний виклик для послідовного коду workflow. Кожен виклик записує типізовану подію історії MemoUpserted і об’єднує нові записи зі збереженим memo запуску.
use Workflow\V2\Workflow;
use function Workflow\V2\{activity, upsertMemo};
final class OrderWorkflow extends Workflow
{
public function handle(string $orderId, string $customer): array
{
upsertMemo([
'customer_name' => $customer,
'order_id' => $orderId,
'status' => 'processing',
'line_items' => [
['sku' => 'WIDGET-1', 'qty' => 2],
['sku' => 'GADGET-3', 'qty' => 1],
],
]);
$result = activity(ProcessOrderActivity::class, $orderId);
upsertMemo([
'status' => 'completed',
'result_summary' => $result->outcome,
]);
return $result->toArray();
}
}
Memo також можна задати під час запуску через StartOptions:
use Workflow\V2\StartOptions;
use Workflow\V2\WorkflowStub;
$workflow = WorkflowStub::make(OrderWorkflow::class, 'order-123');
$workflow->start(
'ORD-456',
'Taylor',
StartOptions::rejectDuplicate()->withMemo([
'source' => 'api',
'priority' => 'high',
]),
);
Як це працює
Функція upsertMemo() приймає асоціативний масив пар ключ–значення:
- Ключі мають бути непорожніми рядками завдовжки до 64 символів
- Значення можуть містити будь-які дані, які серіалізуються в JSON: скалярні значення, null, масиви або вкладені об’єкти
- Значення
nullвидаляє відповідний ключ із memo
Кожен виклик:
- Призупиняє fiber workflow і передає команду
UpsertMemoCall - Виконавець перевіряє й нормалізує записи, сортуючи ключі за абеткою
- До історії додається подія
MemoUpsertedз оновленимиentriesта повним результатомmerged - Стовпець
memoзапуску оновлюється об’єднаною мапою
Під час replay використовуються записані події memo без повторного виконання оновлення. Це зберігає детермінізм.
Правила об’єднання
Кілька викликів оновлення в межах одного запуску об’єднують memo. Кожен виклик додає нові ключі та замінює значення наявних:
// First upsert
upsertMemo(['status' => 'processing', 'customer' => 'Taylor']);
// memo = { customer: Taylor, status: processing }
// Second upsert
upsertMemo(['status' => 'completed', 'result' => 'success']);
// memo = { customer: Taylor, result: success, status: completed }
Щоб видалити ключ, задайте для нього null:
upsertMemo(['temporary_note' => null]);
Видимість
Memo відображаються в таких місцях:
- Детальний перегляд запуску — повне об’єднане memo відображається на сторінці workflow у Waterline
- Хронологія історії — кожна подія
MemoUpsertedвідображається як типізований запис у хронології запуску - Експорт історії — memo входять до експорту історії у JSON
- Describe — відповідь
describeплощини керування містить поточне memo
Memo не входять до проєкцій стислого представлення запуску й не доступні для фільтрування, сортування або збережених представлень. Для індексованих метаданих із фільтруванням використовуйте атрибути пошуку.
Continue-as-New
Під час continue-as-new поточне memo автоматично переноситься до нового запуску. Новий запуск починається з повного об’єднаного memo попереднього запуску й може продовжувати його оновлення.
Вкладені структури
На відміну від атрибутів пошуку, які обмежені скалярними значеннями, memo підтримують вкладені структури JSON:
upsertMemo([
'order' => [
'id' => 'ORD-456',
'items' => [
['sku' => 'WIDGET-1', 'qty' => 2],
['sku' => 'GADGET-3', 'qty' => 1],
],
],
'metadata' => [
'source' => 'api',
'version' => 2,
],
]);
Для вкладених об’єктів діють ті самі обмеження ключів: непорожні рядки завдовжки до 64 символів для кожного ключа на кожному рівні.
Обмеження
- Назви ключів: непорожні рядки завдовжки до 64 символів на кожному рівні вкладеності
- Значення: будь-який тип, який серіалізується в JSON, зокрема скалярні значення, null, масиви та вкладені об’єкти
- Значення
nullвидаляє відповідний ключ - Memo — це метадані з узгодженістю в кінцевому підсумку, а не джерело істини для replay. Не обирайте гілки логіки workflow за значеннями memo
Memo, атрибути пошуку й позначки видимості
| Memo | Атрибути пошуку | Позначки видимості | |
|---|---|---|---|
| Коли задаються | Під час запуску або виконання | У будь-який момент виконання | Лише під час запуску |
| Змінюються | Так, через upsertMemo() | Так, через upsertSearchAttributes() | Ні |
| Типи значень | Будь-які серіалізовані в JSON | Лише скалярні | Лише скалярні |
| Індексуються | Ні | Так | Так |
| Фільтруються | Ні | Так | Так |
| Призначення | Структуровані метадані, примітки, контекст | Динамічний стан, відстеження прогресу | Статична класифікація |
| Події історії | MemoUpserted на кожне оновлення | SearchAttributesUpserted на кожне оновлення | Немає, задаються під час запуску |