[英]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.