def query(self, decision_task: PollForDecisionTaskResponse, query: WorkflowQuery) -> bytes: query_args = query.query_args if query_args is None: args = [] else: args = json_to_args(query_args) task = QueryMethodTask( task_id=self.execution_id, workflow_instance=self.workflow_task.workflow_instance, query_name=query.query_type, query_input=args, decider=self) self.tasks.append(task) task.start() self.event_loop.run_event_loop_once() if task.status == Status.DONE: if task.exception_thrown: raise task.exception_thrown else: # ret_value might be None, need to put it in else return task.ret_value else: raise QueryDidNotComplete( f"Query method {query.query_type} with args {query.query_args} did not complete" )
def handle_workflow_execution_started(self, event: HistoryEvent): start_event_attributes = event.workflow_execution_started_event_attributes self.decision_context.set_current_run_id(start_event_attributes.original_execution_run_id) if start_event_attributes.input is None or start_event_attributes.input == b'': workflow_input = [] else: workflow_input = json_to_args(start_event_attributes.input) self.workflow_task = WorkflowMethodTask(task_id=self.execution_id, workflow_input=workflow_input, worker=self.worker, workflow_type=self.workflow_type, decider=self) self.event_loop.run_event_loop_once() assert self.workflow_task.workflow_instance self.tasks.append(self.workflow_task)
def handle_workflow_execution_signaled(self, event: HistoryEvent): signaled_event_attributes = event.workflow_execution_signaled_event_attributes signal_input = signaled_event_attributes.input if not signal_input: signal_input = [] else: signal_input = json_to_args(signal_input) task = SignalMethodTask(task_id=self.execution_id, workflow_instance=self.workflow_task.workflow_instance, signal_name=signaled_event_attributes.signal_name, signal_input=signal_input, decider=self) self.tasks.append(task) task.start()
def activity_task_loop(worker: Worker): service: WorkflowService = WorkflowService.create( worker.host, worker.port, timeout=worker.get_timeout()) worker.manage_service(service) logger.info( f"Activity task worker started: {WorkflowService.get_identity()}") try: while True: if worker.is_stop_requested(): return try: service.set_next_timeout_cb(worker.raise_if_stop_requested) polling_start = datetime.datetime.now() polling_request = PollForActivityTaskRequest() polling_request.task_list_metadata = TaskListMetadata() polling_request.task_list_metadata.max_tasks_per_second = 200000 polling_request.domain = worker.domain polling_request.identity = WorkflowService.get_identity() polling_request.task_list = TaskList() polling_request.task_list.name = worker.task_list task: PollForActivityTaskResponse task, err = service.poll_for_activity_task(polling_request) polling_end = datetime.datetime.now() logger.debug("PollForActivityTask: %dms", (polling_end - polling_start).total_seconds() * 1000) except StopRequestedException: return except Exception as ex: logger.error("PollForActivityTask error: %s", ex) continue if err: logger.error("PollForActivityTask failed: %s", err) continue task_token = task.task_token if not task_token: logger.debug( "PollForActivityTask has no task_token (expected): %s", task) continue args = json_to_args(task.input) logger.info(f"Request for activity: {task.activity_type.name}") fn = worker.activities.get(task.activity_type.name) if not fn: logger.error("Activity type not found: " + task.activity_type.name) continue process_start = datetime.datetime.now() activity_context = ActivityContext() activity_context.service = service activity_context.activity_task = ActivityTask.from_poll_for_activity_task_response( task) activity_context.domain = worker.domain try: ActivityContext.set(activity_context) return_value = fn(*args) if activity_context.do_not_complete: logger.info( f"Not completing activity {task.activity_type.name}({str(args)[1:-1]})" ) continue error = complete(service, task_token, return_value) if error: logger.error( "Error invoking RespondActivityTaskCompleted: %s", error) logger.info( f"Activity {task.activity_type.name}({str(args)[1:-1]}) returned {json.dumps(return_value)}" ) except Exception as ex: logger.error( f"Activity {task.activity_type.name} failed: {type(ex).__name__}({ex})", exc_info=1) error = complete_exceptionally(service, task_token, ex) if error: logger.error( "Error invoking RespondActivityTaskFailed: %s", error) finally: ActivityContext.set(None) process_end = datetime.datetime.now() logger.info("Process ActivityTask: %dms", (process_end - process_start).total_seconds() * 1000) finally: try: service.close() except: logger.warning("service.close() failed", exc_info=1) worker.notify_thread_stopped()
def activity_task_loop(worker: Worker): service = WorkflowService.create(worker.host, worker.port) logger.info( f"Activity task worker started: {WorkflowService.get_identity()}") try: while True: if worker.is_stop_requested(): return try: polling_start = datetime.datetime.now() polling_request = PollForActivityTaskRequest() polling_request.task_list_metadata = TaskListMetadata() polling_request.task_list_metadata.max_tasks_per_second = 200000 polling_request.domain = worker.domain polling_request.identity = WorkflowService.get_identity() polling_request.task_list = TaskList() polling_request.task_list.name = worker.task_list task: PollForActivityTaskResponse task, err = service.poll_for_activity_task(polling_request) polling_end = datetime.datetime.now() logger.debug("PollForActivityTask: %dms", (polling_end - polling_start).total_seconds() * 1000) except Exception as ex: logger.error("PollForActivityTask error: %s", ex) continue if err: logger.error("PollForActivityTask failed: %s", err) continue if not task.task_token: logger.debug( "PollForActivityTask has no task_token (expected): %s", task) continue args = json_to_args(task.input) logger.info(f"Request for activity: {task.activity_type.name}") fn = worker.activities.get(task.activity_type.name) if not fn: logger.error("Activity type not found: " + task.activity_type.name) continue process_start = datetime.datetime.now() activity_context = ActivityContext() activity_context.task_token = task.task_token activity_context.workflow_execution = task.workflow_execution activity_context.domain = worker.domain try: ActivityContext.set(activity_context) ret = fn(*args) ActivityContext.set(None) respond = RespondActivityTaskCompletedRequest() respond.task_token = task.task_token respond.result = json.dumps(ret) respond.identity = WorkflowService.get_identity() _, error = service.respond_activity_task_completed(respond) if error: logger.error( "Error invoking RespondActivityTaskCompleted: %s", error) logger.info( f"Activity {task.activity_type.name}({str(args)[1:-1]}) returned {respond.result}" ) except Exception as ex: logger.error( f"Activity {task.activity_type.name} failed: {type(ex).__name__}({ex})", exc_info=1) respond: RespondActivityTaskFailedRequest = RespondActivityTaskFailedRequest( ) respond.task_token = task.task_token respond.identity = WorkflowService.get_identity() respond.details = json.dumps({ "detailMessage": f"Python error: {type(ex).__name__}({ex})", "class": "java.lang.Exception" }) respond.reason = "java.lang.Exception" _, error = service.respond_activity_task_failed(respond) if error: logger.error( "Error invoking RespondActivityTaskFailed: %s", error) process_end = datetime.datetime.now() logger.info("Process ActivityTask: %dms", (process_end - process_start).total_seconds() * 1000) finally: worker.notify_thread_stopped()