我应该在哪里调用 Phoenix 中的初始化代码,这可能涉及到数据库的连接?
Where should I call initialization code in Phoenix, which might involve connection to a db?
我有一些代码需要在我的 Elixir Phoneix 应用程序启动时调用。代码的某些部分需要向数据库发出请求以检索将用于初始化的数据。
虽然我可以在
中调用正常代码——不对数据库发出任何请求的代码defmodule MyAppWeb.Endpoint do
# [............]
#
# some of my init code will go here
#
def init(...) do
# [.........]
end
end
如果我理解正确,执行数据库、HTTP 请求或类似操作的代码——可能需要花费大量时间的操作——不应从 MyAppWeb.Endpoint
这是正确的吗?如果是这样,那么我应该从哪里进行初始化的代码?
首先,不要将与 Phoenix 本身无关的代码放入它的助手中。
创建你自己的GenServer
,做任何你需要的,然后优雅地停止它。
GenServer
初始化过程分为三个阶段:
第一个在调用进程中执行,最后两个是回调,在已经启动的GenServer
进程中执行,init/1
同步并且handle_continue/2
异步。
也就是说,执行长 运行 初始化的常见做法是:
defmodule MyInit do
use GenServer
@spec start_link(opts :: keyword()) :: GenServer.on_start()
@doc "Starts the GenServer process"
def start_link(opts \ []) do
GenServer.start_link(__MODULE__, ..., name: __MODULE__)
end
@impl GenServer
@doc false
def init(:ok), do: {:ok, :ok, {:continue, :connect}}
@impl GenServer
@doc false
def handle_continue(:connect, :ok) do
do_init(...)
{:stop, :normal, nil}
end
end
并从你的监督树开始这个过程。
如果在端点启动之前完成此初始化至关重要,请将对do_init
的调用移至init/1
回调并将此GenServer
before 监督树中的端点。