I wrote a module SC in my Elixir script, wget.exs
. The module SC
utilizes Erlang's OS module to execute complex commands and print their output on the screen. I use the module in my script to download many packages at once with wget
:
#!/usr/bin/env elixir
defmodule SC do
def run(cmmnd) do
output = :os.cmd(String.to_charlist(cmmnd))
IO.puts output
end
end
defmodule Downloader do
def download_packages do
lst_f_pckgs = "wget-list-sysv"
#System.cmd("wget", ["https://www.linuxfromscratch.org/lfs/view/stable/#{lst_f_pckgs}"])
SC.run("wget -c https://www.linuxfromscratch.org/lfs/view/stable/#{lst_f_pckgs}")
{:ok, file_content} = File.read(lst_f_pckgs)
arr_f_pckgs = String.split(file_content, ~r/\s+/)
tasks =
arr_f_pckgs
|> Enum.map(fn l ->
#Task.async(fn -> System.cmd("wget", [l]) end)
Task.async(fn -> SC.run("wget -c #{l}") end)
end)
tasks
|> Enum.each(&Task.await/1)
IO.puts "All of them are downloaded."
end
end
Downloader.download_packages()
The script is meant fist to download a text file that contains a list of packages to download, this part of the script works fine, and then in meant to proceed to download all the packages in parallel. When utilizing my module SC
the scripts starts downloading but then it exits and I get the following output:
5550K .......... .......... .......... .......... .......... 98% 11.6M 0s
5600K .......... .......... .......... .......... .......... 99% 457K 0s
5650K .......... .......... .. 100% 145M=8.1s
2024-01-15 13:38:05 (702 KB/s) - ‘coreutils-9.3.tar.xz’ saved [5808696/5808696]
--2024-01-15 13:37:56-- https://github.com/systemd/systemd/archive/v254/systemd-254.tar.gz
Resolving github.com (github.com)... 140.82.121.3
Connecting to github.com (github.com)|140.82.121.3|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/systemd/systemd/tar.gz/refs/tags/v254 [following]
--2024-01-15 13:37:56-- https://codeload.github.com/systemd/systemd/tar.gz/refs/tags/v254
Resolving codeload.github.com (codeload.github.com)... 140.82.121.10
Connecting to codeload.github.com (codeload.github.com)|140.82.121.10|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-gzip]
Saving to: ‘systemd-254.tar.gz’
0K .......... .......... .......... .......... .......... 267K
50K .......... .......... .......... .......... .......... 27.2M
100K .......... .......... .......... .......... .......... 442K
150K .......... .......... .......... .......... .......... 202K
[many similar lines]
8.10M 0s
6200K .......... .......... .......... .......... .......... 97% 31.7M 0s
6250K .......... .......... .......... .......... .......... 98% 1.48M 0s
6300K .......... .......... .......... .......... .......... 98% 700K 0s
6350K .......... .......... .......... .......... .......... 99% 5.73M 0s
6400K .......... .......... ....... 100% 460M=10s
2024-01-15 13:38:07 (639 KB/s) - ‘grub-2.06.tar.xz’ saved [6581924/6581924]
** (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)
** (EXIT) time out
(elixir 1.14.0) lib/task.ex:830: Task.await/2
(elixir 1.14.0) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2
wget.exs:28: Downloader.download_packages/0
Whereas if I utilize Elixir's System module the script does its job and prints
"All of them are downloaded."` to the screen.
The error returned is:
exited in: Task.await(..., 5000)
** (EXIT) time out
The default timeout for Task.await
is 5 seconds. Presumably downloading a bunch of files takes longer than that.
Increase the timout to some reasonable value for your use case or :infinity
if you don't want to timeout.
|> Enum.each(&Task.await(&1, :infinity))