Ruby Tempfile and Garbage CollectionSun, Jan 31, 2016
Tempfile gives you an easy way to quickly create a temporary file without having to worry about generating a file name that doesn’t already exist and cleaning up the file after you are done. However, you have to be aware that the temporary file will be deleted when the tempfile instance is garbage collected.
From ruby Tempfile documentation
When a Tempfile object is garbage collected, or when the Ruby interpreter exits, its associated temporary file is automatically deleted.
Here is an example that will cause intermittent problem
# create tempfile and return the path def create_tempfile(body) tmpfile = Tempfile.new tmpfile.write(body) tmpfile.close # so it will actually write the content to disk tmpfile.path end path = create_tempfile(‘hello’) File.read(path)
In some cases you would get an error that the file does not exist. Because what gets returned from the create_tempfile method is the tempfile path, so tempfile is no longer referenced anywhere once
create_tempfile is done. When garbage collector runs, it will cleanup tmpfile and also delete the file.
You can test this by manually starting the garbage collector, and always get an error when trying to read the file.
path = create_tempfile(‘hello’) GC.start File.read(path)
In order to avoid this issue, you need to return the tmpfile instance. So as long as your code still references the tempfile instance, it will not be garbage collected.
def create_tempfile(body) tmpfile = Tempfile.new tmpfile.write(body) tmpfile.close tmpfile end file = create_tempfile(‘hello’) GC.start File.read(file.path) # this will work even after garbage collection ran