What is the simplest way to call the function loading some data from the database on Phoenix app start? So I need my function to have Ecto.Query goodness at it's disposal and been called before the Phoenix started serving any requests.
You can start a worker at startup time between your Repo and Endpoint supervisors in my_app/application.ex:
# Define workers and child supervisors to be supervised
children = [
# Start the Ecto repository
supervisor(MyApp.Repo, []),
# The new worker
worker(MyApp.DoSomething, [], restart: :temporary),
# Start the endpoint when the application starts
supervisor(MyAppWeb.Endpoint, []),
# Start your own worker by calling: MyApp.Worker.start_link(arg1, arg2, arg3)
# worker(MyApp.Worker, [arg1, arg2, arg3]),
]
And create a file my_app/do_something.ex:
defmodule MyApp.DoSomething do
use GenServer
def start_link do
GenServer.start_link(__MODULE__, %{})
end
@impl true
def init(state) do
user = MyApp.Accounts.get_user!(1)
IO.inspect user
Process.sleep(10_000)
IO.inspect "Done sleeping"
# Process will send :timeout to self after 1 second
{:ok, state, 1_000}
end
@impl true
def handle_info(:timeout, state) do
# Stop this process, because it's temporary it will not be restarted
IO.inspect "Terminating DoSomething"
{:stop, :normal, state}
end
end
At startup time, you should see some info printed about the user and after a 10 second delay: Running MyAppWeb.Endpoint with Cowboy using http://0.0.0.0:4000.
I'm not 100% sure if this is the best and safest way to do this (perhaps a GenServer is not needed at all?), but it works. The repo is available in the worker and the endpoint does not start until init has returned.
Edit: I've updated the code to (hopefully) correctly shutdown the process when it's done.
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