From 57e9241dce3f9e3abb8ea498f2d7fa827b4a2fd1 Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Fri, 16 Oct 2026 01:33:53 +0000 Subject: [PATCH] Remove retired Temporal comparison page and links --- .github/workflows/qualification.yml | 6 - docusaurus.config.js | 16 -- i18n/de/docusaurus-theme-classic/footer.json | 3 - i18n/es/docusaurus-theme-classic/footer.json | 1 - i18n/fr/docusaurus-theme-classic/footer.json | 3 - i18n/ja/docusaurus-theme-classic/footer.json | 1 - .../docusaurus-theme-classic/footer.json | 1 - .../compare/temporal.mdx | 228 ------------------ i18n/uk/docusaurus-theme-classic/footer.json | 4 - .../docusaurus-theme-classic/footer.json | 1 - src/pages/compare/temporal.mdx | 223 ----------------- .../examples/temporal-comparison/client.php | 20 -- .../temporal-comparison/composer.json | 9 - .../examples/temporal-comparison/handlers.php | 26 -- static/examples/temporal-comparison/test.php | 29 --- .../examples/temporal-comparison/worker.php | 19 -- 16 files changed, 590 deletions(-) delete mode 100644 i18n/uk/docusaurus-plugin-content-pages/compare/temporal.mdx delete mode 100644 src/pages/compare/temporal.mdx delete mode 100644 static/examples/temporal-comparison/client.php delete mode 100644 static/examples/temporal-comparison/composer.json delete mode 100644 static/examples/temporal-comparison/handlers.php delete mode 100644 static/examples/temporal-comparison/test.php delete mode 100644 static/examples/temporal-comparison/worker.php diff --git a/.github/workflows/qualification.yml b/.github/workflows/qualification.yml index 0d21f1af620..935a8e43cfa 100644 --- a/.github/workflows/qualification.yml +++ b/.github/workflows/qualification.yml @@ -66,11 +66,5 @@ jobs: cache: npm - name: Install dependencies run: npm ci - - name: Test the published PHP comparison example - run: | - example_dir="$(mktemp -d)" - cp static/examples/temporal-comparison/* "$example_dir/" - composer install --working-dir="$example_dir" --no-interaction --prefer-dist - php "$example_dir/test.php" - name: Build routes and validate links run: npm run build diff --git a/docusaurus.config.js b/docusaurus.config.js index 8d8aad2bfa5..6fc02612276 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -124,18 +124,6 @@ const config = { ], plugins: [ - function executableExamples() { - return { - name: 'executable-code-examples', - configureWebpack() { - return {module: {rules: [{ - test: /\.php$/, - include: require('path').resolve(__dirname, 'static/examples'), - type: 'asset/source', - }]}}; - }, - }; - }, mobileNavigationReachabilityPlugin, [ '@docusaurus/plugin-client-redirects', @@ -257,10 +245,6 @@ const config = { { title: 'More', items: [ - { - label: 'Durable Workflow vs Temporal', - to: '/compare/temporal/', - }, { label: 'LLM Docs', href: 'https://durable-workflow.com/llms-full.txt', diff --git a/i18n/de/docusaurus-theme-classic/footer.json b/i18n/de/docusaurus-theme-classic/footer.json index 4c5fbc7bad1..3b8161b4115 100644 --- a/i18n/de/docusaurus-theme-classic/footer.json +++ b/i18n/de/docusaurus-theme-classic/footer.json @@ -14,9 +14,6 @@ "link.item.label.Installation": { "message": "Installation" }, - "link.item.label.Durable Workflow vs Temporal": { - "message": "Durable Workflow im Vergleich zu Temporal" - }, "link.item.label.LLM Docs": { "message": "Dokumentation für LLMs" } diff --git a/i18n/es/docusaurus-theme-classic/footer.json b/i18n/es/docusaurus-theme-classic/footer.json index 37cc3824d4c..aa6415b3bf5 100644 --- a/i18n/es/docusaurus-theme-classic/footer.json +++ b/i18n/es/docusaurus-theme-classic/footer.json @@ -4,7 +4,6 @@ "link.title.More": {"message": "Más recursos"}, "link.item.label.Introduction": {"message": "Introducción"}, "link.item.label.Installation": {"message": "Instalación"}, - "link.item.label.Durable Workflow vs Temporal": {"message": "Durable Workflow y Temporal"}, "link.item.label.LLM Docs": {"message": "Documentación para LLM"}, "copyright": {"message": "Copyright © 2026 Durable Workflow."} } diff --git a/i18n/fr/docusaurus-theme-classic/footer.json b/i18n/fr/docusaurus-theme-classic/footer.json index a0a63b69f93..f4fe2276842 100644 --- a/i18n/fr/docusaurus-theme-classic/footer.json +++ b/i18n/fr/docusaurus-theme-classic/footer.json @@ -14,9 +14,6 @@ "link.item.label.Installation": { "message": "Installation" }, - "link.item.label.Durable Workflow vs Temporal": { - "message": "Durable Workflow face à Temporal" - }, "link.item.label.LLM Docs": { "message": "Documentation pour les LLM" } diff --git a/i18n/ja/docusaurus-theme-classic/footer.json b/i18n/ja/docusaurus-theme-classic/footer.json index 3c9e0f2cedf..f4e19113652 100644 --- a/i18n/ja/docusaurus-theme-classic/footer.json +++ b/i18n/ja/docusaurus-theme-classic/footer.json @@ -4,6 +4,5 @@ "link.title.More": {"message": "その他"}, "link.item.label.Introduction": {"message": "はじめに"}, "link.item.label.Installation": {"message": "インストール"}, - "link.item.label.Durable Workflow vs Temporal": {"message": "Durable Workflow と Temporal の比較"}, "link.item.label.LLM Docs": {"message": "LLM 向けドキュメント"} } diff --git a/i18n/pt-BR/docusaurus-theme-classic/footer.json b/i18n/pt-BR/docusaurus-theme-classic/footer.json index 33499292e3c..792cb003d86 100644 --- a/i18n/pt-BR/docusaurus-theme-classic/footer.json +++ b/i18n/pt-BR/docusaurus-theme-classic/footer.json @@ -4,7 +4,6 @@ "link.title.More": {"message": "Mais recursos"}, "link.item.label.Introduction": {"message": "Introdução"}, "link.item.label.Installation": {"message": "Instalação"}, - "link.item.label.Durable Workflow vs Temporal": {"message": "Durable Workflow e Temporal"}, "link.item.label.LLM Docs": {"message": "Documentação para LLMs"}, "copyright": {"message": "Copyright © 2026 Durable Workflow."} } diff --git a/i18n/uk/docusaurus-plugin-content-pages/compare/temporal.mdx b/i18n/uk/docusaurus-plugin-content-pages/compare/temporal.mdx deleted file mode 100644 index ba866bcb978..00000000000 --- a/i18n/uk/docusaurus-plugin-content-pages/compare/temporal.mdx +++ /dev/null @@ -1,228 +0,0 @@ ---- -title: Durable Workflow і Temporal -description: "Порівняння Durable Workflow і Temporal: workflow на PHP, Python та Rust, PHP на основі Fiber без RoadRunner, окрема архітектура, відтворення та самостійна експлуатація." -image: /img/durable-workflow-2.0.png ---- - -import CodeBlock from '@theme/CodeBlock'; -import handlers from '@site/static/examples/temporal-comparison/handlers.php'; - -# Durable Workflow і Temporal {#durable-workflow-vs-temporal} - -**Стійке виконання для PHP, Python та Rust на знайомому серверному стеку.** - -Durable Workflow — рушій workflow з відкритим кодом. Ваш застосунок запускає -worker для workflow й activity на PHP, Python або Rust. Server відповідає за -надійне зберігання історії, розподіл завдань, timer та відновлення. Вашому -застосунку Laravel не потрібен. - -Запускайте Server як окремий сервіс із опублікованого контейнера, а застосунок -і worker залишайте у власному мовному середовищі та середовищі розгортання. -Можна використовувати одну мову або поєднувати worker різними мовами. -Розробники PHP отримують workflow на основі Fiber та worker, який запускається -безпосередньо, без RoadRunner. - -Temporal використовує спеціалізований сервіс оркестрації та має ширший вибір SDK. -У PHP його API для workflow використовує генератори, а worker працюють через -RoadRunner. Вибір залежить від потреб застосунку та відповідальності за експлуатацію. - -Обіцянка Durable Workflow — **передбачувана вартість, передбачувана поведінка та -передбачувана експлуатація**: інфраструктура з планованим бюджетом, явні контракти -виконання та історія workflow, яку можна дослідити. - -*Від команди підтримки Durable Workflow. Оновлено 21 вересня 2026 року.* - -## Коротко про архітектуру {#architecture-at-a-glance} - -| Рішення | Durable Workflow | Temporal | -| --- | --- | --- | -| Окреме середовище виконання | Server, незалежний від мови клієнта, реалізований як застосунок Laravel. | Спеціалізований Temporal Service зі сховищами збереження й видимості. | -| Мови SDK | PHP, Python та Rust. | Go, Java, .NET, PHP, Python, Ruby, Rust та TypeScript. | -| Написання PHP-коду | Послідовні методи зі стійкими викликами на основі Fiber та звичайними типами повернення. | Методи workflow на основі генераторів зі стійкими операціями через yield. | -| PHP worker | Безпосередній процес PHP з HTTP-клієнтом. | Процеси PHP під керуванням RoadRunner. | -| Вбудовування в застосунок | Застосунки Laravel можуть запускати рушій у власній базі даних і чергах. | Worker застосунку підключаються до Temporal Service. | - -Джерела: [Durable Workflow Server](/docs/polyglot/server/), -[PHP SDK](https://php.durable-workflow.com/), -[Temporal Service](https://docs.temporal.io/temporal-service), -[workflow на PHP у Temporal](https://docs.temporal.io/develop/php/workflows/basics), -[worker на PHP у Temporal](https://docs.temporal.io/develop/php/workers/run-worker-process) -та [SDK Temporal](https://docs.temporal.io/develop). - -## Один Server, три офіційні SDK {#one-server-three-first-party-sdks} - -Ви можете писати workflow й activity на -[PHP](https://php.durable-workflow.com/), -[Python](https://python.durable-workflow.com/) та -[Rust](https://rust.durable-workflow.com/). Worker працюють у середовищі вашого -застосунку, підключаються до Server та масштабуються незалежно від нього. - -Команда Python може залишити весь застосунок на Python. Команда Rust може -залишити весь застосунок на Rust. Мова реалізації Server не стає залежністю -застосунку. - -Мови можна поєднувати й у межах одного workflow. -[Приклад із запуском кількох мов](https://github.com/durable-workflow/sample-app#service-mode) -використовує workflow на PHP, activity обчислення на Python та activity квитанції -на Rust в окремих чергах завдань. Рушій координує їх через іменовані типи -workflow й activity. - -Temporal пропонує [SDK для ширшого набору мов](https://docs.temporal.io/develop). -Для застосунку на Go, Java, .NET, Ruby або TypeScript така підтримка є конкретною -причиною обрати Temporal. - -## Послідовний PHP-код без RoadRunner {#straight-line-php-without-roadrunner} - -PHP SDK Durable Workflow використовує керований Fiber. Виклик -`$context->activity(...)` призупиняє виконання workflow, доки стійкий результат -не стане доступним. Потім метод продовжується з цим результатом. Ваш workflow -залишається послідовним PHP-методом зі звичайним типом повернення. У коді workflow -не потрібно використовувати `yield` чи типи повернення Generator. - -Worker запускається безпосередньо командою `php worker.php`. Його -[HTTP-транспорт PSR-18](https://github.com/durable-workflow/sdk-php/blob/main/src/Transport/Psr18Transport.php) -не потребує ані RoadRunner, ані розширення gRPC. - -[API workflow на PHP у Temporal](https://docs.temporal.io/develop/php/workflows/basics) -виражає призупинення через генератори й `yield`. Його -[налаштування PHP](https://docs.temporal.io/develop/php/set-up-your-local-php) -включає RoadRunner та розширення gRPC. - -Ось повний файл обробників Durable Workflow **для режиму сервісу**. Workflow -планує activity привітання та повертає її результат: - -{handlers} - -Завантажте [worker, клієнт і тест](https://github.com/durable-workflow/durable-workflow.github.io/tree/main/static/examples/temporal-comparison). -У цьому каталозі, маючи PHP 8.1+ та Composer, виконайте: - -```sh -composer install -php test.php -``` - -Тест перевіряє реєстрацію, планування та виконання activity, а також відтворення -із записаним результатом activity. Щоб запустити worker і клієнт із реальним -середовищем виконання, запустіть [локальний Server](/docs/polyglot/server/) за -адресою `http://localhost:8080` з документованим токеном розробки, а потім -виконайте `php worker.php` та `php client.php` в окремих терміналах: - -```json -{"greeting":"Hello, Ada!"} -``` - -Ми перевірили цей результат з опублікованими SDK та Server. -[Версії та результати тестів](https://github.com/durable-workflow/durable-workflow.github.io/pull/135) -записано разом із вихідним кодом. - -## Передбачувана поведінка між worker {#predictable-behavior-across-workers} - -Обидва рушії відновлюють стан workflow із записаної історії. Результати завершених -activity відтворюються в коді workflow без повторного виконання вже завершеної -роботи. Тому рішення workflow мають залишатися детермінованими: мережеві виклики -та зміни бази даних розміщуйте в activity, а для часу використовуйте стійкі API -timer і часу. Дивіться [модель виконання Durable Workflow](/docs/how-it-works/) -та [відтворення workflow у Temporal](https://docs.temporal.io/workflow-execution#replays). - -Доставка activity — окреме питання. Worker може виконати зовнішню дію та -завершитися з помилкою до повідомлення результату, тож повторна спроба може -повторити цю дію. Durable Workflow надає стабільну логічну ідентичність виконання -activity між спробами. Її можна використовувати як ключ ідемпотентності для -платежів та інших зовнішніх ефектів. -[Гарантії виконання](/docs/constraints/execution-guarantees/) пояснюють цей -контракт. Temporal також рекомендує -[ідемпотентні activity](https://docs.temporal.io/activities). - -### Спільний контракт даних {#a-shared-payload-contract} - -SDK Durable Workflow для PHP, Python та Rust використовують спільний фіксований -[контракт Avro Value](/docs/polyglot/avro-value-protocol/). Він зберігає між мовами -відмінності, зокрема між байтами й текстом та між цілими числами й числами з -рухомою комою. SDK містять схему, тож вам не потрібно експлуатувати реєстр схем. -Об’єкти застосунку адаптуються до цих переносимих значень. - -Temporal використовує [Data Converters](https://docs.temporal.io/dataconversion) -із типовою серіалізацією та підтримкою власних конвертерів і кодеків. Durable -Workflow обирає більш визначений підхід: один переносимий контракт значень -для всіх офіційних SDK. - -Для впевненості в розгортанні перевіряйте зміни workflow на записаній історії, -а також тестуйте бізнес-логіку activity. Durable Workflow надає -[тести відтворення PHP SDK](https://php.durable-workflow.com/build/testing/) та -[тестові підміни вбудованого режиму](/docs/testing/). Temporal документує свої -[засоби модульного та інтеграційного тестування PHP](https://docs.temporal.io/develop/php/best-practices/testing-suite). - -## Самостійне розгортання на знайомому стеку застосунків {#self-host-on-a-familiar-application-stack} - -**Запуск Durable Workflow Server означає запуск застосунку Laravel.** Він -використовує налаштування PHP-застосунку, базу даних, сервіси черг і кешу, а також -процеси worker та планувальника. Оператори, знайомі з Laravel, можуть застосувати -свої навички для розгортання, журналювання, нагляду за процесами та обслуговування -бази даних. - -[Вихідний код Server](https://github.com/durable-workflow/server) та -[посібник із розгортання](/docs/polyglot/server/) дозволяють дослідити це -налаштування. Опублікований Docker-образ уже містить застосунок. Його використання -не вимагає PHP чи Laravel у середовищі ваших worker на Python або Rust. - -| Розгортання | Що ви експлуатуєте | -| --- | --- | -| Durable Workflow Server | Застосунок Laravel із процесами API, worker і планувальника, сервіси бази даних, черг і кешу, а також SDK worker застосунку. | -| Вбудований Durable Workflow | Ваш застосунок Laravel, базу даних, споживачів черг та кеш із підтримкою блокувань. | -| Temporal Service | Temporal Server, сховища збереження й видимості, а також SDK worker застосунку. | - -[Опубліковане налаштування Compose](/docs/polyglot/server/#published-image--compose) -для Durable Workflow використовує MySQL та Redis. Локальний швидкий старт також -підтримує SQLite. -[Посібник із самостійного розгортання Temporal](https://docs.temporal.io/self-hosted-guide) -описує варіанти розгортання. Локальний сервіс розробки доступний через Temporal CLI. - -**Передбачувана вартість випливає з явної відповідальності.** -[Рушій Durable Workflow](https://github.com/durable-workflow/workflow/blob/main/LICENSE), -[Server](https://github.com/durable-workflow/server/blob/main/LICENSE) та -[Temporal Server](https://github.com/temporalio/temporal/blob/main/LICENSE) -мають ліцензію MIT. Самостійне розгортання будь-якого рушія не передбачає плати за -кожну дію в програмному забезпеченні. Ваші витрати — це інфраструктура та її -експлуатація. Durable Workflow дозволяє використовувати усталені інструменти -PHP-застосунків і незалежно масштабувати worker мовою вашого застосунку. - -### Дослідження історії workflow {#inspect-workflow-history} - -[Waterline](/docs/monitoring/) показує історію виконання Durable Workflow, -результати activity, timer та помилки. Він може працювати як окремий -операторський інтерфейс для Server або всередині застосунку Laravel для -вбудованого виконання. CLI та Server API також відкривають стан середовища -виконання. Temporal надає [вебінтерфейс](https://docs.temporal.io/web-ui) для -дослідження виконань та історії. - -### Інтеграція з Laravel, якщо застосунок використовує Laravel {#laravel-integration-when-your-application-uses-laravel} - -Користувачі Laravel мають два варіанти: вбудувати рушій або залишити окремий -Server і використовувати -[міст Laravel у PHP SDK](https://php.durable-workflow.com/frameworks/laravel/). -Міст надає обробники, які отримуються з контейнера, налаштування, журналювання, -команду Artisan для worker та тестову підміну. Відокремлення стану оркестрації -не вимагає відмовлятися від звичних правил фреймворку застосунку. - -Вбудовування йде далі: стан workflow зберігається в базі даних застосунку, а -worker черг Laravel виконують роботу. Ви розгортаєте рушій разом із застосунком, -замість експлуатації окремого сервісу. Почніть із -[посібника встановлення вбудованого режиму](/docs/installation/). - -## Який рушій підходить вашій команді? {#which-engine-fits-your-team} - -**Обирайте Durable Workflow** для застосунків на PHP, Python та Rust, якщо вам -потрібен рушій для самостійного розгортання зі спільним міжмовним контрактом -виконання та незалежно розгорнутими worker застосунку. Команди PHP також -отримують workflow на основі Fiber без RoadRunner і необов’язкову інтеграцію -з Laravel. - -**Обирайте Temporal**, якщо його ширша підтримка мов у SDK або ваші наявні -інструменти та досвід Temporal краще відповідають застосунку. - -**Почніть розробку:** [оберіть швидкий старт для PHP, Python чи Rust](/docs/quickstart/), -[запустіть Durable Workflow Server](/docs/polyglot/server/) або -[дослідіть SDK Temporal](https://docs.temporal.io/develop). - -Знайшли фактичну помилку? [Створіть issue документації](https://github.com/durable-workflow/durable-workflow.github.io/issues/new) -і вкажіть твердження та його джерело. diff --git a/i18n/uk/docusaurus-theme-classic/footer.json b/i18n/uk/docusaurus-theme-classic/footer.json index 1b3b8b0cef5..f35540cd497 100644 --- a/i18n/uk/docusaurus-theme-classic/footer.json +++ b/i18n/uk/docusaurus-theme-classic/footer.json @@ -27,10 +27,6 @@ "message": "X", "description": "The label of footer link with label=X linking to https://x.com/DurableWorkflow" }, - "link.item.label.Durable Workflow vs Temporal": { - "message": "Durable Workflow і Temporal", - "description": "The label of footer link with label=Durable Workflow vs Temporal linking to /compare/temporal/" - }, "link.item.label.LLM Docs": { "message": "Документація для LLM", "description": "The label of footer link with label=LLM Docs linking to https://durable-workflow.com/llms-full.txt" diff --git a/i18n/zh-Hans/docusaurus-theme-classic/footer.json b/i18n/zh-Hans/docusaurus-theme-classic/footer.json index 7550943fffa..80d2ec87d3e 100644 --- a/i18n/zh-Hans/docusaurus-theme-classic/footer.json +++ b/i18n/zh-Hans/docusaurus-theme-classic/footer.json @@ -4,6 +4,5 @@ "link.title.More": {"message": "更多"}, "link.item.label.Introduction": {"message": "简介"}, "link.item.label.Installation": {"message": "安装"}, - "link.item.label.Durable Workflow vs Temporal": {"message": "Durable Workflow 与 Temporal 对比"}, "link.item.label.LLM Docs": {"message": "LLM 文档"} } diff --git a/src/pages/compare/temporal.mdx b/src/pages/compare/temporal.mdx deleted file mode 100644 index 6c9c40b94f0..00000000000 --- a/src/pages/compare/temporal.mdx +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: Durable Workflow vs Temporal -description: "Compare Durable Workflow and Temporal: PHP, Python, and Rust workflows, Fiber-based PHP without RoadRunner, standalone architecture, replay, and self-hosted operations." -image: /img/durable-workflow-2.0.png ---- - -import CodeBlock from '@theme/CodeBlock'; -import handlers from '@site/static/examples/temporal-comparison/handlers.php'; - -# Durable Workflow vs Temporal - -**Durable execution for PHP, Python, and Rust, on a familiar server stack.** - -Durable Workflow is an open-source workflow engine. Your application runs -workflow and activity workers in PHP, Python, or Rust; Server handles durable -history, task dispatch, timers, and recovery. Your application does not need -Laravel. - -Run Server as a separate service using the published container, and keep your -application and workers in their own language and deployment environment. You -can use one language throughout or combine workers across languages. PHP -developers get Fiber-based workflows and a directly runnable worker, without -RoadRunner. - -Temporal uses a dedicated orchestration service, with a broader SDK selection. -For PHP, its workflow API uses generators and its workers run through RoadRunner. -The choice is about application fit and operational ownership. - -Durable Workflow's promise is **predictable cost, predictable behavior, and -predictable operations**: infrastructure you can budget for, explicit execution -contracts, and workflow history you can inspect. - -*By the Durable Workflow maintainers. Updated September 21, 2026.* - -## Architecture at a glance - -| Decision | Durable Workflow | Temporal | -| --- | --- | --- | -| Standalone runtime | Language-neutral Server implemented as a Laravel application. | Dedicated Temporal Service with persistence and visibility stores. | -| SDK languages | PHP, Python, and Rust. | Go, Java, .NET, PHP, Python, Ruby, Rust, and TypeScript. | -| PHP authoring | Straight-line methods with Fiber-backed durable calls and ordinary return types. | Generator-based workflow methods with yielded durable operations. | -| PHP worker | Direct PHP process using an HTTP client. | PHP processes managed through RoadRunner. | -| Application embedding | Laravel apps can run the engine in their own database and queues. | Application workers connect to Temporal Service. | - -Sources: [Durable Workflow Server](/docs/polyglot/server/), -[PHP SDK](https://php.durable-workflow.com/), -[Temporal Service](https://docs.temporal.io/temporal-service), -[Temporal PHP workflows](https://docs.temporal.io/develop/php/workflows/basics), -[Temporal PHP workers](https://docs.temporal.io/develop/php/workers/run-worker-process), -and [Temporal SDKs](https://docs.temporal.io/develop). - -## One Server, three first-party SDKs - -You can author both workflows and activities in -[PHP](https://php.durable-workflow.com/), -[Python](https://python.durable-workflow.com/), and -[Rust](https://rust.durable-workflow.com/). Workers run in your application's -environment, connect to Server, and scale independently from it. - -A Python team can keep its application entirely in Python. A Rust team can keep -its application entirely in Rust. Server's implementation language does not -become an application dependency. - -You can also combine languages in one workflow. The -[runnable polyglot example](https://github.com/durable-workflow/sample-app#service-mode) -uses a PHP workflow, a Python calculation activity, and a Rust receipt activity -on separate task queues. The engine coordinates them through named workflow and -activity types. - -Temporal offers [SDKs for a wider set of languages](https://docs.temporal.io/develop). -For an application built around Go, Java, .NET, Ruby, or TypeScript, that coverage -is a concrete reason to choose Temporal. - -## Straight-line PHP, without RoadRunner - -Durable Workflow's PHP SDK uses a managed Fiber. Calling -`$context->activity(...)` suspends workflow execution until the durable result is -available; the method then continues with that result. Your workflow remains a -straight-line PHP method with an ordinary return type. There are no `yield` -statements or Generator return types to carry through your workflow code. - -The worker runs directly as `php worker.php`. Its -[PSR-18 HTTP transport](https://github.com/durable-workflow/sdk-php/blob/main/src/Transport/Psr18Transport.php) -requires neither RoadRunner nor a gRPC extension. - -Temporal's [PHP workflow API](https://docs.temporal.io/develop/php/workflows/basics) -expresses suspension through generators and `yield`. Its -[PHP setup](https://docs.temporal.io/develop/php/set-up-your-local-php) -includes RoadRunner and the gRPC extension. - -Here is a complete Durable Workflow **service-mode** handler file. The workflow -schedules a greeting activity and returns its result: - -{handlers} - -Get the [worker, client, and test](https://github.com/durable-workflow/durable-workflow.github.io/tree/main/static/examples/temporal-comparison). -In that directory, with PHP 8.1+ and Composer: - -```sh -composer install -php test.php -``` - -The test checks registration, activity scheduling and execution, and replay with -a recorded activity result. To run the worker and client against a real runtime, -start the [local Server](/docs/polyglot/server/) at `http://localhost:8080` with -its documented development token, then run `php worker.php` and `php client.php` -in separate terminals: - -```json -{"greeting":"Hello, Ada!"} -``` - -We verified this result with published SDK and Server artifacts. -[Versions and test results](https://github.com/durable-workflow/durable-workflow.github.io/pull/135) -are recorded with the source. - -## Predictable behavior across workers - -Both engines rebuild workflow state from recorded history. Completed activity -results are replayed into workflow code rather than repeating that completed -work. Workflow decisions therefore need to remain deterministic: put network -calls and database effects in activities, and use durable timer and time APIs. -See [Durable Workflow's execution model](/docs/how-it-works/) and -[Temporal workflow replay](https://docs.temporal.io/workflow-execution#replays). - -Activity delivery is a separate concern. A worker can perform an external action -and fail before reporting its result, so a retry may repeat that action. Durable -Workflow provides a stable logical activity execution identity across attempts, -which can serve as an idempotency key for payments and other external effects. -The [execution guarantees](/docs/constraints/execution-guarantees/) explain that -contract. Temporal also recommends -[idempotent activities](https://docs.temporal.io/activities). - -### A shared payload contract - -Durable Workflow's PHP, Python, and Rust SDKs share a fixed -[Avro Value contract](/docs/polyglot/avro-value-protocol/). It preserves distinctions -such as bytes versus text and integers versus floating-point values across -languages. The SDKs bundle the schema; you do not operate a schema registry. -Application-specific objects are adapted to these portable values. - -Temporal uses [Data Converters](https://docs.temporal.io/dataconversion) with -default serialization and support for custom converters and codecs. Durable -Workflow takes a more opinionated approach: one portable value contract across -its first-party SDKs. - -For deployment confidence, test workflow changes against recorded history as -well as testing activity business logic. Durable Workflow provides -[PHP SDK replay tests](https://php.durable-workflow.com/build/testing/) and -[embedded test fakes](/docs/testing/). Temporal documents its -[PHP unit and integration testing tools](https://docs.temporal.io/develop/php/best-practices/testing-suite). - -## Self-host on a familiar application stack - -**Running Durable Workflow Server means running a Laravel application.** It uses -PHP application configuration, a database, queue/cache services, and worker and -scheduler processes. Operators familiar with Laravel can use those skills for -deployment, logs, process supervision, and database maintenance. - -The [Server source](https://github.com/durable-workflow/server) and -[deployment guide](/docs/polyglot/server/) make that setup inspectable. The -published Docker image packages the application for you. Using it does not -require PHP or Laravel in your Python or Rust worker environment. - -| Deployment | What you operate | -| --- | --- | -| Durable Workflow Server | A Laravel application with API, worker and scheduler processes, database and queue/cache services, plus application SDK workers. | -| Durable Workflow embedded | Your Laravel app, database, queue consumers, and lock-capable cache. | -| Temporal Service | Temporal Server, persistence and visibility stores, plus application SDK workers. | - -The Durable Workflow [published Compose setup](/docs/polyglot/server/#published-image--compose) -uses MySQL and Redis. Its local quickstart also supports SQLite. -Temporal's [self-hosting guide](https://docs.temporal.io/self-hosted-guide) -covers its deployment options, with a local development service available through -the Temporal CLI. - -**Predictable cost follows from explicit ownership.** The -[Durable Workflow engine](https://github.com/durable-workflow/workflow/blob/main/LICENSE), -[Server](https://github.com/durable-workflow/server/blob/main/LICENSE), and -[Temporal Server](https://github.com/temporalio/temporal/blob/main/LICENSE) -are MIT-licensed. Self-hosting either engine has no per-action software fee. -Your costs are infrastructure and the work of operating it. Durable Workflow -lets you use established PHP application tooling, while independently scaling -workers written in your application's language. - -### Inspect workflow history - -[Waterline](/docs/monitoring/) shows Durable Workflow execution history, -activity results, timers, and failures. It can run as a separate operator UI -for Server, or inside a Laravel app for embedded execution. The CLI and Server -API also expose runtime state. Temporal provides its -[Web UI](https://docs.temporal.io/web-ui) for inspecting executions and history. - -### Laravel integration when your application uses Laravel - -Laravel users get two choices: embed the engine, or keep a separate Server and -use the [PHP SDK's Laravel bridge](https://php.durable-workflow.com/frameworks/laravel/). -The bridge supplies container-resolved handlers, configuration, logging, an -Artisan worker command, and a test fake. Separating orchestration state does not -require abandoning the application's framework conventions. - -Embedding goes further: workflow state lives in the application's database, and -Laravel queue workers execute the work. You deploy the engine with your app -instead of operating a separate service. Start with the -[embedded installation guide](/docs/installation/). - -## Which engine fits your team? - -**Choose Durable Workflow** for PHP, Python, and Rust applications when you want -a self-hostable engine with a shared cross-language execution contract and -independently deployed application workers. PHP teams also get Fiber-based -workflow code without RoadRunner, with optional Laravel integration. - -**Choose Temporal** when its broader language SDK coverage or your existing -Temporal tooling and expertise fit the application better. - -**Start building:** [choose a PHP, Python, or Rust quickstart](/docs/quickstart/), -[run Durable Workflow Server](/docs/polyglot/server/), or -[explore Temporal's SDKs](https://docs.temporal.io/develop). - -Found a factual error? [Open a documentation issue](https://github.com/durable-workflow/durable-workflow.github.io/issues/new) -with the claim and its source. diff --git a/static/examples/temporal-comparison/client.php b/static/examples/temporal-comparison/client.php deleted file mode 100644 index cc345cc258a..00000000000 --- a/static/examples/temporal-comparison/client.php +++ /dev/null @@ -1,20 +0,0 @@ -startWorkflow( - workflowType: 'comparison.php.greeting', - workflowId: 'comparison-'.bin2hex(random_bytes(8)), - taskQueue: 'comparison-php', - input: ['Ada'], -); -echo json_encode($handle->result(timeoutSeconds: 60), JSON_THROW_ON_ERROR).PHP_EOL; diff --git a/static/examples/temporal-comparison/composer.json b/static/examples/temporal-comparison/composer.json deleted file mode 100644 index 55683064d53..00000000000 --- a/static/examples/temporal-comparison/composer.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "durable-workflow/comparison-example", - "description": "Runnable PHP example for the Durable Workflow and Temporal comparison", - "type": "project", - "require": { - "php": "^8.1", - "durable-workflow/sdk": "^2.0" - } -} diff --git a/static/examples/temporal-comparison/handlers.php b/static/examples/temporal-comparison/handlers.php deleted file mode 100644 index 521abe1d80e..00000000000 --- a/static/examples/temporal-comparison/handlers.php +++ /dev/null @@ -1,26 +0,0 @@ - $context->activity('comparison.php.greet', [$name])]; - } -} - -final class GreetingActivities -{ - #[Activity('comparison.php.greet')] - public function greet(ActivityContext $context, string $name): string - { - return "Hello, {$name}!"; - } -} diff --git a/static/examples/temporal-comparison/test.php b/static/examples/temporal-comparison/test.php deleted file mode 100644 index 2108f0f05ce..00000000000 --- a/static/examples/temporal-comparison/test.php +++ /dev/null @@ -1,29 +0,0 @@ -register(GreetingWorkflow::class, GreetingActivities::class); -$harness = new WorkerTestHarness($worker); -$harness->assertWorkflowEmits('comparison.php.greeting', 'schedule_activity', ['Ada']); -$harness->assertActivityResult('comparison.php.greet', 'Hello, Ada!', ['Ada']); -$codec = $client->payloadCodec(); -$replay = $harness->runWorkflow('comparison.php.greeting', ['Ada'], [ - ['event_type' => 'ActivityScheduled', 'payload' => ['sequence' => 1, 'activity_type' => 'comparison.php.greet']], - ['event_type' => 'ActivityCompleted', 'payload' => ['sequence' => 1, 'result' => $codec->envelope('Hello, Ada!')]], -]); -if (($replay->commands[0]['type'] ?? null) !== 'complete_workflow' - || $codec->decodeEnvelope($replay->commands[0]['result']) !== ['greeting' => 'Hello, Ada!']) { - throw new RuntimeException('The workflow did not replay to the expected result.'); -} -echo "PASS: registration, activity scheduling, activity result, and completed-history replay.\n"; diff --git a/static/examples/temporal-comparison/worker.php b/static/examples/temporal-comparison/worker.php deleted file mode 100644 index 39bc454e840..00000000000 --- a/static/examples/temporal-comparison/worker.php +++ /dev/null @@ -1,19 +0,0 @@ -register(GreetingWorkflow::class, GreetingActivities::class) - ->run();