예제 #1
0
 def setUp(self) -> None:
     fp = open(os.path.join(__location__, "workflow_started_decision_task_response.json"))
     self.poll_response: PollForDecisionTaskResponse = json_to_data_class(json.loads(fp.read()),
                                                                          PollForDecisionTaskResponse)
     fp.close()
     self.worker = Worker()
     self.loop = DecisionTaskLoop(worker=self.worker)
     global dummy_workflow_self
     dummy_workflow_self = None
예제 #2
0
def test_worker_register_query_method():
    worker = Worker()
    worker.register_workflow_implementation_type(DummyWorkflowImpl, "DummyWorkflow")
    assert DummyWorkflowImpl._query_methods
    assert "DummyWorkflow::dummy_query" in DummyWorkflowImpl._query_methods
    assert "DummyWorkflow::dummyQuery" in DummyWorkflowImpl._query_methods
    assert "DummyWorkflow::dummy_query_paren" in DummyWorkflowImpl._query_methods
    assert "DummyWorkflow::dummyQueryParen" in DummyWorkflowImpl._query_methods
    assert "blah" in DummyWorkflowImpl._query_methods
예제 #3
0
 def new_worker(self,
                task_list: str,
                worker_options: WorkerOptions = None) -> Worker:
     worker = Worker(host=self.host,
                     port=self.port,
                     domain=self.domain,
                     task_list=task_list,
                     options=worker_options)
     self.workers.append(worker)
     return worker
예제 #4
0
class TestDecisionTaskLoop(TestCase):
    def setUp(self) -> None:
        fp = open(
            os.path.join(__location__,
                         "workflow_started_decision_task_response.json"))
        self.poll_response: PollForDecisionTaskResponse = json_to_data_class(
            json.loads(fp.read()), PollForDecisionTaskResponse)
        fp.close()
        self.worker = Worker()
        self.loop = DecisionTaskLoop(worker=self.worker)
        global dummy_workflow_self
        dummy_workflow_self = None

    def test_create_workflow_object(self):
        class DummyWorkflow:
            @workflow_method()
            async def dummy(self):
                nonlocal dummy_workflow_self
                dummy_workflow_self = self

        dummy_workflow_self = None
        self.worker.register_workflow_implementation_type(DummyWorkflow)
        self.loop.process_task(self.poll_response)
        self.assertIsInstance(dummy_workflow_self, DummyWorkflow)

    def test_return_none(self):
        class DummyWorkflow:
            @workflow_method()
            async def dummy(self):
                return None

        self.worker.register_workflow_implementation_type(DummyWorkflow)
        decisions = self.loop.process_task(self.poll_response)
        complete_workflow = decisions[
            0].complete_workflow_execution_decision_attributes
        self.assertEqual("null", complete_workflow.result)

    def test_one_arg(self):
        class DummyWorkflow:
            @workflow_method()
            async def dummy(self, arg1):
                nonlocal arg1_value
                arg1_value = arg1

        arg1_value = None
        self.worker.register_workflow_implementation_type(DummyWorkflow)
        self.poll_response.history.events[
            0].workflow_execution_started_event_attributes.input = json.dumps(
                ["first"])
        self.loop.process_task(self.poll_response)
        self.assertEqual(arg1_value, "first")

    def test_args(self):
        class DummyWorkflow:
            @workflow_method()
            async def dummy(self, arg1, arg2):
                nonlocal arg1_value, arg2_value
                arg1_value = arg1
                arg2_value = arg2

        arg1_value = None
        arg2_value = None
        self.worker.register_workflow_implementation_type(DummyWorkflow)
        self.poll_response.history.events[
            0].workflow_execution_started_event_attributes.input = json.dumps(
                ["first", "second"])
        self.loop.process_task(self.poll_response)
        self.assertEqual(arg1_value, "first")
        self.assertEqual(arg2_value, "second")

    def test_no_args(self):
        class DummyWorkflow:
            @workflow_method()
            async def dummy(self):
                nonlocal executed
                executed = True

        executed = False
        self.worker.register_workflow_implementation_type(DummyWorkflow)
        self.poll_response.history.events[
            0].workflow_execution_started_event_attributes.input = json.dumps(
                [])
        self.loop.process_task(self.poll_response)
        self.assertTrue(executed)

    def test_return_value(self):
        class DummyWorkflow:
            @workflow_method()
            async def dummy(self):
                return "value"

        self.worker.register_workflow_implementation_type(DummyWorkflow)
        decisions = self.loop.process_task(self.poll_response)
        complete_workflow = decisions[
            0].complete_workflow_execution_decision_attributes
        self.assertEqual('"value"', complete_workflow.result)
예제 #5
0
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()
예제 #6
0
 def setUpClass(cls) -> None:
     cls.task_list = "task-list-" + str(uuid4())
     cls.worker = worker = Worker("localhost", 7933, "test-domain",
                                  cls.task_list)
     worker.register_workflow_implementation_type(GreetingWorkflow)
     worker.start()
예제 #7
0
def worker():
    return Worker()
예제 #8
0
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()
예제 #9
0
def worker():
    worker = Worker()
    worker.register_workflow_implementation_type(DummyWorkflow)
    return worker
def worker():
    worker = Worker()
    return worker