Протокол Avro Value
Durable Workflow 2.0 використовує одну фіксовану рекурсивну схему
durable_workflow.protocol.Value
для кожного payload Avro. Входи й результати workflow, значення та деталі
помилок activity, signal, query, update, історія replay та payload у зовнішньому
сховищі використовують ту саму схему. Застосунки не публікують власні
схеми Avro, а платформа не потребує мережевого реєстру схем.
Об’єднання значень має окремі іменовані гілки для null, boolean, знакового
64-бітного цілого числа, скінченного double, bytes, рядка UTF-8, списку
та мапи з рядковими ключами. Це зберігає відмінності 7 і 7.0, тексту
та bytes, списків і мап у PHP, Python і Rust.
Формат передавання
Поле blob містить base64 стандартних байтів Avro single-object:
C3 01 || 8-byte little-endian CRC-64-AVRO fingerprint || Avro datum
Схема v1 має fingerprint e2a33dff55802237. SDK містять незмінну схему
для кожного підтримуваного fingerprint, обирають схему запису з кадру
й узгоджують її з поточною схемою читання. Невідомий fingerprint або
несумісна нова гілка завершуються unsupported_payload_schema.
Декодери не вгадують формат і не переходять до JSON.
Майбутні види значень додаються в кінець об’єднання як нові гілки record з унікальними назвами. Опубліковані гілки ніколи не змінюють порядок і не використовуються повторно для іншого значення.
Правила значень
- Ключі мап мають бути рядками. SDK відхиляють інші ключі замість перетворення їх на рядки.
- Цілі числа мають вкладатися в знаковий 64-бітний діапазон Avro
long. - Double мають бути скінченними. NaN і нескінченності відхиляються.
- Python
bytesі RustAvroValue::Bytesобирають Avrobytes. Клієнти PHP використовуютьAvroBinaryValue::fromBytes(), оскільки сам рядок PHP не визначає, чи є він текстом або двійковими даними. - Decimal, цілі довільної точності, дата/час, UUID, enum, dataclass, Pydantic та об’єкти предметної області потребують явних адаптерів до канонічного виду значення.
Avro — єдиний кодек payload Durable Workflow 2.0. Документи запитів і
відповідей HTTP залишаються транспортом JSON, але кожне стійке значення
в них використовує цю фіксовану схему й кадр single-object. Позначка кодека
json, невідомий кодек або сирий стійкий blob без позначки відхиляються
з unsupported_payload_codec. Runtime ніколи не перекодовують і не вгадують.
Проєкція для перегляду JSON
Описи run зберігають input_envelope, output_envelope і конверти
результатів як джерело payload без втрати даних. Інтерфейси перегляду JSON,
як CLI та Waterline, відображають значення, які JSON не може подати,
через типізовану проєкцію:
{"$type":"bytes","base64":"AP8="}
{"$type":"map","entries":[{"key":"0","value":"zero"}]}
Проєкція мапи застосовується для порожніх мап і рядкових ключів, схожих на числа, які масиви PHP не зберігають без зміни типу. Звичайні скаляри, списки та однозначні мапи з рядковими ключами залишаються звичайними значеннями JSON. Споживачі, яким потрібне початкове типізоване значення, декодують супровідний конверт, а не проєкцію відображення.
Відтворюваний benchmark
Кожен SDK містить однаковий benchmark репрезентативних значень і забезпечує бюджет обраного виробничого шляху:
# PHP SDK checkout
composer benchmark-avro-value
# Python SDK checkout
python benchmarks/avro_value.py --enforce
# Rust SDK checkout
cargo run --release --example avro_value_benchmark -- --enforce
Вивід JSON порівнює компактний JSON, вилучену обгортку JSON-in-Avro та
фіксовану типізовану схему. Він повідомляє розміри сирого datum, payload
у кадрі та фактичного HTTP-конверта {codec, blob} разом із наскрізною
затримкою адаптера, кодування й декодування. AVRO_VALUE_ENCODE_BUDGET_US
і AVRO_VALUE_DECODE_BUDGET_US можуть посилити типові бюджети на runner
перевірки випуску. CI виконує ці команди з перевіркою бюджету. Регресію
виробничого шляху потрібно пояснити або виправити до випуску. Стара
реалізація обгортки існує лише в benchmark, без сумісного шляху runtime.
Перевірка перед розгортанням
Під час запуску Server перелічує всі збережені payload_codec і перевіряє
magic single-object та fingerprint фіксованої схеми для вбудованих кадрів,
конвертів вкладеної історії та посилань на зовнішні payload. Розгортання
зупиняється до запуску нового runtime за наявності активного чи потрібного
для replay payload не Avro, payload без позначки, пошкодженого посилання
або застарілого кадру. Активні run можуть завершитися на поточній
попередній версії. Збережені термінальні та потрібні для replay дані мають
пройти міграцію історії попередніх версій
із резервною копією перед змінами. Експорт run не змінює відхилений стан
бази даних. Ніколи не видаляйте історію для обходу попередньої перевірки.