edda-framework 0.14.0__tar.gz → 0.14.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. {edda_framework-0.14.0 → edda_framework-0.14.1}/PKG-INFO +1 -1
  2. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/app.py +6 -21
  3. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/locking.py +12 -37
  4. {edda_framework-0.14.0 → edda_framework-0.14.1}/pyproject.toml +1 -1
  5. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_cross_language_channel.py +637 -0
  6. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_stale_workflow_recovery.py +0 -3
  7. {edda_framework-0.14.0 → edda_framework-0.14.1}/uv.lock +1 -1
  8. {edda_framework-0.14.0 → edda_framework-0.14.1}/.github/workflows/ci.yml +0 -0
  9. {edda_framework-0.14.0 → edda_framework-0.14.1}/.github/workflows/docs.yml +0 -0
  10. {edda_framework-0.14.0 → edda_framework-0.14.1}/.github/workflows/release.yml +0 -0
  11. {edda_framework-0.14.0 → edda_framework-0.14.1}/.gitignore +0 -0
  12. {edda_framework-0.14.0 → edda_framework-0.14.1}/.gitmodules +0 -0
  13. {edda_framework-0.14.0 → edda_framework-0.14.1}/.python-version +0 -0
  14. {edda_framework-0.14.0 → edda_framework-0.14.1}/Justfile +0 -0
  15. {edda_framework-0.14.0 → edda_framework-0.14.1}/LICENSE +0 -0
  16. {edda_framework-0.14.0 → edda_framework-0.14.1}/README.md +0 -0
  17. {edda_framework-0.14.0 → edda_framework-0.14.1}/demo_app.py +0 -0
  18. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/api/reference.md +0 -0
  19. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/durable-execution/replay.md +0 -0
  20. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/events/cloudevents-http-binding.md +0 -0
  21. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/events/postgres-notify.md +0 -0
  22. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/events/wait-event.md +0 -0
  23. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/hooks.md +0 -0
  24. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/messages.md +0 -0
  25. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/retry.md +0 -0
  26. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/saga-compensation.md +0 -0
  27. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/transactional-outbox.md +0 -0
  28. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/core-features/workflows-activities.md +0 -0
  29. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/examples/ecommerce.md +0 -0
  30. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/examples/events.md +0 -0
  31. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/examples/fastapi-integration.md +0 -0
  32. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/examples/saga.md +0 -0
  33. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/examples/simple.md +0 -0
  34. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/getting-started/concepts.md +0 -0
  35. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/getting-started/first-workflow.md +0 -0
  36. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/getting-started/installation.md +0 -0
  37. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/getting-started/quick-start.md +0 -0
  38. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/index.md +0 -0
  39. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/integrations/mcp.md +0 -0
  40. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/integrations/mirascope.md +0 -0
  41. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/integrations/opentelemetry.md +0 -0
  42. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/integrations/pydantic-rpc.md +0 -0
  43. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/cloudevents-cli-trigger.png +0 -0
  44. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/compensation-execution.png +0 -0
  45. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/detail-page-loan-approval.png +0 -0
  46. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/detail-page-match-case.png +0 -0
  47. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/nested-pydantic-form.png +0 -0
  48. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/start-workflow-form-pydantic.png +0 -0
  49. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/wait-event-visualization.png +0 -0
  50. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/workflow-list-view.png +0 -0
  51. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/images/workflow-selection-dropdown.png +0 -0
  52. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/setup.md +0 -0
  53. {edda_framework-0.14.0 → edda_framework-0.14.1}/docs/viewer-ui/visualization.md +0 -0
  54. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/__init__.py +0 -0
  55. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/activity.py +0 -0
  56. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/channels.py +0 -0
  57. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/compensation.py +0 -0
  58. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/context.py +0 -0
  59. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/exceptions.py +0 -0
  60. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/hooks.py +0 -0
  61. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/__init__.py +0 -0
  62. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mcp/__init__.py +0 -0
  63. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mcp/decorators.py +0 -0
  64. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mcp/server.py +0 -0
  65. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mirascope/__init__.py +0 -0
  66. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mirascope/agent.py +0 -0
  67. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mirascope/call.py +0 -0
  68. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mirascope/decorator.py +0 -0
  69. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/mirascope/types.py +0 -0
  70. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/opentelemetry/__init__.py +0 -0
  71. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/integrations/opentelemetry/hooks.py +0 -0
  72. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/migrations/mysql/20251217000000_initial_schema.sql +0 -0
  73. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/migrations/postgresql/20251217000000_initial_schema.sql +0 -0
  74. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/migrations/sqlite/20251217000000_initial_schema.sql +0 -0
  75. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/outbox/__init__.py +0 -0
  76. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/outbox/relayer.py +0 -0
  77. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/outbox/transactional.py +0 -0
  78. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/pydantic_utils.py +0 -0
  79. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/replay.py +0 -0
  80. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/retry.py +0 -0
  81. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/serialization/__init__.py +0 -0
  82. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/serialization/base.py +0 -0
  83. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/serialization/json.py +0 -0
  84. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/storage/__init__.py +0 -0
  85. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/storage/migrations.py +0 -0
  86. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/storage/models.py +0 -0
  87. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/storage/notify_base.py +0 -0
  88. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/storage/pg_notify.py +0 -0
  89. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/storage/protocol.py +0 -0
  90. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/storage/sqlalchemy_storage.py +0 -0
  91. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/viewer_ui/__init__.py +0 -0
  92. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/viewer_ui/app.py +0 -0
  93. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/viewer_ui/components.py +0 -0
  94. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/viewer_ui/data_service.py +0 -0
  95. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/viewer_ui/theme.py +0 -0
  96. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/visualizer/__init__.py +0 -0
  97. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/visualizer/ast_analyzer.py +0 -0
  98. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/visualizer/mermaid_generator.py +0 -0
  99. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/workflow.py +0 -0
  100. {edda_framework-0.14.0 → edda_framework-0.14.1}/edda/wsgi.py +0 -0
  101. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/__init__.py +0 -0
  102. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/cancellable_workflow.py +0 -0
  103. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/compensation_workflow.py +0 -0
  104. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/event_waiting_app.py +0 -0
  105. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/event_waiting_workflow.py +0 -0
  106. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/event_waiting_workflow_complete.py +0 -0
  107. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/long_running_loop.py +0 -0
  108. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mcp/README.md +0 -0
  109. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mcp/order_processing_mcp.py +0 -0
  110. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mcp/prompts_example.py +0 -0
  111. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mcp/remote_server_example.py +0 -0
  112. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mcp/simple_mcp_server.py +0 -0
  113. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/message_passing.py +0 -0
  114. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mirascope/__init__.py +0 -0
  115. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mirascope/durable_agent.py +0 -0
  116. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mirascope/multi_turn.py +0 -0
  117. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mirascope/simple_call.py +0 -0
  118. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/mirascope/with_tools.py +0 -0
  119. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/observability_with_logfire.py +0 -0
  120. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/observability_with_opentelemetry.py +0 -0
  121. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/pydantic_rpc_integration.py +0 -0
  122. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/pydantic_saga.py +0 -0
  123. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/retry_example.py +0 -0
  124. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/retry_with_compensation.py +0 -0
  125. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/simple_workflow.py +0 -0
  126. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/typeddict_example.py +0 -0
  127. {edda_framework-0.14.0 → edda_framework-0.14.1}/examples/with_outbox.py +0 -0
  128. {edda_framework-0.14.0 → edda_framework-0.14.1}/schema/.dbmate.yml +0 -0
  129. {edda_framework-0.14.0 → edda_framework-0.14.1}/schema/.git +0 -0
  130. {edda_framework-0.14.0 → edda_framework-0.14.1}/schema/.gitignore +0 -0
  131. {edda_framework-0.14.0 → edda_framework-0.14.1}/schema/LICENSE +0 -0
  132. {edda_framework-0.14.0 → edda_framework-0.14.1}/schema/README.md +0 -0
  133. {edda_framework-0.14.0 → edda_framework-0.14.1}/schema/docs/column-values.md +0 -0
  134. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/__init__.py +0 -0
  135. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/conftest.py +0 -0
  136. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/__init__.py +0 -0
  137. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mcp/__init__.py +0 -0
  138. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mcp/test_cancel.py +0 -0
  139. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mcp/test_integration.py +0 -0
  140. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mcp/test_jsonrpc.py +0 -0
  141. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mcp/test_prompts.py +0 -0
  142. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mcp/test_server.py +0 -0
  143. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mirascope/__init__.py +0 -0
  144. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mirascope/test_agent.py +0 -0
  145. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mirascope/test_call.py +0 -0
  146. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mirascope/test_decorator.py +0 -0
  147. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/mirascope/test_types.py +0 -0
  148. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/opentelemetry/__init__.py +0 -0
  149. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/integrations/opentelemetry/test_hooks.py +0 -0
  150. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_activity.py +0 -0
  151. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_activity_retry.py +0 -0
  152. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_activity_sync.py +0 -0
  153. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_app.py +0 -0
  154. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_ast_analyzer.py +0 -0
  155. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_atomic_wait_event.py +0 -0
  156. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_auto_migration.py +0 -0
  157. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_binary_data.py +0 -0
  158. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_channel_competing.py +0 -0
  159. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_channel_direct.py +0 -0
  160. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_channel_mode_locking.py +0 -0
  161. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_channel_transactional.py +0 -0
  162. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_cloudevents_http_binding.py +0 -0
  163. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_compensation.py +0 -0
  164. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_compensation_crash_recovery.py.wip +0 -0
  165. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_concurrent_outbox.py +0 -0
  166. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_context.py +0 -0
  167. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_ctx_session.py +0 -0
  168. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_distributed_event_delivery.py +0 -0
  169. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_events.py +0 -0
  170. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_instance_id_routing.py +0 -0
  171. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_lock_race_condition.py +0 -0
  172. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_lock_timeout_customization.py +0 -0
  173. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_locking.py +0 -0
  174. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_message_cleanup.py +0 -0
  175. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_message_delivery_lock.py +0 -0
  176. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_messages.py +0 -0
  177. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_migrations_integration.py +0 -0
  178. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_multidb_storage.py +0 -0
  179. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_outbox.py +0 -0
  180. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_pg_notify.py +0 -0
  181. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_polling_optimization.py +0 -0
  182. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_pydantic_activity.py +0 -0
  183. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_pydantic_enum.py +0 -0
  184. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_pydantic_events.py +0 -0
  185. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_pydantic_saga.py +0 -0
  186. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_pydantic_utils.py +0 -0
  187. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_receive_timeout.py +0 -0
  188. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_received_event.py +0 -0
  189. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_recur.py +0 -0
  190. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_recur_cleanup.py +0 -0
  191. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_replay.py +0 -0
  192. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_retry_policy.py +0 -0
  193. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_saga_parameter_extraction.py +0 -0
  194. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_serialization.py +0 -0
  195. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_skip_locked.py +0 -0
  196. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_storage.py +0 -0
  197. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_storage_mysql.py +0 -0
  198. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_storage_postgresql.py +0 -0
  199. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_transactions.py +0 -0
  200. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_viewer_pagination.py +0 -0
  201. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_viewer_pydantic_form.py +0 -0
  202. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_viewer_start_saga.py +0 -0
  203. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_wait_timer.py +0 -0
  204. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_workflow.py +0 -0
  205. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_workflow_auto_register.py +0 -0
  206. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_workflow_cancellation.py +0 -0
  207. {edda_framework-0.14.0 → edda_framework-0.14.1}/tests/test_workflow_resumption.py +0 -0
  208. {edda_framework-0.14.0 → edda_framework-0.14.1}/viewer_app.py +0 -0
  209. {edda_framework-0.14.0 → edda_framework-0.14.1}/zensical.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edda-framework
3
- Version: 0.14.0
3
+ Version: 0.14.1
4
4
  Summary: Lightweight Durable Execution Framework
5
5
  Project-URL: Homepage, https://github.com/i2y/edda
6
6
  Project-URL: Documentation, https://github.com/i2y/edda#readme
@@ -583,7 +583,6 @@ class EddaApp:
583
583
  auto_resume_stale_workflows_periodically(
584
584
  self.storage,
585
585
  self.replay_engine,
586
- self.worker_id,
587
586
  interval=60,
588
587
  ),
589
588
  name="leader_stale_workflow_resume",
@@ -628,7 +627,6 @@ class EddaApp:
628
627
  auto_resume_stale_workflows_periodically(
629
628
  self.storage,
630
629
  self.replay_engine,
631
- self.worker_id,
632
630
  interval=60,
633
631
  ),
634
632
  name="leader_stale_workflow_resume",
@@ -1411,7 +1409,8 @@ class EddaApp:
1411
1409
  from growing indefinitely with orphaned messages (messages that were
1412
1410
  published but never received by any subscriber).
1413
1411
 
1414
- Uses system-level locking to ensure only one pod executes cleanup at a time.
1412
+ Important: This task should only be run by a single worker (e.g., via leader
1413
+ election). It does not perform its own distributed coordination.
1415
1414
 
1416
1415
  Args:
1417
1416
  interval: Cleanup interval in seconds (default: 3600 = 1 hour)
@@ -1422,27 +1421,13 @@ class EddaApp:
1422
1421
  """
1423
1422
  while True:
1424
1423
  try:
1425
- # Add jitter to prevent thundering herd in multi-pod deployments
1424
+ # Add jitter to prevent thundering herd
1426
1425
  jitter = random.uniform(0, interval * 0.3)
1427
1426
  await asyncio.sleep(interval + jitter)
1428
1427
 
1429
- # Try to acquire global lock for this task
1430
- lock_acquired = await self.storage.try_acquire_system_lock(
1431
- lock_name="cleanup_old_messages",
1432
- worker_id=self.worker_id,
1433
- timeout_seconds=interval,
1434
- )
1435
-
1436
- if not lock_acquired:
1437
- # Another pod is handling this task
1438
- continue
1439
-
1440
- try:
1441
- deleted_count = await self.storage.cleanup_old_channel_messages(retention_days)
1442
- if deleted_count > 0:
1443
- logger.info("Cleaned up %d old channel messages", deleted_count)
1444
- finally:
1445
- await self.storage.release_system_lock("cleanup_old_messages", self.worker_id)
1428
+ deleted_count = await self.storage.cleanup_old_channel_messages(retention_days)
1429
+ if deleted_count > 0:
1430
+ logger.info("Cleaned up %d old channel messages", deleted_count)
1446
1431
  except Exception as e:
1447
1432
  logger.error("Error cleaning up old messages: %s", e, exc_info=True)
1448
1433
 
@@ -192,7 +192,6 @@ async def _refresh_lock_periodically(
192
192
 
193
193
  async def cleanup_stale_locks_periodically(
194
194
  storage: StorageProtocol,
195
- worker_id: str,
196
195
  interval: int = 60,
197
196
  ) -> None:
198
197
  """
@@ -204,49 +203,37 @@ async def cleanup_stale_locks_periodically(
204
203
  Note: This function only cleans up locks without resuming workflows.
205
204
  For automatic workflow resumption, use auto_resume_stale_workflows_periodically().
206
205
 
207
- Uses system-level locking to ensure only one pod executes cleanup at a time.
206
+ Important: This function should only be run by a single worker (e.g., via leader
207
+ election). It does not perform its own distributed coordination.
208
208
 
209
209
  Example:
210
210
  >>> asyncio.create_task(
211
- ... cleanup_stale_locks_periodically(storage, worker_id, interval=60)
211
+ ... cleanup_stale_locks_periodically(storage, interval=60)
212
212
  ... )
213
213
 
214
214
  Args:
215
215
  storage: Storage backend
216
- worker_id: Unique identifier for this worker (for global lock coordination)
217
216
  interval: Cleanup interval in seconds (default: 60)
218
217
  """
219
218
  with suppress(asyncio.CancelledError):
220
219
  while True:
221
- # Add jitter to prevent thundering herd in multi-pod deployments
220
+ # Add jitter to prevent thundering herd
222
221
  jitter = random.uniform(0, interval * 0.3)
223
222
  await asyncio.sleep(interval + jitter)
224
223
 
225
- # Try to acquire global lock for this task
226
- lock_acquired = await storage.try_acquire_system_lock(
227
- lock_name="cleanup_stale_locks",
228
- worker_id=worker_id,
229
- timeout_seconds=interval,
230
- )
231
-
232
- if not lock_acquired:
233
- # Another pod is handling this task
234
- continue
235
-
236
224
  try:
237
225
  # Clean up stale locks
238
226
  workflows = await storage.cleanup_stale_locks()
239
227
 
240
228
  if len(workflows) > 0:
241
229
  logger.info("Cleaned up %d stale locks", len(workflows))
242
- finally:
243
- await storage.release_system_lock("cleanup_stale_locks", worker_id)
230
+ except Exception as e:
231
+ logger.error("Failed to cleanup stale locks: %s", e, exc_info=True)
244
232
 
245
233
 
246
234
  async def auto_resume_stale_workflows_periodically(
247
235
  storage: StorageProtocol,
248
236
  replay_engine: Any,
249
- worker_id: str,
250
237
  interval: int = 60,
251
238
  ) -> None:
252
239
  """
@@ -255,39 +242,27 @@ async def auto_resume_stale_workflows_periodically(
255
242
  This combines lock cleanup with automatic workflow resumption, ensuring
256
243
  that workflows interrupted by worker crashes are automatically recovered.
257
244
 
258
- Uses system-level locking to ensure only one pod executes this task at a time,
259
- preventing duplicate workflow execution (CRITICAL for safety).
245
+ Important: This function should only be run by a single worker (e.g., via leader
246
+ election). It does not perform its own distributed coordination.
260
247
 
261
248
  Example:
262
249
  >>> asyncio.create_task(
263
250
  ... auto_resume_stale_workflows_periodically(
264
- ... storage, replay_engine, worker_id, interval=60
251
+ ... storage, replay_engine, interval=60
265
252
  ... )
266
253
  ... )
267
254
 
268
255
  Args:
269
256
  storage: Storage backend
270
257
  replay_engine: ReplayEngine instance for resuming workflows
271
- worker_id: Unique identifier for this worker (for global lock coordination)
272
258
  interval: Cleanup interval in seconds (default: 60)
273
259
  """
274
260
  with suppress(asyncio.CancelledError):
275
261
  while True:
276
- # Add jitter to prevent thundering herd in multi-pod deployments
262
+ # Add jitter to prevent thundering herd
277
263
  jitter = random.uniform(0, interval * 0.3)
278
264
  await asyncio.sleep(interval + jitter)
279
265
 
280
- # Try to acquire global lock for this task
281
- lock_acquired = await storage.try_acquire_system_lock(
282
- lock_name="auto_resume_stale_workflows",
283
- worker_id=worker_id,
284
- timeout_seconds=interval,
285
- )
286
-
287
- if not lock_acquired:
288
- # Another pod is handling this task
289
- continue
290
-
291
266
  try:
292
267
  # Clean up stale locks and get workflows to resume
293
268
  workflows_to_resume = await storage.cleanup_stale_locks()
@@ -369,8 +344,8 @@ async def auto_resume_stale_workflows_periodically(
369
344
  e,
370
345
  exc_info=True,
371
346
  )
372
- finally:
373
- await storage.release_system_lock("auto_resume_stale_workflows", worker_id)
347
+ except Exception as e:
348
+ logger.error("Failed to cleanup stale locks: %s", e, exc_info=True)
374
349
 
375
350
 
376
351
  class LockNotAcquiredError(Exception):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "edda-framework"
3
- version = "0.14.0"
3
+ version = "0.14.1"
4
4
  description = "Lightweight Durable Execution Framework"
5
5
  authors = [
6
6
  { name = "Yasushi Itoh", email = "6240399+i2y@users.noreply.github.com" }