[PR #378] Fix DBOS non-determinism #380

Open
opened 2026-02-16 02:17:23 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/run-llama/workflows-py/pull/378
Author: @adrianlyjak
Created: 2/12/2026
Status: 🔄 Open

Base: devHead: adrian/non-determinism


📝 Commits (5)

  • 3ca5607 debug
  • eeb4a37 Switch to a task execution model more controled by the runtime
  • 64c2cb3 remove debugs
  • 27b3437 Refactor named task/pull task
  • 7aa699c Move task execution into runtime for determinism control

📊 Changes

8 files changed (+317 additions, -237 deletions)

View changed files

.changeset/proud-mugs-heal.md (+7 -0)
📝 packages/llama-agents-dbos/src/llama_agents/dbos/runtime.py (+35 -31)
📝 packages/llama-agents-dbos/tests/test_dbos_runtime.py (+4 -3)
📝 packages/llama-agents-server/src/llama_agents/server/_runtime/runtime_decorators.py (+6 -5)
📝 packages/llama-index-workflows/src/workflows/runtime/control_loop.py (+52 -36)
📝 packages/llama-index-workflows/src/workflows/runtime/types/named_task.py (+100 -60)
📝 packages/llama-index-workflows/src/workflows/runtime/types/plugin.py (+33 -27)
📝 packages/llama-index-workflows/tests/runtime/test_named_task.py (+80 -75)

📄 Description

Summary

Refactors task lifecycle management so that the InternalRunAdapter controls when worker and pull coroutines are started, rather than the control loop starting them eagerly as asyncio.Tasks.

Previously, workers were started immediately and gated with an asyncio.Event to prevent interleaving with the main loop's DBOS operations. This was fragile because it relied on timing to ensure deterministic function_id ordering during DBOS replay.

Now:

  • Worker coroutines are collected as PendingStart objects instead of being started immediately
  • wait_for_next_task receives both running (already-started) tasks and pending (not-yet-started) coroutines
  • The adapter starts each pending coroutine with an asyncio.sleep(0) between them, ensuring deterministic DBOS function_id acquisition order
  • Returns a WaitForNextTaskResult containing both the completed task and the newly started NamedTasks

This gives DBOS (and any future durable adapter) full control over task startup ordering without requiring synchronization primitives in the control loop.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/run-llama/workflows-py/pull/378 **Author:** [@adrianlyjak](https://github.com/adrianlyjak) **Created:** 2/12/2026 **Status:** 🔄 Open **Base:** `dev` ← **Head:** `adrian/non-determinism` --- ### 📝 Commits (5) - [`3ca5607`](https://github.com/run-llama/workflows-py/commit/3ca560700fdeb134aa2f4d46eb13de537d645ae0) debug - [`eeb4a37`](https://github.com/run-llama/workflows-py/commit/eeb4a374b427af4f140b1e5566a1b035f190c4f7) Switch to a task execution model more controled by the runtime - [`64c2cb3`](https://github.com/run-llama/workflows-py/commit/64c2cb3266a4e13100b61c97fc37e168adae0edd) remove debugs - [`27b3437`](https://github.com/run-llama/workflows-py/commit/27b3437d8e45aa7e60347be857c7db9eb1ff1956) Refactor named task/pull task - [`7aa699c`](https://github.com/run-llama/workflows-py/commit/7aa699c14771f0319c10e3edccb02f68ea3ed1dd) Move task execution into runtime for determinism control ### 📊 Changes **8 files changed** (+317 additions, -237 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/proud-mugs-heal.md` (+7 -0) 📝 `packages/llama-agents-dbos/src/llama_agents/dbos/runtime.py` (+35 -31) 📝 `packages/llama-agents-dbos/tests/test_dbos_runtime.py` (+4 -3) 📝 `packages/llama-agents-server/src/llama_agents/server/_runtime/runtime_decorators.py` (+6 -5) 📝 `packages/llama-index-workflows/src/workflows/runtime/control_loop.py` (+52 -36) 📝 `packages/llama-index-workflows/src/workflows/runtime/types/named_task.py` (+100 -60) 📝 `packages/llama-index-workflows/src/workflows/runtime/types/plugin.py` (+33 -27) 📝 `packages/llama-index-workflows/tests/runtime/test_named_task.py` (+80 -75) </details> ### 📄 Description ## Summary Refactors task lifecycle management so that the `InternalRunAdapter` controls when worker and pull coroutines are started, rather than the control loop starting them eagerly as `asyncio.Task`s. Previously, workers were started immediately and gated with an `asyncio.Event` to prevent interleaving with the main loop's DBOS operations. This was fragile because it relied on timing to ensure deterministic function_id ordering during DBOS replay. Now: - Worker coroutines are collected as `PendingStart` objects instead of being started immediately - `wait_for_next_task` receives both `running` (already-started) tasks and `pending` (not-yet-started) coroutines - The adapter starts each pending coroutine with an `asyncio.sleep(0)` between them, ensuring deterministic DBOS function_id acquisition order - Returns a `WaitForNextTaskResult` containing both the completed task and the newly started `NamedTask`s This gives DBOS (and any future durable adapter) full control over task startup ordering without requiring synchronization primitives in the control loop. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-16 02:17:23 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: run-llama/workflows-py#380