[英]Calling function on Phoenix app start
在Phoenix应用程序启动时,调用该函数从数据库加载一些数据的最简单方法是什么? 因此,我需要我的函数拥有Ecto.Query优良性,并在Phoenix开始处理任何请求之前调用它。
您可以在启动时在Repo
和Endpoint
主管之间的my_app/application.ex
中启动工作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]),
]
并创建一个文件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
在启动时,您应该在10秒钟的延迟后看到一些有关用户的信息: Running MyAppWeb.Endpoint with Cowboy using http://0.0.0.0:4000
。
我不确定这是否是最好,最安全的方法(也许根本不需要GenServer吗?),但还是可以100%确定。 该回购在工作进程中可用,并且端点在init
返回之前不会启动。
编辑:我已经更新了代码,以(希望)完成后正确关闭该过程。
除了@zwippie很棒的答案外,我还对自己的问题给出了自己的答案,这是更通用的OTP标准,但我的却更简单,可以在某些情况下使用。
要在Phoenix端点开始服务请求之前立即调用该函数,我们可以从应用程序的Endpoint模块的init()回调中调用该函数,该回调在Ecto.Repo.Supervisor启动Ecto.Repo工作器之后立即调用。
因此,如果我们有:my_app应用程序,则可以打开lib / my_app_web / endpoint.ex文件,在其中找到回调函数init()并从那里调用某些函数。
这篇不错的文章还总结了第三种方法,即使用Task
模块。 它省去了编写完整的Genserver的麻烦:
defmodule Danny.Application do
use Application
# ...
def start(_type, _args) do
children = [
supervisor(Danny.Repo, []),
# ...
worker(Task, [&CacheWarmer.warm/0], restart: :temporary) # this worker starts, does its thing and dies
# ...
]
opts = [strategy: :one_for_one, name: Danny.Supervisor]
Supervisor.start_link(children, opts)
end
end
定义一个模块:
defmodule CacheWarmer do
import Logger, only: [debug: 1]
def warm do
# warming the caches
debug "warming the cache"
# ...
debug "finished warming the cache, shutting down"
end
end
请注意, your_app.ex
唯一的附加行是: worker(Task, [&CacheWarmer.warm/0], restart: :temporary)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.