传递一个环境。动态变量到应用程序模块,在运行时?
Posted
技术标签:
【中文标题】传递一个环境。动态变量到应用程序模块,在运行时?【英文标题】:Passing an env. variable dynamically to Application module, at runtime? 【发布时间】:2021-09-22 04:45:29 【问题描述】:在我的 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
中正确执行此操作?它必须在运行时进行评估,而不是在编译时。
【问题讨论】:
【参考方案1】:Ecto.Migrator.up/4
是你的朋友。
它可能会直接从Application.start/2
调用,因为它是幂等的。它可能在部署后立即启动应用程序之前调用。
除了这个建议之外,真正的实现实际上是一个品味问题。
【讨论】:
我已经有一个运行迁移的模块,它是代码中提到的那些“工人”之一。也就是说,它必须在 Application 的哪个位置被准确地调用?作为start(_type, _args)
的第一个命令?
开始回购之前。第一行有效,是的。
我不确定这在未创建数据库时是否会有所帮助,我们有一个使用 repo.__adapter__.storage_up/1 的服务器,但我通常会手动创建数据库。
@Daniel 问题明确指出问题与迁移有关。但是,是的,通常您的评论完全有道理。以上是关于传递一个环境。动态变量到应用程序模块,在运行时?的主要内容,如果未能解决你的问题,请参考以下文章