问题描述
在我的 opt 应用程序中,我有一些东西可以在应用程序启动时运行:
defmodule MyApp.Application do
use Application
def start(_type,_args) do
children = [
{Phoenix.PubSub,[name: MyApp.PubSub,adapter: Phoenix.PubSub.PG2]},{MyAppLib.Repo,[]},{MyAppWeb.Endpoint,{MyAppLib.Cache,# these are GenServer-s,some may work with a database
{MyApp.Worker1,# 1
{MyApp.Worker2,# 2
{MyApp.Initializer,[]} # 3
]
opts = [strategy: :one_for_one,name: MyApp.Supervisor]
Supervisor.start_link(children,opts)
end
但是,我发现每当我在新服务器上部署应用程序时,它都会无法启动,因为尚未创建数据库。即使通过控制台启动应用程序也无法解决问题,因为它仍然会因同样的原因崩溃。
如何解决?
我是否应该引入一个布尔环境。变量“disable_db_related_workers”只有在第一次在新服务器上运行应用程序时我才设置为“true”?然后我会运行控制台并从中运行迁移。
$ MIX_ENV=prod disABLE_DB_WORKERS=true ~/my_apps/my_app1/bin/my_app1 console
如果是这样,那么如何在 Application
中正确执行此操作?它必须在运行时进行评估,而不是在编译时。
解决方法
Ecto.Migrator.up/4
是您的朋友。
它可以直接从 Application.start/2
调用,因为它是幂等的。它可能在部署后立即启动应用程序之前被调用。
除了这个建议之外,真正的实现实际上是一个品味问题。