I currently have a couple Task
's that are responsible for sending some emails. In the event of a server restart, I’d like to be able to pull all the records from my database that still need emails to be sent and then start some Task
's to finish the job.
What is the best way to spawn Task
's when the supervisor restarts? Does it make sense to use something other than Task
and Task.Supervisor
?
Sure, you can do this. Simply pass a Task
as one of your worker
s like this:
defmodule MySupervisor do
use Supervisor
def init([]) do
tasks = [fn -> do_something() end]
children = [
worker(Task, tasks, restart: :transient),
]
supervise(children, strategy: :one_for_one)
end
end
This will start the tasks and, by using :transient
option, they will be performed just once after the supervisor starts its children. I hope this answers your question ![:slight_smile: :slight_smile:](https://elixirforum.com/images/emoji/apple/slight_smile.png?v=9)
3 Likes
I’ve been playing around with this a little bit and it’s starting to make sense. If I want my tasks to be supervised would I need multiple supervisors? One for finishing unfinished tasks I pull from the database and another for supervising new tasks?
1 Like
You may give your Supervisor a name and add children to the supervision tree directly from your worker.
defmodule Worker do
...
import Supervisor.Spec
defp something do
[] # list of emails to be sent(?)
|> Enum.map(
fn data ->
Supervisor.start_child(
MySupervisor,
worker(Task, data) # Supervisor.Spec.worker
)
end
)
end
...
end
1 Like
Is this possible with a :one_for_one
supervisor? I tried playing around with something like this yesterday but was only able to get it working for :simple_one_for_one
.
1 Like
@satom99 I think I got this working.
Thanks, @mkaszubowski and @satom99 for your help!
1 Like