Sorry if this was asked before, but i can’t find an answer to this anywhere.
I’m currently learning elixir (i come from a mostly non-functional background go & javascript) there’s something bugging me, in elixir we just let things crash right? and have the supervising process deal with the error but what happens if we do something like
{:ok, f} = File.open("foo.json")
# do things with f
:ok = File.close(f)
What if between the call to File.open("foo.json") and the File.close(f)
an exception occurs this would mean that File.close will never be called does that mean that my process will start leaking resources ? or is the process spawned by File.open is linked to the process calling File.open and will be shutdown and the file handle released when the supervising process shuts down.
Hey @MSE99 welcome! When you open a resource in Elixir / Erlang, that resource is linked to your current process. If that process crashes, the link ensures that the resource is released as well.
The important piece here is that the runtime doesn’t prevent leaks because the processes opening the file cleans up, but it works because there are multiple processes. Monitors and links are methods a process can use to get notified if another process crashed. This can then be used to trigger cleanup even if the original process requesting the resource is gone.
We open files with File.open right? And we close them using File.close - what if between the call to File.open and File.close an error occurs?
That File.close will never be called and the program will leak that file descriptor?
I know that File.open spawns a process, is that process linked to the process that spawned it?
kwando
from the docs of File.open:
This function returns:
{:ok, io_device} - the file has been opened in the requested mode.io_device is actually the PID of the process which handles the file. This process monitors the process that originally opened the file (the owner process). If the owner process terminates, the file is closed and the process itself terminates too. If any process to which the io_device is linked terminates, the file will be closed and the process itself will be terminated. An io_device returned from this call can be used as an argument to the IO module functions.
File.open also takes a callback. File will be closed automatically after the callback.
if an exception is raised without being catched, then the process will be killed (by default), and all the related resources will be garbage-collected.
if an exception is raised, and you can catch it, then you still have the chance to call File.close.