From 8977eb7f05ada70800b5c7e71c7c7d9d9235fd4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20Crespo?= Date: Mon, 4 May 2020 11:08:12 -0700 Subject: [PATCH 1/9] Remove unused dep: six --- cadence/workflow.py | 1 - requirements.txt | 1 - setup.py | 1 - 3 files changed, 3 deletions(-) diff --git a/cadence/workflow.py b/cadence/workflow.py index ea3ecc6..98ddb84 100644 --- a/cadence/workflow.py +++ b/cadence/workflow.py @@ -8,7 +8,6 @@ from typing import Callable, List, Type, Dict, Tuple from uuid import uuid4 -from six import reraise from cadence.activity import ActivityCompletionClient from cadence.activity_method import RetryParameters, ActivityOptions diff --git a/requirements.txt b/requirements.txt index 9d6fbd7..5b30432 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ more-itertools==7.0.0 ply==3.11 -six==1.12.0 tblib==1.6.0 thriftrw==1.7.2 dataclasses-json==0.3.8 diff --git a/setup.py b/setup.py index 299424c..febac75 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,6 @@ "dataclasses-json>=0.3.8", "more-itertools>=7.0.0", "ply>=3.11", - "six>=1.12.0", "tblib>=1.6.0", "thriftrw>=1.7.2", ], From 769574a235890361ecac86c02b8e954ac953f7e6 Mon Sep 17 00:00:00 2001 From: Mohammed Firdaus Date: Thu, 7 May 2020 01:42:54 +0800 Subject: [PATCH 2/9] Handle DecisionTaskFailed. --- cadence/decision_loop.py | 8 +++++++- cadence/tests/test_decision_loop.py | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/cadence/decision_loop.py b/cadence/decision_loop.py index 954ca7c..48d7731 100644 --- a/cadence/decision_loop.py +++ b/cadence/decision_loop.py @@ -27,7 +27,7 @@ HistoryEvent, EventType, WorkflowType, ScheduleActivityTaskDecisionAttributes, \ CancelWorkflowExecutionDecisionAttributes, StartTimerDecisionAttributes, TimerFiredEventAttributes, \ FailWorkflowExecutionDecisionAttributes, RecordMarkerDecisionAttributes, Header, WorkflowQuery, \ - RespondQueryTaskCompletedRequest, QueryTaskCompletedType, QueryWorkflowResponse + RespondQueryTaskCompletedRequest, QueryTaskCompletedType, QueryWorkflowResponse, DecisionTaskFailedCause from cadence.conversions import json_to_args, args_to_json from cadence.decisions import DecisionId, DecisionTarget from cadence.exception_handling import serialize_exception, deserialize_exception @@ -674,6 +674,11 @@ def handle_activity_task_failed(self, event: HistoryEvent): def handle_activity_task_timed_out(self, event: HistoryEvent): self.decision_context.handle_activity_task_timed_out(event) + def handle_decision_task_failed(self, event: HistoryEvent): + attr = event.decision_task_failed_event_attributes + if attr and attr.cause == DecisionTaskFailedCause.RESET_WORKFLOW: + self.decision_context.set_current_run_id(attr.new_run_id) + def handle_workflow_execution_signaled(self, event: HistoryEvent): signaled_event_attributes = event.workflow_execution_signaled_event_attributes signal_input = signaled_event_attributes.input @@ -816,6 +821,7 @@ def on_timer_canceled(self: ReplayDecider, event: HistoryEvent): EventType.DecisionTaskScheduled: noop, EventType.DecisionTaskStarted: noop, # Filtered by HistoryHelper EventType.DecisionTaskTimedOut: noop, # TODO: check + EventType.DecisionTaskFailed: ReplayDecider.handle_decision_task_failed, EventType.ActivityTaskScheduled: ReplayDecider.handle_activity_task_scheduled, EventType.ActivityTaskStarted: ReplayDecider.handle_activity_task_started, EventType.ActivityTaskCompleted: ReplayDecider.handle_activity_task_completed, diff --git a/cadence/tests/test_decision_loop.py b/cadence/tests/test_decision_loop.py index 2d4ba10..255225c 100644 --- a/cadence/tests/test_decision_loop.py +++ b/cadence/tests/test_decision_loop.py @@ -6,7 +6,8 @@ from cadence.cadence_types import HistoryEvent, EventType, PollForDecisionTaskResponse, \ ScheduleActivityTaskDecisionAttributes, WorkflowExecutionStartedEventAttributes, Decision, \ - ActivityTaskStartedEventAttributes, MarkerRecordedEventAttributes + ActivityTaskStartedEventAttributes, MarkerRecordedEventAttributes, DecisionTaskFailedEventAttributes, \ + DecisionTaskFailedCause from cadence.clock_decision_context import VERSION_MARKER_NAME from cadence.decision_loop import HistoryHelper, is_decision_event, DecisionTaskLoop, ReplayDecider, DecisionEvents, \ nano_to_milli @@ -365,6 +366,18 @@ def test_handle_activity_task_started(self): args, kwargs = state_machine.handle_started_event.call_args_list[0] self.assertIn(event, args) + def test_handle_decision_task_failed(self): + event = HistoryEvent(event_id=15) + event.event_type = EventType.DecisionTaskFailed + event.decision_task_failed_event_attributes = DecisionTaskFailedEventAttributes() + event.decision_task_failed_event_attributes.cause = DecisionTaskFailedCause.RESET_WORKFLOW + event.decision_task_failed_event_attributes.new_run_id = "the-new-run-id" + self.decider.decision_context = decision_context = MagicMock() + self.decider.handle_decision_task_failed(event) + decision_context.set_current_run_id.assert_called() + args, kwargs = decision_context.set_current_run_id.call_args_list[0] + assert args[0] == "the-new-run-id" + def tearDown(self) -> None: self.decider.destroy() From f5c9fa1f80eefce3932b33b66e6eade38b8cc2ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20Crespo?= Date: Fri, 8 May 2020 11:02:06 -0700 Subject: [PATCH 3/9] Add min. Py3 version required --- README.md | 4 ++++ setup.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 99c6226..bece74b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +

+PyPI - Python Version +

+ # Intro: Fault-Oblivious Stateful Python Code cadence-python allows you to create Python functions that have their state (local variables etc..) implicitly saved such that if the process/machine fails the state of the function is not lost and can resume from where it left off. diff --git a/setup.py b/setup.py index 299424c..a4e51f3 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,8 @@ ], classifiers=[ "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], From 4f70eb427eb18ae320b84517a6b6766a39d69be6 Mon Sep 17 00:00:00 2001 From: Mohammed Firdaus Date: Tue, 26 May 2020 01:52:47 +0800 Subject: [PATCH 4/9] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 99c6226..e4e6e6a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +> I'm doing a survey to figure out the way forward for this library - https://airtable.com/shrJWfd63yBWSJKoI +> Your feedback is very much appreciated! + # Intro: Fault-Oblivious Stateful Python Code cadence-python allows you to create Python functions that have their state (local variables etc..) implicitly saved such that if the process/machine fails the state of the function is not lost and can resume from where it left off. From 1a29c72d1d984f769dab59ab55395e0ad29313dc Mon Sep 17 00:00:00 2001 From: Mohammed Firdaus Date: Tue, 26 May 2020 01:58:32 +0800 Subject: [PATCH 5/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4e6e6a..fc954a5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> I'm doing a survey to figure out the way forward for this library - https://airtable.com/shrJWfd63yBWSJKoI +> I'm doing a survey to figure out the way forward for this library - https://airtable.com/shrJWfd63yBWSJKoI
> Your feedback is very much appreciated! # Intro: Fault-Oblivious Stateful Python Code From 7a36c4924e430359419162d469bed312b4e14a40 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Fri, 5 Jun 2020 16:39:13 -0700 Subject: [PATCH 6/9] Improved README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e656486..5a7a65a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ pip install cadence-client==1.0.0b2 ## Hello World Sample -``` +```python import sys import logging from cadence.activity_method import activity_method @@ -70,7 +70,7 @@ class GreetingActivities: # Activities Implementation class GreetingActivitiesImpl: def compose_greeting(self, greeting: str, name: str): - return greeting + " " + name + "!" + return f"{greeting} {name}!" # Workflow Interface From d58d5d7fc9eea2703c450ab583bec2eb8dcf5fea Mon Sep 17 00:00:00 2001 From: Mohammed Firdaus Date: Wed, 8 Jul 2020 23:25:44 +0800 Subject: [PATCH 7/9] Released b3. --- README.md | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a7a65a..b3d14e8 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ docker run --network=host --rm ubercadence/cli:master --do sample domain registe ## Installation cadence-python ``` -pip install cadence-client==1.0.0b2 +pip install cadence-client==1.0.0b3 ``` ## Hello World Sample diff --git a/setup.py b/setup.py index 31db30d..ea3d576 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="cadence-client", - version="1.0.0-beta2", + version="1.0.0-beta3", author="Mohammed Firdaus", author_email="firdaus.halim@gmail.com", description="Python framework for Cadence Workflow Service", From 05671bb0959f8370a2f80e67090f1d741a00a379 Mon Sep 17 00:00:00 2001 From: Mohammed Firdaus Date: Sat, 1 Aug 2020 16:47:35 +0800 Subject: [PATCH 8/9] Update README.md --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index b3d14e8..7c8541b 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,3 @@ -> I'm doing a survey to figure out the way forward for this library - https://airtable.com/shrJWfd63yBWSJKoI
-> Your feedback is very much appreciated! - -

-PyPI - Python Version -

- # Intro: Fault-Oblivious Stateful Python Code cadence-python allows you to create Python functions that have their state (local variables etc..) implicitly saved such that if the process/machine fails the state of the function is not lost and can resume from where it left off. From c429263c30fbd9da96f6f8ef92dd678d7b0074d5 Mon Sep 17 00:00:00 2001 From: Mohammed Firdaus Date: Tue, 1 Sep 2020 16:05:46 +0800 Subject: [PATCH 9/9] Add Workflow.get_workflow_id() and Workflow.get_execution_id(). --- cadence/decision_loop.py | 7 +++++-- cadence/workflow.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cadence/decision_loop.py b/cadence/decision_loop.py index 48d7731..afdf0d5 100644 --- a/cadence/decision_loop.py +++ b/cadence/decision_loop.py @@ -537,6 +537,7 @@ class ReplayDecider: decision_events: DecisionEvents = None decisions: OrderedDict[DecisionId, DecisionStateMachine] = field(default_factory=OrderedDict) decision_context: DecisionContext = None + workflow_id: str = None activity_id_to_scheduled_event_id: Dict[str, int] = field(default_factory=dict) @@ -910,14 +911,16 @@ def poll(self) -> Optional[PollForDecisionTaskResponse]: def process_task(self, decision_task: PollForDecisionTaskResponse) -> List[Decision]: execution_id = str(decision_task.workflow_execution) - decider = ReplayDecider(execution_id, decision_task.workflow_type, self.worker) + decider = ReplayDecider(execution_id, decision_task.workflow_type, self.worker, + workflow_id=decision_task.workflow_execution.workflow_id) decisions: List[Decision] = decider.decide(decision_task.history.events) decider.destroy() return decisions def process_query(self, decision_task: PollForDecisionTaskResponse) -> bytes: execution_id = str(decision_task.workflow_execution) - decider = ReplayDecider(execution_id, decision_task.workflow_type, self.worker) + decider = ReplayDecider(execution_id, decision_task.workflow_type, self.worker, + workflow_id=decision_task.workflow_execution.workflow_id) decider.decide(decision_task.history.events) try: result = decider.query(decision_task, decision_task.query) diff --git a/cadence/workflow.py b/cadence/workflow.py index 98ddb84..be570a8 100644 --- a/cadence/workflow.py +++ b/cadence/workflow.py @@ -89,6 +89,19 @@ def get_logger(name): task: ITask = ITask.current() return task.decider.decision_context.get_logger(name) + @staticmethod + def get_workflow_id(): + from cadence.decision_loop import ITask + task: ITask = ITask.current() + return task.decider.workflow_id + + @staticmethod + def get_execution_id(): + from cadence.decision_loop import ITask + task: ITask = ITask.current() + return task.decider.execution_id + + class WorkflowStub: pass