LoginSignup
15
13

More than 5 years have passed since last update.

Elixirで試しに何か書いてみる(その4) - Taskを使って簡単にする

Last updated at Posted at 2015-08-02

Elixirで試しに何か書いてみる(その3) - Elixirのアプリケーションでアプリの形にしたんですが、肝心のプロセス起動と結果の取得を「手探りの状態で」書いたままにしていました。

naoya@githubさんがElixir のプロセスを使ってフェイルセーフなアプリケーションを作る ─ 失敗は恐れず泥水にダイブおまけのところでTaskを使ってプロセスの並行処理を簡単に記述する方法を書いてくださったので取り入れてみました。

2015.8.29追記:Timexを最新にするとDate.localの仕様が変わっていて時刻の変換ができないことがわかったので(thanks shibacowさん)、GitHub上のコードを修正しました。

更に続く
Elixirで試しに何か書いてみる(その5) - 失敗したらやり直す


変えたところ

もともと、VercheckEx.main/1の中でプロセスをspawn_link/1で個別に起動しPIDを配列に入れて、それぞれのPIDに対して引数をsendし、VercheckEx.receiverで結果を受信していた…あーややこしい…ところを以下のようにEnum.mapとパイプ演算子でまとめちゃいました。

前のバージョン

  def main(args) do
    urls = [ #{ URL, type, index}
      {"https://github.com/jquery/jquery/releases", :type1},
# (...長いので略)
      {"https://github.com/takscape/elixir-array/releases", :type2},
    ]

    # Spawn processes upto the number of URLs
    fetchers = for _ <- 0..length(urls), do: spawn_link fn -> VercheckEx.fetch_content() end

    Enum.with_index(urls)|>Enum.each( fn(x) ->
      {{u,t},i} = x
      send Enum.at(fetchers,i), {self, u, t, i}
    end)

    result_list = []
    VercheckEx.receiver(result_list, length(urls))

  end

変更後


  def main(args) do
    urls = [ #{ URL, type, index}
      {"https://github.com/jquery/jquery/releases", :type1},
# (...長いので略)
      {"https://github.com/takscape/elixir-array/releases", :type2},
    ]

    urls
    |> Enum.with_index
    |> Enum.map(&(Task.async(fn -> fetch_content(&1) end)))
    |> Enum.map(&(Task.await/1))
    |> Enum.sort(fn(a,b) ->
      {:ok, {_, _, _, i1}} = a
      {:ok, {_, _, _, i2}} = b
      i1 < i2
    end
    )
    |> Enum.map(&put_a_formatted_line/1)

  end

あとはもともと引数を変に組み立てなおしていたところを「ありのままで」使うようにした、とか結果が帰ってきてからソートする部分を追加した、などがありますが、全体として
* プロセス起動のための部分がEnum.map/2Task.async/1で書けた
* PIDを明示的に管理する必要がなくなった
* 結果を受け取るVercheckEx.receiverがいらなくなった
などかなりすっきりしました。

全体のソースはgithubにあります。

まとめ

やっぱり「用意されているものをちゃんと使う」ことは大事ですね。前回のスクリプトをアプリケーションにする方法もそうでしたがElixirの場合、探してみるとほんとにいろいろうまい仕組みが用意されているので早く「試しに何か書いてみた」の段階から前に進みたいものだなあと思いました。

15
13
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13