<@ULVA73B9P> when a flow is cancelled from UI, i w...
# ask-marvin
r
@Marvin when a flow is cancelled from UI, i want to perform certain actions before flow is marked cancelled.
m
thought for 167.9 seconds
Great question. In Prefect 3.x you have a few good options to run cleanup when a flow is cancelled from the UI: 1) Use a flow state hook (recommended) - The
flow
decorator accepts
on_cancellation
hooks. These are invoked during cancellation handling and awaited as part of the flow’s teardown, so your code runs reliably when a cancel is requested.
Copy code
from prefect import flow, get_run_logger

async def cleanup_on_cancel(flow, flow_run, state):
    logger = get_run_logger()
    <http://logger.info|logger.info>(f"Cleaning up for run {flow_run.id} (state={state.type})")
    # release locks, close external sessions, notify, etc.

@flow(on_cancellation=cleanup_on_cancel)
def my_flow():
    # your flow logic
    ...
Notes: - The hook receives
(flow, flow_run, state)
. - You can pass a single callable or a list of callables. - Hooks are for side-effects; they don’t change the final state (the run will still end as Cancelled). 2) Add try/finally in your flow body for in-process cleanup - This ensures cleanup runs even if your logic is interrupted by cancellation:
Copy code
from prefect import flow
from prefect.exceptions import CancelledRun

@flow
def my_flow():
    try:
        # long-running work
        ...
    except CancelledRun:
        # optional: handle cancellation-specific paths
        ...
        raise
    finally:
        # always-run cleanup (files, temp dirs, unlocks, etc.)
        ...
3) Trigger cleanup externally via Automations - If you want cleanup to run outside the flow’s process (more reliable if the worker/container is terminated), create an Automation that triggers on the flow-run transitioning to “Cancelling” and executes a “Call Webhook” or runs another deployment that performs cleanup. A couple of caveats: - If the underlying infrastructure hard-kills the process (e.g., container eviction), in-process hooks/cleanup may not run. For that scenario, prefer Automations or ensure your infra has a sufficient termination grace period. - If you’re also cancelling long-running tasks, apply similar patterns at the task level (task state hooks or try/finally) to guarantee their cleanup. Would you like help wiring a specific cleanup (e.g., releasing a DB lock, revoking a token, stopping a job in an external system)? If you can share your actions and environment (worker type, infra), I can tailor an example.