示例#1
0
async def complete_exceptionally(service, task_token, ex: Exception):
    respond: RespondActivityTaskFailedRequest = RespondActivityTaskFailedRequest(
    )
    respond.task_token = task_token
    respond.identity = get_identity()
    respond.failure = serialize_exception(ex)
    await service.respond_activity_task_failed(request=respond)
async def complete(client: "WorkflowClient", task_token, return_value: object):
    respond = RespondActivityTaskCompletedRequest()
    respond.task_token = task_token
    respond.namespace = client.namespace
    respond.identity = get_identity()
    respond.result = client.data_converter.to_payloads([return_value])
    await client.service.respond_activity_task_completed(request=respond)
async def complete_exceptionally(client: "WorkflowClient", task_token,
                                 ex: Exception):
    respond: RespondActivityTaskFailedRequest = RespondActivityTaskFailedRequest(
    )
    respond.task_token = task_token
    respond.namespace = client.namespace
    respond.identity = get_identity()
    respond.failure = serialize_exception(ex)
    await client.service.respond_activity_task_failed(request=respond)
示例#4
0
async def heartbeat(service: WorkflowService, task_token: bytes,
                    details: object):
    request: RecordActivityTaskHeartbeatRequest = RecordActivityTaskHeartbeatRequest(
    )
    request.details = to_payloads([details])
    request.identity = get_identity()
    request.task_token = task_token
    response = await service.record_activity_task_heartbeat(request=request)
    # -----
    # if error:
    #     raise error
    # -----
    if response.cancel_requested:
        raise ActivityCancelledException()
async def heartbeat(client: "WorkflowClient", task_token: bytes,
                    details: object):
    request: RecordActivityTaskHeartbeatRequest = RecordActivityTaskHeartbeatRequest(
    )
    request.details = client.data_converter.to_payloads([details])
    request.namespace = client.namespace
    request.identity = get_identity()
    request.task_token = task_token
    response = await client.service.record_activity_task_heartbeat(
        request=request)
    # -----
    # if error:
    #     raise error
    # -----
    if response.cancel_requested:
        raise ActivityCancelledException()
async def test(worker):
    client = WorkflowClient.new_client(namespace=NAMESPACE)
    greeting_workflow: GreetingWorkflow = client.new_workflow_stub(GreetingWorkflow)
    context: WorkflowExecutionContext = await client.start(
        greeting_workflow.get_greeting
    )
    await asyncio.sleep(60 * 3)
    assert invoke_count >= 2
    request = TerminateWorkflowExecutionRequest()
    request.namespace = NAMESPACE
    request.identity = get_identity()
    request.workflow_execution = context.workflow_execution
    request.workflow_execution.run_id = None
    response: TerminateWorkflowExecutionResponse = (
        await client.service.terminate_workflow_execution(request=request)
    )
示例#7
0
async def activity_task_loop_func(worker: Worker):
    service: WorkflowService = worker.client.service
    logger.info(f"Activity task worker started: {get_identity()}")
    try:
        while True:
            if worker.is_stop_requested():
                return
            try:
                polling_start = datetime.datetime.now()
                polling_request: PollActivityTaskQueueRequest = PollActivityTaskQueueRequest(
                )
                polling_request.task_queue_metadata = TaskQueueMetadata()
                polling_request.task_queue_metadata.max_tasks_per_second = 200000
                polling_request.namespace = worker.namespace
                polling_request.identity = get_identity()
                polling_request.task_queue = TaskQueue()
                polling_request.task_queue.name = worker.task_queue
                task: PollActivityTaskQueueResponse
                task = await service.poll_activity_task_queue(
                    request=polling_request)
                polling_end = datetime.datetime.now()
                logger.debug("PollActivityTaskQueue: %dms",
                             (polling_end - polling_start).total_seconds() *
                             1000)
            except StopRequestedException:
                return
            except GRPCError as ex:
                logger.error("Error invoking poll_activity_task_queue: %s",
                             ex,
                             exc_info=True)
                continue
            task_token = task.task_token
            if not task_token:
                logger.debug(
                    "PollActivityTaskQueue has no task_token (expected): %s",
                    task)
                continue

            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

            args: List[object] = worker.client.data_converter.from_payloads(
                task.input, get_fn_args_type_hints(fn))

            process_start = datetime.datetime.now()
            activity_context = ActivityContext()
            activity_context.client = worker.client
            activity_context.activity_task = ActivityTask.from_poll_for_activity_task_response(
                task)
            activity_context.namespace = worker.namespace
            try:
                ActivityContext.set(activity_context)
                if inspect.iscoroutinefunction(fn):
                    return_value = await fn(*args)
                else:
                    raise Exception(
                        f"Activity method {fn.__module__}.{fn.__qualname__} should be a coroutine"
                    )
                if activity_context.do_not_complete:
                    logger.info(
                        f"Not completing activity {task.activity_type.name}({str(args)[1:-1]})"
                    )
                    continue

                logger.info(
                    f"Activity {task.activity_type.name}({str(args)[1:-1]}) returned {return_value}"
                )

                try:
                    await complete(worker.client, task_token, return_value)
                except GRPCError as ex:
                    logger.error(
                        "Error invoking respond_activity_task_completed: %s",
                        ex,
                        exc_info=True)
            except Exception as ex:
                logger.error(
                    f"Activity {task.activity_type.name} failed: {type(ex).__name__}({ex})",
                    exc_info=True)
                try:
                    await complete_exceptionally(worker.client, task_token, ex)
                except GRPCError as ex2:
                    logger.error(
                        "Error invoking respond_activity_task_failed: %s",
                        ex2,
                        exc_info=True)
            finally:
                ActivityContext.set(None)
                process_end = datetime.datetime.now()
                logger.info("Process ActivityTask: %dms",
                            (process_end - process_start).total_seconds() *
                            1000)
    finally:
        worker.notify_thread_stopped()
        logger.info("Activity loop ended")
async def activity_task_loop_func(worker: Worker):
    service: WorkflowService = create_workflow_service(worker.host, worker.port, timeout=worker.get_timeout())
    worker.manage_service(service)
    logger.info(f"Activity task worker started: {get_identity()}")
    try:
        while True:
            if worker.is_stop_requested():
                return
            try:
                polling_start = datetime.datetime.now()
                polling_request: PollActivityTaskQueueRequest = PollActivityTaskQueueRequest()
                polling_request.task_queue_metadata = TaskQueueMetadata()
                polling_request.task_queue_metadata.max_tasks_per_second = 200000
                polling_request.namespace = worker.namespace
                polling_request.identity = get_identity()
                polling_request.task_queue = TaskQueue()
                polling_request.task_queue.name = worker.task_queue
                task: PollActivityTaskQueueResponse
                task = await service.poll_activity_task_queue(request=polling_request)
                polling_end = datetime.datetime.now()
                logger.debug("PollActivityTaskQueue: %dms", (polling_end - polling_start).total_seconds() * 1000)
            except StopRequestedException:
                return
            except GRPCError as ex:
                logger.error("Error invoking poll_activity_task_queue: %s", ex, exc_info=True)
                continue
            task_token = task.task_token
            if not task_token:
                logger.debug("PollActivityTaskQueue has no task_token (expected): %s", task)
                continue

            args: List[object] = from_payloads(task.input)
            print(args)
            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.namespace = worker.namespace
            try:
                ActivityContext.set(activity_context)
                if inspect.iscoroutinefunction(fn):
                    return_value = await fn(*args)
                else:
                    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

                logger.info(
                    f"Activity {task.activity_type.name}({str(args)[1:-1]}) returned {json.dumps(return_value)}")

                try:
                    await complete(service, task_token, return_value)
                except GRPCError as ex:
                    logger.error("Error invoking respond_activity_task_completed: %s", ex, exc_info=True)
            except Exception as ex:
                logger.error(f"Activity {task.activity_type.name} failed: {type(ex).__name__}({ex})", exc_info=True)
                try:
                    await complete_exceptionally(service, task_token, ex)
                except GRPCError as ex2:
                    logger.error("Error invoking respond_activity_task_failed: %s", ex2, exc_info=True)
            finally:
                ActivityContext.set(None)
                process_end = datetime.datetime.now()
                logger.info("Process ActivityTask: %dms", (process_end - process_start).total_seconds() * 1000)
    finally:
        # noinspection PyBroadException
        try:
            service.channel.close()
        except Exception:
            logger.warning("service.close() failed", exc_info=True)
        worker.notify_thread_stopped()
        logger.info("Activity loop ended")
示例#9
0
async def complete(service, task_token, return_value: object):
    respond = RespondActivityTaskCompletedRequest()
    respond.task_token = task_token
    respond.result = to_payloads([return_value])
    respond.identity = get_identity()
    await service.respond_activity_task_completed(request=respond)