Skip to content

Instantly share code, notes, and snippets.

@hopsor
Last active February 16, 2021 07:18
Show Gist options
  • Save hopsor/fa187507d40ad576607fe8e2fab56f8e to your computer and use it in GitHub Desktop.
Save hopsor/fa187507d40ad576607fe8e2fab56f8e to your computer and use it in GitHub Desktop.
ftp download using elixir and erlang interop
defmodule Reporter do
def progress(last_data, file_name, {size_type, chunk_size}) do
IO.inspect({last_data[:downloaded], "#{last_data[:rate]} MB/s", file_name, size_type, chunk_size})
new_timestamp = :os.system_time(:milli_seconds)
timestamp_diff = new_timestamp - last_data[:last_timestamp]
case chunk_size do
:unknown ->
downloaded = 0
rate = 0
_ ->
downloaded = last_data[:downloaded] + chunk_size
# Kilobytes per second
cond do
timestamp_diff > 0 ->
rate = (chunk_size/1000000)/(timestamp_diff/1000)
true ->
rate = last_data[:rate]
end
end
%{downloaded: downloaded, last_timestamp: new_timestamp, rate: rate}
end
end
cfg = [
host: 'ftp.iinet.net.au',
progress: {
Reporter,
:progress,
%{
downloaded: 0,
last_timestamp: :os.system_time(:milli_seconds),
rate: 0
}
}
]
:inets.start
{:ok, pid} = :inets.start(:ftpc, cfg)
:ftp.user(pid, 'anonymous', 'anonymous')
:ftp.type(pid, :binary)
:ftp.ls(pid)
a = :os.system_time(:milli_seconds)
:ftp.recv(pid, '1mb.dat')
b = :os.system_time(:milli_seconds)
IO.puts "Time spent: #{(b-a)/1000} seconds"
@hopsor
Copy link
Author

hopsor commented Aug 9, 2016

{1040680, "1.46 MB/s", '1mb.dat', :transfer_size, 1460}
{1042140, "1.46 MB/s", '1mb.dat', :transfer_size, 1460}
{1043600, "1.46 MB/s", '1mb.dat', :transfer_size, 1460}
{1045060, "1.46 MB/s", '1mb.dat', :transfer_size, 1460}
{1046520, "0.73 MB/s", '1mb.dat', :transfer_size, 1460}
{1047980, "0.73 MB/s", '1mb.dat', :transfer_size, 596}
{1048576, "0.596 MB/s", '1mb.dat', :transfer_size, 0}
:ok
iex(12)> b = :os.system_time(:milli_seconds)
1470772308509
iex(13)> IO.puts "Time spent: #{(b-a)/1000} seconds"
Time spent: 9.922 seconds

Calculating the transfer rate within the progress block doesn't seem feasible. Maybe it's better for each download to start a different process that watches the progress each 1-2 seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment