Vys*_*san 10 elixir phoenix-framework
def create(conn, %{"data" => %{"attributes" => user_params}}) do
changeset = User.changeset(%User{}, user_params)
case Repo.insert(changeset) do
{:ok, user} ->
UserMailer.send_welcome_email(user)
conn
|> put_status(:created)
|> render("show.json", model: user)
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(MyApp.ChangesetView, "error.json", changeset: changeset)
end
end
Run Code Online (Sandbox Code Playgroud)
在此控制器操作中,UserMailer.send_welcome_email是同步的,请求等待.
我想让它异步,所以产生了这样的过程
spawn_link(fn ->
UserMailer.send_welcome_email(user)
end)
Run Code Online (Sandbox Code Playgroud)
请求不会等到邮件发送完毕.
Supervisor吗?spawn_link失败了,也记录在我们的凤凰日志中,它会这样做)Joh*_*der 10
使用启动进程spawn_link/1将导致双向链接,因此产生进程和刚出现的进程中的任何一个将首先杀死另一个(除非它捕获退出,它可能不应该是).在某些情况下这很好,而在其他情况下则不是很好; 例如,如果发送该电子邮件需要很长时间,那么Phoenix请求可能会先完成,并且可能会导致生成的进程被终止.
但是,由于链接,不应该有任何进程成为孤儿的风险.
一个更好的方法肯定是创建一个Supervisor(或使用Task.Supervisor),你可以很容易地滚动你自己的后台作业设置.
但是,可能值得看一下exq你提到的东西,或者例如Toniq,它可能已经拥有你需要的一切; 尤其是在失败和重生的情况下重试的事情.如果你想尝试一些不同的选择,在Awesome Elixir列表中还有一些其他有趣的选项.