aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeir Storli <geirstorli@yahoo.no>2017-11-01 12:13:54 +0100
committerGitHub <noreply@github.com>2017-11-01 12:13:54 +0100
commit1e099baf24eca738a3f4754e628f11f3c12fd8a9 (patch)
treee09a2f27cfd2a3a0ec12d64953f8f6081dc03c5a
parent46cfff0bd05b994b563648922f06d7edfe249230 (diff)
parent2154af8b9ed6c1d6d1249cf892dc1793eb2b42c8 (diff)
Merge pull request #3961 from vespa-engine/vekterli/catch-and-retry-disk-usage-sampling
Catch exceptions and retry disk usage sampling
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp
index a19243287a4..7ef8c53d4dd 100644
--- a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp
@@ -60,23 +60,41 @@ sampleDiskUsageOnFileSystem(const fs::path &path, const HwInfo::Disk &disk)
return result;
}
+// May throw fs::filesystem_error on concurrent directory tree modification
uint64_t
-sampleDiskUsageInDirectory(const fs::path &path)
+attemptSampleDirectoryDiskUsageOnce(const fs::path &path)
{
uint64_t result = 0;
for (const auto &elem : fs::recursive_directory_iterator(path,
fs::directory_options::skip_permission_denied)) {
if (fs::is_regular_file(elem.path()) && !fs::is_symlink(elem.path())) {
- try {
- result += fs::file_size(elem.path());
- } catch (const fs::filesystem_error &) {
- // This typically happens when a file is removed while doing the directory scan. Ignoring.
+ std::error_code fsize_err;
+ const auto size = fs::file_size(elem.path(), fsize_err);
+ // Errors here typically happens when a file is removed while doing the directory scan. Ignore them.
+ if (!fsize_err) {
+ result += size;
}
}
}
return result;
}
+uint64_t
+sampleDiskUsageInDirectory(const fs::path &path)
+{
+ // Since attemptSampleDirectoryDiskUsageOnce may throw on concurrent directory
+ // modifications, immediately retry a bounded number of times if this happens.
+ // Number of retries chosen randomly by counting fingers.
+ for (int i = 0; i < 10; ++i) {
+ try {
+ return attemptSampleDirectoryDiskUsageOnce(path);
+ } catch (const fs::filesystem_error&) {
+ // Go around for another spin that hopefully won't race.
+ }
+ }
+ return 0;
+}
+
}
void