https://prefect.io logo
Title
j

Jai P

05/03/2022, 3:09 PM
👋 hullo folks! have a general question about flows vs. tasks vs. just regular functions in prefect 2.0. are there any high level guidelines on where we may want to use each? i'll try to describe a scenario in the thread
:discourse: 1
👋 2
let's say we have some plain python code:
def a():
    ...

def b():
    ...

def c():
    b()

def d():
    b()
    c()
there are a number of scenarios we could structure this where some things are `@flow`s, some things are `@task`s, or there's only one flow at the top and everything else is tasks, or everything is marked as a
@flow
, etc. etc.
i guess i'm not looking for the optimal solution for the example above, but more "hey i have a function, when might i want to mark it as a task or a flow, and what are the tradeoffs of doing so"
z

Zanie

05/03/2022, 3:16 PM
A major difference is that flows block execution while tasks are run in the background.
If you call a flow, it will not return until its final state is reached. If you call a task, it returns a future immediately and the return value can be retrieved later.
j

Jai P

05/03/2022, 3:20 PM
i can trigger multiple flows in parallel though right? but maybe that adds some clarity about how much you want to deeply nest things as flows
a

Anna Geller

05/03/2022, 5:12 PM
We have this Discourse page that may help: https://discourse.prefect.io/t/are-there-any-guidelines-when-to-use-flow-vs-task-decora[…]flow-should-be-defined-at-a-task-subflow-vs-flow-level/522 I added Michael's info there. Regarding running flows in parallel, you could do:
@flow
async def main_flow():
    parallel_subflows = [subflow_1(), subflow_2(), subflow_3(), subflow_4()]
    await asyncio.gather(*parallel_subflows)
more on that here
z

Zanie

05/03/2022, 5:14 PM
We’re also likely to add an interface for running flows in parallel without using async in the future.
👍 2
🙌 1
j

Jai P

05/03/2022, 7:03 PM
amazing! and again, tasks can't call other tasks right? so if i have a situation where i'd want to, say, programmatically call some set of tasks conditionally, it may be better to have those tasks called via some function rather than a subflow, especially if i don't want the blocking behavior
so like:
@task
def a():
    ...

@task
def b(something):
    ...

def c():
    a_result = a()
    b_result = b(a_result)

@flow
def d():
    c()
where, if possible, avoid making
c
a subflow unless its absolutely necessary (maybe using a different taskrunner, or storage, or something)
z

Zanie

05/03/2022, 7:18 PM
Yep that makes sense
The tasks would still run concurrently, but only within the subflow. They’d all finish before the subflow returns.
:upvote: 1
j

Jai P

05/03/2022, 8:04 PM
gotcha gotcha, ok thanks!