Elixirタスクモジュールのパワー-タスクに.主任
今では物事を少し複雑にする時間です
Task.Supervisor
といくつかのエリクサーの概念を参照してください.先に進む前に、いくつかのエリクサーベースの概念を見てみましょう.
Supervisor
A supervisor is a process that supervises other processes, which we refer to as child processes. Supervisors are used to building a hierarchical process structure called a supervision tree. Supervision trees provide fault-tolerance and encapsulate how our applications start and shutdown.
Processes
In Elixir, all code runs inside processes. Processes are isolated from each other, run concurrent to one another, and communicate via message passing.
Elixir’s processes should not be confused with operating system processes. Processes in Elixir are extremely lightweight in terms of memory and CPU (even compared to threads as used in many other programming languages). Because of this, it is not uncommon to have tens or even hundreds of thousands of processes running simultaneously.
私たちは
Task.Supervisor
関連する子を管理するプロセスを作成する.遊び場の作成
最初のステップは、監督の木と新しいエリクサーアプリケーションを作成し、ミックスの可能性についての詳細情報を見つけることができますin the official documentation .
mix new newsample --sup
作成されたものを見る時間 lib
lib/newsample
lib/newsample.ex
lib/newsample/application.ex
test
test/newsample_test.exs
test/test_helper.exs
README.md
mix.exs
今のところ私たちはlib/newsample.ex
and lib/newsample/application.ex
.番目のステップは、前の投稿から同じ機能を作成することです
lib/newsample.ex
マイナーな変更を簡単に我々のテストを実行します.爆発的なシナリオを強制するために、我々は「アルファ」値と一致しているパターンを持っています.
def say_hello("alpha" = to), do: raise("Error to say hello to #{to}")
def say_hello(to) do
IO.puts("Hello #{to}")
:ok
end
def process() do
items = ["alpha", "beta", "gama"]
Enum.map(items, fn item ->
Task.async(fn ->
say_hello(item)
end)
end)
|> Enum.map(&Task.await/1)
end
そして最後にelixir's interactive shell .iex -S mix
次に、コードを実行します.iex(1)> self
#PID<0.145.0>
iex(2)> Newsample.process
Hello beta
Hello gama
22:01:54.276 [error] Task #PID<0.148.0> started from #PID<0.145.0> terminating
** (RuntimeError) Error to say hello to alpha
(newsample 0.1.0) lib/newsample.ex:15: anonymous fn/2 in Newsample.process/1
(elixir 1.11.3) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
(elixir 1.11.3) lib/task/supervised.ex:35: Task.Supervised.reply/5
(stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Function: #Function<1.13017213/0 in Newsample.process/1>
Args: []
** (EXIT from #PID<0.145.0>) shell process exited with reason: an exception was raised:
** (RuntimeError) Error to say hello to alpha
(newsample 0.1.0) lib/newsample.ex:15: anonymous fn/2 in Newsample.process/1
(elixir 1.11.3) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
(elixir 1.11.3) lib/task/supervised.ex:35: Task.Supervised.reply/5
(stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Interactive Elixir (1.11.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> self
#PID<0.151.0>
我々が見ることができるように、上がる例外はiex
セッション.それを比較するのをチェックすることは可能ですPID
以前#PID<0.145.0>
以降#PID<0.151.0>
コードを実行します.どのように、我々はこの爆発的エラー伝播を避けますか?
今、我々は監督のタスクを使用するには、オープンしましょう
lib/newsample/application.ex
. def start(_type, _args) do
children = []
opts = [strategy: :one_for_one, name: Newsample.Supervisor]
Supervisor.start_link(children, opts)
end
をつくりましょうTask.Supervisor
子プロセスとして children = [
{Task.Supervisor, name: Newsample.TaskSupervisor}
]
そして今、この監督のタスクを使用してprocess
方法と開始async_no_link
. この子プロセスと親プロセスの間にリンクがないことを意味します. def process() do
items = ["alpha", "beta", "gama"]
Enum.map(items, fn item ->
Task.Supervisor.async_nolink(Newsample.TaskSupervisor, fn ->
say_hello(item)
end)
end)
|> Enum.map(&Task.await/1)
end
我々が再び実行するならば、すべてはこの誤り伝播なしで正しく働きます.iex(1)> self
#PID<0.158.0>
iex(2)> Newsample.process
Hello beta
Hello gama
21:04:48.200 [error] Task #PID<0.161.0> started from #PID<0.158.0> terminating
** (RuntimeError) Error to say hello to alpha
(newsample 0.1.0) lib/newsample.ex:6: Newsample.say_hello/1
(elixir 1.11.3) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
(elixir 1.11.3) lib/task/supervised.ex:35: Task.Supervised.reply/5
(stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Function: #Function<1.39266525/0 in Newsample.process/0>
Args: []
** (exit) exited in: Task.await(%Task{owner: #PID<0.158.0>, pid: #PID<0.161.0>, ref: #Reference<0.1303494724.713818114.156158>}, 5000)
** (EXIT) an exception was raised:
** (RuntimeError) Error to say hello to alpha
(newsample 0.1.0) lib/newsample.ex:6: Newsample.say_hello/1
(elixir 1.11.3) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
(elixir 1.11.3) lib/task/supervised.ex:35: Task.Supervised.reply/5
(stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
(elixir 1.11.3) lib/task.ex:639: Task.await/2
(elixir 1.11.3) lib/enum.ex:1411: Enum."-map/2-lists^map/1-0-"/2
iex(2)> self
#PID<0.158.0>
我々が見ることができるようにPID
は実行の前後で同じです.プロセスとスーパーバイザ木は、回復と耐故障システムを構築するために、エリクサーの重要な構成要素です.
Reference
この問題について(Elixirタスクモジュールのパワー-タスクに.主任), 我々は、より多くの情報をここで見つけました https://dev.to/felipearaujos/the-power-of-elixir-task-module-into-task-supervisor-5365テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol