2017-08-06 17 views
1

データサイズに応じて相対的に長い時間がかかるcsv形式でデータを保存するモジュールがあります。これを非同期的に達成するエリクシールの方法は何ですか?エージェントを使ってみましたが、処理がタイムアウトしました。Elixirで長時間実行されているタスクを非同期に実行する

enter image description here

defmodule FinReporting.Export_CSV do 
    alias FinReporting.DistributeRepo 
    alias FinReporting.InterfaceMdl 
    import Ecto.Query 

    def start_link do 
     Agent.start_link(fn -> HashDict.new end, name: __MODULE__) 
    end 

    def export do 
     Agent.update(__MODULE__, fn dict -> 

            export_sub()  
           end) 
    end 

    defp export_sub do 
     file = File.open!("test.csv",[:write, :utf8]) 
     IO.puts("===> CSV export of NGInterface file started.") 
     DistributeRepo.all(from entry in InterfaceMdl, limit: 100000, select: %{ field1: entry.field1, amount: entry.amount}) 
       |>Enum.map(fn(entry)-> %{entry|amount: Decimal.to_string(entry.amount)}end) 
       |> Enum.map(fn(m) -> [m.field1, m.amount] end) 
       |> CSV.encode 
       |> Enum.each(&IO.write(file, &1)) 

     IO.puts("===> CSV export of NGInterface file completed.") 
     _ = File.close(file) 
    end 
end 

答えて

4

あなたはAgent.updateに第三引数を使用してカスタムのタイムアウトを指定することができます。ミリ秒数を指定する整数を渡すことができます。 60000を1分間、無限のタイムアウトを:infinityに設定します。

Agent.update(__MODULE__, fn dict -> export_sub() end, 60000) 

しかし、あなたが望むものではありませんこれは、実行を完了するための機能のためのAgent.update待機。

Task、具体的にはTask.async/1が必要です。

Task.async(fn -> export_sub() end) 

これはTask.awaitを使用して、アプリケーションの後半で待つか、Task.yieldを使用して、そのステータスを求めることができTask構造体を返します。これ以上のことは、the documentation of Taskで詳細に説明されています。

関連する問題