In writing this message I think I got there myself...
# ask-community
t
In writing this message I think I got there myself, but since I typed it (and prototyped it in code) I figure I will ask anyway. A question for the Prefect devs and other users. What is the rational on a
@task
decorated function blocking when calling it as is, e.g.
Copy code
@task 
def square_num(a):
    return a**2

@flow 
def main_flow():
    squares = [square_num(i) for i in range(4)]
here each time
square_num
is called in the loop, it is not a
PrefectFuture
that is stored, it is the evaluated number. To get the behaviour that is similar to the
@dask.delayed
type decorated function, the
.submit
method should be used. I ask this question after mocking up a port of a
dask
workflow over to
prefect
. If the
__call__
of a
Task
instance behaved similar to its
submit
method, the conversion would basically be as simple as replacing
@delayed
with
@task
and calling it a day, I mocked up a extra
Task
keyword argument in my own
prefect
fork called
block_on_call
, and could tweak this
__call__
vs
.submit()
behaviour on a per
@task
basis. Maybe it is because of my previous
dask
exposure, but this kind of feels more natural to me, and kind of makes this toy porting problem pretty effortless. Is it a case that the current
Task.__call__
behaviour is to support a DAG-less type use case/style? Would there be much interest in a pull request of the above make sense/be useful, or am I missing the larger intent here? Does my rambling make sense?
🙏 1
r
I believe calling tasks directly did return futures in early Prefect 2 alpha and beta releases, but it changed to the current behaviour in 2.0b9. You can read the rationale [here]{https://github.com/PrefectHQ/prefect/blob/main/RELEASE-NOTES.md#code-as-workflows), but the short version is that many users found returning a future confusing. Since calling a task just looks like calling any other Python function, users expected that calling a task would return the same result they'd get if the function weren't wrapped by the
@task
decorator.
t
Thanks Ryan, especially for the link! My confusion with the current behaviour is why not just not apply a
@task
to a function and call the function as it is written without prefect involved? The net effect is the same, modulo the monitoring on the prefect server. My initial feeling would have been the concurrent processing that prefect provides would be more valued than the monitoring in a blocking type mode. But I say all this as one user - and I really hope that I am not a painful one! My little patch in my own test environment can revert this behaviour on a per-task basis, with the default behaviour being what is currently implement, i.e. The old behaviour is only used when
@task(block_on_call=False)
which is not the default. I would be happy to submit a pull request for review if it makes sense
I've raised a pull request: https://github.com/PrefectHQ/prefect/pull/10041 If for nothing else that there is a record for discussion.