Перейти до основного вмісту
Версія: 2.0

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

Кожен виклик:

  1. Призупиняє fiber workflow і передає команду UpsertMemoCall
  2. Виконавець перевіряє й нормалізує записи, сортуючи ключі за абеткою
  3. До історії додається подія MemoUpserted з оновленими entries та повним результатом merged
  4. Стовпець 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 на кожне оновленняНемає, задаються під час запуску