From 63a4aa65ff8eb0498b7a75a820d766e282763d21 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Mon, 27 Jan 2020 02:59:54 +0100 Subject: [PATCH] DEV: Ignore `ls` errors when clearing FileStore cache (#8780) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A race condition issue is possible when multiple thread/processes are calling this method. `ls` prints out to stderr "cannot access '...': No such file or directory" if any of the files it's currently trying to list are being removed by the `xargs rm -rf` in an another process. That doesn't affect the result, but it did raise an error before this change. Tested on a production instance where the original issue was observed. Co-Authored-By: RĂ©gis Hanol --- lib/file_store/base_store.rb | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/file_store/base_store.rb b/lib/file_store/base_store.rb index 47c61b60ebe..563970d0880 100644 --- a/lib/file_store/base_store.rb +++ b/lib/file_store/base_store.rb @@ -150,14 +150,23 @@ module FileStore dir = File.dirname(path) FileUtils.mkdir_p(dir) unless Dir.exist?(dir) FileUtils.cp(file.path, path) - # keep latest 500 files + + # Keep latest 500 files processes = Open3.pipeline( - "ls -t #{CACHE_DIR}", + ["ls -t #{CACHE_DIR}", err: "/dev/null"], "tail -n +#{CACHE_MAXIMUM_SIZE + 1}", "awk '$0=\"#{CACHE_DIR}\"$0'", "xargs rm -f" ) - raise "Error clearing old cache" if !processes.all?(&:success?) + + ls = processes.shift + + # Exit status `1` in `ls` occurs when e.g. "listing a directory + # in which entries are actively being removed or renamed". + # It's safe to ignore it here. + if ![0, 1].include?(ls.exitstatus) || !processes.all?(&:success?) + raise "Error clearing old cache" + end end private