def run(self): try: logger.info( f"Decision task worker started: {WorkflowService.get_identity()}" ) event_loop = asyncio.new_event_loop() asyncio.set_event_loop(event_loop) self.service = WorkflowService.create(self.worker.host, self.worker.port) self.worker.manage_service(self.service) while True: if self.worker.is_stop_requested(): return decision_task: PollForDecisionTaskResponse = self.poll() if not decision_task: continue if decision_task.query: try: result = self.process_query(decision_task) self.respond_query(decision_task.task_token, result, None) except Exception as ex: logger.error("Error") self.respond_query(decision_task.task_token, None, serialize_exception(ex)) else: decisions = self.process_task(decision_task) self.respond_decisions(decision_task.task_token, decisions) finally: # noinspection PyPep8,PyBroadException try: self.service.close() except: logger.warning("service.close() failed", exc_info=1) self.worker.notify_thread_stopped()
def complete_exceptionally(service, task_token, ex: Exception) -> Optional[Exception]: respond: RespondActivityTaskFailedRequest = RespondActivityTaskFailedRequest() respond.task_token = task_token respond.identity = WorkflowService.get_identity() respond.reason = "ActivityFailureException" respond.details = serialize_exception(ex) _, error = service.respond_activity_task_failed(respond) return error
def fail_workflow_execution(self, exception): # PORT: addAllMissingVersionMarker(false, Optional.empty()); decision = Decision() fail_attributes = FailWorkflowExecutionDecisionAttributes() fail_attributes.reason = "WorkflowFailureException" fail_attributes.details = serialize_exception(exception) decision.fail_workflow_execution_decision_attributes = fail_attributes decision.decision_type = DecisionType.FailWorkflowExecution decision_id = DecisionId(DecisionTarget.SELF, 0) self.add_decision(decision_id, CompleteWorkflowStateMachine(decision_id, decision)) self.completed = True
def test_activity_task_failed(self): event = HistoryEvent(event_type=EventType.ActivityTaskFailed) attr = ActivityTaskFailedEventAttributes() attr.scheduled_event_id = 20 event.activity_task_failed_event_attributes = attr attr.reason = "the-reason" ex = None try: raise DummyUserLevelException("abc") except Exception as e: ex = e attr.details = serialize_exception(ex) self.context.handle_activity_task_failed(event) self.assertTrue(self.future.done()) exception = self.future.exception() self.assertIsInstance(exception, DummyUserLevelException) self.assertEqual(0, len(self.context.scheduled_activities))
def test_serialize_deserialize_exception(): try: a() except TestException as e: ex = e details = serialize_exception(ex) details_dict = json.loads(details) assert details_dict[ "class"] == "cadence.tests.test_exception_handling.TestException" assert details_dict["args"] == ["here"] assert details_dict["traceback"] assert details_dict["source"] == "cadence-python" dex = deserialize_exception(details) assert type(dex) == TestException assert repr(dex) == repr(ex) assert dex.__traceback__
async def schedule_activity_task(self, parameters: ExecuteActivityParameters): attr = ScheduleActivityTaskDecisionAttributes() attr.activity_type = parameters.activity_type attr.input = parameters.input if parameters.heartbeat_timeout_seconds > 0: attr.heartbeat_timeout_seconds = parameters.heartbeat_timeout_seconds attr.schedule_to_close_timeout_seconds = parameters.schedule_to_close_timeout_seconds attr.schedule_to_start_timeout_seconds = parameters.schedule_to_start_timeout_seconds attr.start_to_close_timeout_seconds = parameters.start_to_close_timeout_seconds attr.activity_id = parameters.activity_id if not attr.activity_id: attr.activity_id = self.decider.get_and_increment_next_id() attr.task_list = TaskList() attr.task_list.name = parameters.task_list if parameters.retry_parameters: attr.retry_policy = parameters.retry_parameters.to_retry_policy() scheduled_event_id = self.decider.schedule_activity_task(schedule=attr) future = self.decider.event_loop.create_future() self.scheduled_activities[scheduled_event_id] = future try: await future except CancelledError as e: logger.debug("Coroutine cancelled (expected)") raise e except Exception as ex: pass ex = future.exception() if ex: activity_failure = ActivityFailureException( scheduled_event_id, parameters.activity_type.name, parameters.activity_id, serialize_exception(ex)) raise activity_failure assert future.done() raw_bytes = future.result() return json.loads(str(raw_bytes, "utf-8"))