temporalio / sdk-python

Temporal Python SDK
MIT License
467 stars 72 forks source link

[Feature Request] Timeout in Workflow definition not in execution #686

Open cosminpm opened 6 days ago

cosminpm commented 6 days ago

Is your feature request related to a problem? Please describe.

I’m trying to set a timeout for a Workflow, but I’m unsure if I’m missing documentation or if this might be a feature request.

I know it’s possible to set a timeout when executing a workflow directly, like this:

result = await client.execute_workflow(
    YourWorkflow.run,
    "your timeout argument",
    id="your-workflow-id",
    task_queue="your-task-queue",
    # Set Workflow Timeout duration
    execution_timeout=timedelta(seconds=2),
    # run_timeout=timedelta(seconds=2),
    # task_timeout=timedelta(seconds=2),
)

However, I’m running into an issue: I can’t set execution_timeout when the workflow is triggered by a Schedule, as my workflows are executed by a worker:

worker = Worker(
    self.client,
    task_queue=TASK_QUEUE,
    workflows=[
        Workflow1,
        Workflow2,
        Workflow3,
    ],
    activities=[
        activity_1,
        activity_2,
        activity_3,
    ],
)

I’ve reviewed the documentation and examples, but haven’t found a way to configure a workflow timeout outside of the direct execution method.

Describe the solution you'd like

Or the workflow has a timeout parameter in the definition or the worker, both of them would solve my issue.

Additional context

N/A

cretz commented 1 day ago

This is a server side timeout set when the workflow is started, and that start is done by the internal scheduler on schedules. How are you creating the schedule? The workflow schedule action allows execution_timeout, so that's where you'd set this. Also, unless you're sure you need it, you should consider using timers inside your workflow that you can react to for timing things out instead of the server-side timeout that terminates a workflow with no recourse.

cosminpm commented 21 hours ago

Hello @cretz!

Thanks for answering.

We are creating the schedule via de UI by passing the Workflow definition which does not provide an execution timeout as far as I can see from the available parameters.

image

I'm implementing workflow timeouts due to an issue where, occasionally, our workflow remains in a "Running" status indefinitely, with zero pending activities. This occurs despite having timeouts set at the activity level, and I haven’t yet identified the root cause.

This is how I'm defining the workflows:

with workflow.unsafe.imports_passed_through():
    from app.module import activity_1

@workflow.defn
class Workflow1:
    @workflow.run
    async def run(self) -> Any:
        return await workflow.execute_activity(
            activity_1_activity,
            start_to_close_timeout=timedelta(minutes=5),
        )

@activity.defn
async def activity_1_activity() -> Any:
    return activity_1()

Am I missing something?

cretz commented 15 hours ago

We are creating the schedule via de UI

This seems to be an issue with the UI not providing every workflow option and not related to Python SDK. I will confer with the UI team to see if we have plans here. In the meantime, you could consider creating the schedule via the CLI or programmatically in the Python SDK to get the extra options you need.

I'm implementing workflow timeouts due to an issue where, occasionally, our workflow remains in a "Running" status indefinitely, with zero pending activities. This occurs despite having timeouts set at the activity level, and I haven’t yet identified the root cause.

This is worth identifying instead of just setting workflow execution timeouts. Your activity timeout is only set for each attempt (as opposed to schedule to close timeout), so a failing activity will retry indefinitely there any look like it's hanging (see the UI to see if the pending activity is performing many attempts).

Also, for general assistance with activity timeouts and such, feel free to visit our forums or #python-sdk on Slack.