edda-framework 0.9.0__py3-none-any.whl → 0.9.1__py3-none-any.whl
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.
- edda/app.py +15 -36
- edda/context.py +8 -0
- {edda_framework-0.9.0.dist-info → edda_framework-0.9.1.dist-info}/METADATA +1 -1
- {edda_framework-0.9.0.dist-info → edda_framework-0.9.1.dist-info}/RECORD +7 -7
- {edda_framework-0.9.0.dist-info → edda_framework-0.9.1.dist-info}/WHEEL +0 -0
- {edda_framework-0.9.0.dist-info → edda_framework-0.9.1.dist-info}/entry_points.txt +0 -0
- {edda_framework-0.9.0.dist-info → edda_framework-0.9.1.dist-info}/licenses/LICENSE +0 -0
edda/app.py
CHANGED
|
@@ -709,7 +709,6 @@ class EddaApp:
|
|
|
709
709
|
instance_id = subscription["instance_id"]
|
|
710
710
|
channel = subscription["channel"]
|
|
711
711
|
timeout_at = subscription["timeout_at"]
|
|
712
|
-
created_at = subscription["created_at"]
|
|
713
712
|
|
|
714
713
|
# Lock-First pattern: Try to acquire the lock before processing
|
|
715
714
|
# If we can't get the lock, another worker is processing this workflow
|
|
@@ -777,48 +776,28 @@ class EddaApp:
|
|
|
777
776
|
# 2. Remove message subscription
|
|
778
777
|
await self.storage.remove_message_subscription(instance_id, channel)
|
|
779
778
|
|
|
780
|
-
# 3.
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
timeout_at
|
|
788
|
-
if isinstance(timeout_at, dt_type)
|
|
789
|
-
else dt_type.fromisoformat(str(timeout_at))
|
|
790
|
-
)
|
|
791
|
-
created_dt = (
|
|
792
|
-
created_at
|
|
793
|
-
if isinstance(created_at, dt_type)
|
|
794
|
-
else dt_type.fromisoformat(str(created_at))
|
|
779
|
+
# 3. Resume workflow (lock already held - distributed coroutine pattern)
|
|
780
|
+
# The workflow will replay and receive() will raise TimeoutError from cached history
|
|
781
|
+
workflow_name = subscription.get("workflow_name")
|
|
782
|
+
if not workflow_name:
|
|
783
|
+
logger.warning(
|
|
784
|
+
"No workflow_name in subscription for %s, skipping",
|
|
785
|
+
instance_id,
|
|
795
786
|
)
|
|
796
|
-
|
|
797
|
-
timeout_seconds = int((timeout_dt - created_dt).total_seconds())
|
|
798
|
-
except Exception:
|
|
799
|
-
timeout_seconds = 0 # Fallback
|
|
787
|
+
continue
|
|
800
788
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
stack_trace = "".join(
|
|
805
|
-
traceback.format_exception(type(error), error, error.__traceback__)
|
|
806
|
-
)
|
|
789
|
+
if self.replay_engine is None:
|
|
790
|
+
logger.error("Replay engine not initialized")
|
|
791
|
+
continue
|
|
807
792
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
instance_id,
|
|
811
|
-
"failed",
|
|
812
|
-
{
|
|
813
|
-
"error_message": str(error),
|
|
814
|
-
"error_type": "TimeoutError",
|
|
815
|
-
"stack_trace": stack_trace,
|
|
816
|
-
},
|
|
793
|
+
await self.replay_engine.resume_by_name(
|
|
794
|
+
instance_id, workflow_name, already_locked=True
|
|
817
795
|
)
|
|
818
796
|
|
|
819
797
|
logger.debug(
|
|
820
|
-
"
|
|
798
|
+
"Resumed workflow %s after message timeout on channel '%s'",
|
|
821
799
|
instance_id,
|
|
800
|
+
channel,
|
|
822
801
|
)
|
|
823
802
|
|
|
824
803
|
except Exception as e:
|
edda/context.py
CHANGED
|
@@ -217,6 +217,14 @@ class WorkflowContext:
|
|
|
217
217
|
# Cache the timer result for wait_timer replay
|
|
218
218
|
# Timer returns None, so we cache the result field
|
|
219
219
|
self._history_cache[activity_id] = event_data.get("result")
|
|
220
|
+
elif event_type == "MessageTimeout":
|
|
221
|
+
# Cache the timeout error for receive() replay
|
|
222
|
+
# This allows TimeoutError to be raised and caught in workflow code
|
|
223
|
+
self._history_cache[activity_id] = {
|
|
224
|
+
"_error": True,
|
|
225
|
+
"error_type": event_data.get("error_type", "TimeoutError"),
|
|
226
|
+
"error_message": event_data.get("error_message", "Message timeout"),
|
|
227
|
+
}
|
|
220
228
|
|
|
221
229
|
self._history_loaded = True
|
|
222
230
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
edda/__init__.py,sha256=hGC6WR2R36M8LWC97F-0Rw4Ln0QUUT_1xC-7acOy_Fk,2237
|
|
2
2
|
edda/activity.py,sha256=nRm9eBrr0lFe4ZRQ2whyZ6mo5xd171ITIVhqytUhOpw,21025
|
|
3
|
-
edda/app.py,sha256=
|
|
3
|
+
edda/app.py,sha256=11-IczlJpCR_G-jWUvV1DIr_Zwm6bDJnFiNBQsZ79Zo,44306
|
|
4
4
|
edda/channels.py,sha256=Budi0FyxalmcAMwj50mX3WzRce5OuLKXGws0Hp_snfw,34745
|
|
5
5
|
edda/compensation.py,sha256=iKLlnTxiF1YSatmYQW84EkPB1yMKUEZBtgjuGnghLtY,11824
|
|
6
|
-
edda/context.py,sha256=
|
|
6
|
+
edda/context.py,sha256=pPn98-G5HgaOGDRzEhma58TzBulwsiTvmNEMLIu0XwI,21330
|
|
7
7
|
edda/exceptions.py,sha256=-ntBLGpVQgPFG5N1o8m_7weejAYkNrUdxTkOP38vsHk,1766
|
|
8
8
|
edda/hooks.py,sha256=HUZ6FTM__DZjwuomDfTDEroQ3mugEPuJHcGm7CTQNvg,8193
|
|
9
9
|
edda/locking.py,sha256=NAFJmw-JaSVsXn4Y4czJyv_s9bWG8cdrzDBWIEag5X8,13661
|
|
@@ -36,8 +36,8 @@ edda/viewer_ui/theme.py,sha256=mrXoXLRzgSnvE2a58LuMcPJkhlvHEDMWVa8Smqtk4l0,8118
|
|
|
36
36
|
edda/visualizer/__init__.py,sha256=DOpDstNhR0VcXAs_eMKxaL30p_0u4PKZ4o2ndnYhiRo,343
|
|
37
37
|
edda/visualizer/ast_analyzer.py,sha256=plmx7C9X_X35xLY80jxOL3ljg3afXxBePRZubqUIkxY,13663
|
|
38
38
|
edda/visualizer/mermaid_generator.py,sha256=XWa2egoOTNDfJEjPcwoxwQmblUqXf7YInWFjFRI1QGo,12457
|
|
39
|
-
edda_framework-0.9.
|
|
40
|
-
edda_framework-0.9.
|
|
41
|
-
edda_framework-0.9.
|
|
42
|
-
edda_framework-0.9.
|
|
43
|
-
edda_framework-0.9.
|
|
39
|
+
edda_framework-0.9.1.dist-info/METADATA,sha256=8m1LKjz9cWbmwsa7V-FAEIQdgM3_63wan3Yml58KToE,35741
|
|
40
|
+
edda_framework-0.9.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
41
|
+
edda_framework-0.9.1.dist-info/entry_points.txt,sha256=dPH47s6UoJgUZxHoeSMqZsQkLaSE-SGLi-gh88k2WrU,48
|
|
42
|
+
edda_framework-0.9.1.dist-info/licenses/LICENSE,sha256=udxb-V7_cYKTHqW7lNm48rxJ-Zpf0WAY_PyGDK9BPCo,1069
|
|
43
|
+
edda_framework-0.9.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|