为什么这个 Elixir 脚本在完成其工作之前就退出了?

Jer*_*ska 2 concurrency erlang elixir spawn

我在 Elixir 脚本中编写了一个模块 SC wget.exs,. 该模块SC 利用 Erlang 的操作系统模块来执行复杂的命令并将其输出打印在屏幕上。我在脚本中使用该模块一次下载多个包wget

\n
#!/usr/bin/env elixir\n\ndefmodule SC do\n  def run(cmmnd) do\n    output = :os.cmd(String.to_charlist(cmmnd))    \n    IO.puts output\n  end\nend\n\ndefmodule Downloader do\n  def download_packages do\n    lst_f_pckgs = "wget-list-sysv"\n\n    #System.cmd("wget", ["https://www.linuxfromscratch.org/lfs/view/stable/#{lst_f_pckgs}"])\n    SC.run("wget -c https://www.linuxfromscratch.org/lfs/view/stable/#{lst_f_pckgs}")\n    \n    {:ok, file_content} = File.read(lst_f_pckgs)\n    arr_f_pckgs = String.split(file_content, ~r/\\s+/)\n\n    tasks =\n      arr_f_pckgs\n      |> Enum.map(fn l ->\n        #Task.async(fn -> System.cmd("wget", [l]) end)\n        Task.async(fn -> SC.run("wget -c #{l}") end)\n      end)\n\n    tasks\n    |> Enum.each(&Task.await/1)\n\n    IO.puts "All of them are downloaded."\n  end\nend\n\nDownloader.download_packages()\n\n\n
Run Code Online (Sandbox Code Playgroud)\n

该脚本首先要下载一个文本文件,其中包含要下载的软件包列表,这部分脚本工作正常,然后继续并行下载所有软件包。当使用我的模块时,SC脚本开始下载,但随后退出,我得到以下输出:

\n
  5550K .......... .......... .......... .......... .......... 98% 11.6M 0s\n  5600K .......... .......... .......... .......... .......... 99%  457K 0s\n  5650K .......... .......... ..                              100%  145M=8.1s\n\n2024-01-15 13:38:05 (702 KB/s) - \xe2\x80\x98coreutils-9.3.tar.xz\xe2\x80\x99 saved [5808696/5808696]\n\n\n--2024-01-15 13:37:56--  https://github.com/systemd/systemd/archive/v254/systemd-254.tar.gz\nResolving github.com (github.com)... 140.82.121.3\nConnecting to github.com (github.com)|140.82.121.3|:443... connected.\nHTTP request sent, awaiting response... 302 Found\nLocation: https://codeload.github.com/systemd/systemd/tar.gz/refs/tags/v254 [following]\n--2024-01-15 13:37:56--  https://codeload.github.com/systemd/systemd/tar.gz/refs/tags/v254\nResolving codeload.github.com (codeload.github.com)... 140.82.121.10\nConnecting to codeload.github.com (codeload.github.com)|140.82.121.10|:443... connected.\nHTTP request sent, awaiting response... 200 OK\nLength: unspecified [application/x-gzip]\nSaving to: \xe2\x80\x98systemd-254.tar.gz\xe2\x80\x99\n\n     0K .......... .......... .......... .......... ..........  267K\n    50K .......... .......... .......... .......... .......... 27.2M\n   100K .......... .......... .......... .......... ..........  442K\n   150K .......... .......... .......... .......... ..........  202K\n[many similar lines]\n8.10M 0s\n  6200K .......... .......... .......... .......... .......... 97% 31.7M 0s\n  6250K .......... .......... .......... .......... .......... 98% 1.48M 0s\n  6300K .......... .......... .......... .......... .......... 98%  700K 0s\n  6350K .......... .......... .......... .......... .......... 99% 5.73M 0s\n  6400K .......... .......... .......                         100%  460M=10s\n\n2024-01-15 13:38:07 (639 KB/s) - \xe2\x80\x98grub-2.06.tar.xz\xe2\x80\x99 saved [6581924/6581924]\n\n\n** (exit) exited in: Task.await(%Task{mfa: {:erlang, :apply, 2}, owner: #PID<0.96.0>, pid: #PID<0.110.0>, ref: #Reference<0.1214714622.3043557380.75212>}, 5000)\n    ** (EXIT) time out\n    (elixir 1.14.0) lib/task.ex:830: Task.await/2\n    (elixir 1.14.0) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2\n    wget.exs:28: Downloader.download_packages/0\n\n
Run Code Online (Sandbox Code Playgroud)\n

而如果我使用 Elixir 的System module the script does its job and prints “所有这些都已下载。”`到屏幕上。

\n

Sii*_*ser 7

返回的错误是:

exited in: Task.await(..., 5000)
** (EXIT) time out
Run Code Online (Sandbox Code Playgroud)

默认超时时间为Task.await5 秒。大概下载一堆文件需要更长的时间。

:infinity对于您的用例或者如果您不想超时,请将超时增加到某个合理的值。

|> Enum.each(&Task.await(&1, :infinity))
Run Code Online (Sandbox Code Playgroud)