I have the following in my application.ex:
def start(_type, _args) do
children = [
...
{Task.Supervisor, name: Amplify.UpdateMetaAudiencesSupervisor}
]
opts = [strategy: :one_for_one, name: Amplify.Supervisor]
Supervisor.start_link(children, opts)
end
Then in my controller method I have:
Task.Supervisor.async(Amplify.UpdateMetaAudiencesSupervisor, fn ->
IO.inspect("Inside async") # this prints fine
Amplify.Context.Audiences.get_audiences() # this makes a DB call
IO.inspect("After DB call") # never gets printed and no SQL logs
end)
end)
I don’t see any SQL statements being printed for the DB call and even if I put raise "error"
inside the get_audiences()
, I see no error messages in the logs.
How can I perform DB operations inside a Task.Supervisor
(and have them printed to logs)?
Nothing immediately jumps to mind, could you share parts of the Amplify.Context.Audiences.get_audiences()
function source?
Thank you for responding.
Here it is:
def get_audiences() do
IO.inspect("this will print")
Audience
|> preload([:ad_platform_account, :venues, :participants, :products])
|> Repo.all()
|> IO.inspect() # this will not print
end
Is the Repo started when You start your supervisor?
The supervisor is listed after the Repo, so yes?
children = [
AmplifyWeb.Telemetry,
Amplify.Repo,
{OpenIDConnect.Worker, Application.get_env(:amplify, :openid_connect_providers)},
{DNSCluster, query: Application.get_env(:amplify, :dns_cluster_query) || :ignore},
{Phoenix.PubSub, name: Amplify.PubSub},
Lapin.Supervisor,
{Finch, name: Amplify.Finch},
{Task.Supervisor, name: Amplify.UpdateMetaAudiencesSupervisor},
AmplifyWeb.Endpoint
]
The router.ex has this:
scope "/public", AmplifyWeb do
get "/audiences/update", MetaController, :update_meta_audiences
end
I got this to work with Task.Supervisor.async_nolink()
instead of Task.Supervisor.async()
but I’m not fully understanding why that is working for me.
My guess: Task.Supervisor.async
still links the Task
to the calling process - in the case of the controller, that’s the request handler process. When the request finishes, that process exits and the Task
is terminated.
2 Likes
Thank you. That makes sense to me.
You are better off having a dedicated supervisor just for these tasks. As @al2o3cr pointed out, you were linking them to the process of the request and that ends quickly very often.
1 Like