In my Phoenix app, I have a module function like Reviews.create(attributes)
. It does some work immediately, and starts a task (using Task.async
) to do additional work.
I can test it like this:
{:ok, new_review, task} = Reviews.create(attrs)
# verify that new_review is correct
Task.await(task)
# verify that the task did what it should
However, the main place I want to use Reviews.create/1
is from a controller. From there, I want to treat the task as "fire and forget". This is simple: I just don't call Task.await
.
This works fine, except that when I test the controller, I get errors like:
[error] Postgrex.Protocol (#PID<0.344.0>) disconnected: **
(DBConnection.ConnectionError) owner #PID<0.753.0> exited
while client #PID<0.755.0> is still running with: shutdown
In other words, it's telling me that the task got killed when the controller test ended. Which I don't care about.
Is there some way to make this more explicitly "fire and forget"? Eg, it would be nice if, from the controller, I could call Task.forget_about(task)
, but that doesn't exist.
You will want to use Task.start/1
instead. It basically acts the same way, it just runs your function in a different process, but it will not be linked in any way to the process that spawns it.
Directly from the documentation
This is only used when the task is used for side-effects (i.e. no interest in the returned result) and it should not be linked to the current process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With