簡體   English   中英

在elixir phoenix應用程序中創建后台作業的正確方法

[英]Right way to create a background job in an elixir phoenix app

  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

在此控制器操作中, UserMailer.send_welcome_email是同步的,請求等待。

我想讓它異步,所以產生了這樣的過程

spawn_link(fn ->
  UserMailer.send_welcome_email(user)
end)

請求不會等到郵件發送完畢。

  • 雖然它有效但是它是正確的方法嗎?
  • 這些過程是否有可能成為孤兒,或者他們只是在立即執行后死亡?
  • 我們應該創建一個Supervisor嗎?
  • 我們應該使用像https://github.com/akira/exq這樣的庫嗎? (我覺得即使spawn_link失敗,並將其記錄在我們的鳳凰日志中,它會這樣做)

使用spawn_link/1啟動一個進程會產生一個雙向鏈接,因此無論哪個產生進程和剛出現的進程都會先殺死另一個進程(除非它捕獲退出,它可能不應該是)。 在某些情況下這很好,在其他情況下則不是那么好; 例如,如果發送該電子郵件需要很長時間,那么Phoenix請求可能會先完成,並且可能會導致生成的進程被終止。

但是,由於鏈接,不應該有任何進程成為孤兒的風險。

一個更好的方法肯定是創建一個Supervisor (或使用Task.Supervisor ),你可以很容易地滾動你自己的后台作業設置。

但是,可能值得看看你提到的exq ,或者例如Toniq ,它可能已經擁有你需要的一切; 尤其是在失敗和重生的情況下重試的事情。 如果你想嘗試一些不同的選擇,在Awesome Elixir列表中還有一些其他有趣的選項。

我相信你可以簡單地使用spawn\\3並且它會完成這項工作,但問題在於,正如Johan所提到的,不會有任何重試或界面來追蹤工作等所以你是最好使用外部庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM