【发布时间】:2019-01-13 14:59:49
【问题描述】:
我已经实现了一个 GenServer,它通过长轮询来监听外部消息队列。为此,我在应用程序启动时启动 GenServer,即在我的 application.ex 文件的 start/2 函数中,我在主管列表中指定了一个额外的孩子:
children = [
supervisor(MyApp.Repo []),
supervisor(MyAppWeb.Endpoint, []),
supervisor(MyApp.MessageQueueGenServer, [])
]
然后此列表开始于:
Supervisor.start_link(children, [strategy: :one_for_one, name: MyApp.Supervisor])
现在我遇到的问题是,当我使用 mix ecto.reset 运行一些 (1) 数据库设置或使用 (2) 测试时,GenServer 当然也会启动mix test。
对于测试 (2) 我可以,例如如果Mix.env != :test,则仅将MyApp.MessageQueueGenServer 添加到children 列表中。
但是 (1) 呢?运行mix ecto.reset/mix ecto.setup/etc.时如何避免启动我的GenServer?
【问题讨论】:
-
为什么你开始这个
GenServer很重要?在这些情况下不启动它会得到什么? -
因为即使我只想运行一些数据库迁移,我也总是必须确保消息队列正在运行并且可以访问。
-
Elixir / Erlang 中的进程非常轻量级。如果您从启动中删除了该服务器,您甚至不会注意到。至于数据库迁移,运行混合任务实际上不会启动您的应用程序。这意味着服务器未启动。 mix ecto 任务只启动他们需要的东西。
-
首先,感谢您到目前为止提供的帮助。我的消息队列是一个外部队列,很遗憾没有 Erlang 进程。关于数据库迁移:让我在这里更准确地说,
ecto.setup是 .e.g. 的别名。run priv/repo/seeds.exs启动 GenServer。 -
所有
GenServers 都是 Erlang 进程。您可以将实际连接到队列作为从服务器的 init 函数发送的消息。这也将允许您以您想要的方式处理重新连接,而用户甚至不知道发生了什么问题。这是在 BEAM 上处理外部连接的一种相当常见的方式。