Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I run "fire and forget" tasks from a controller without test warnings?

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.

like image 884
Nathan Long Avatar asked Aug 09 '17 14:08

Nathan Long


1 Answers

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.

like image 179
Justin Wood Avatar answered Sep 23 '22 23:09

Justin Wood