Learn how to leverage Erlang + Elixir’s GenServer to build a robust FTP Client.
Well put! The only thing that bugs me is this code would suffer crashes operating against slow ftp servers. The code below would blow up if there is no response for :ftp.ls/0
is 5 seconds.
def ls do
GenServer.call({:global, __MODULE__}, :ls)
end
I would probably put a greater timeout or even :infinity
there.
Damn, this is like a blast from the past. We were using ftp
for one of our projects back in the day, nasty stuff when it stops working silently.
The approach we took back then was to check for files every 1 minute. What we did differently was that we would establish a new connection every-time and close when done, this builds a layer of fault-tolerance because we were interacting with different ftp servers, different versions and OS, and sometimes they would start behaving weirdly for no reason.
Thanks!!
Uff this is a hard one because it can block the calling process infinity.
Were you able to use mode: :active
during that time? I’ve done some experiments but can’t get the active mode to work (receiving data as messages).
No, we were strictly using passive mode, it would be extremely annoying to set the infrastructure to allow incoming connections.
We did have an issue where data transfer would not work. There was a misconfigured ftp
server behind a proxy that would send its local IP for data connections, but send the correct public one for commands, so it would work until you wanted to make file transfers. What I ended up doing was to extract the ftp
library from OTP, mass rename it and change the library to always fetch the IP from the initial command connection for data connections.
I don’t remember exactly how I found out the exact issue, but I think it was by running ftp
in verbose mode, it literally shows all the steps it takes if I remember correctly.
I think it would be useful to include automated tests, as especially for clients and GenServers, this is likely to considerably change the design.