From e36eb50cc2c8897f3868361224e3949e69830394 Mon Sep 17 00:00:00 2001 From: Pedro Yamada Date: Tue, 28 May 2024 15:27:00 +1000 Subject: [PATCH 1/7] Try to make writeSnapshot atomic for watchman backend --- src/watchman/WatchmanBackend.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/watchman/WatchmanBackend.cc b/src/watchman/WatchmanBackend.cc index 04640037..5933acfe 100644 --- a/src/watchman/WatchmanBackend.cc +++ b/src/watchman/WatchmanBackend.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "../DirTree.hh" #include "../Event.hh" @@ -241,8 +242,14 @@ void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *snapshotPath) std::unique_lock lock(mMutex); watchmanWatch(watcher.mDir); - std::ofstream ofs(*snapshotPath); - ofs << clock(watcher); + auto clockValue = clock(watcher); + auto temporaryDirectory = std::filesystem::temp_directory_path(); + auto temporaryFilePath = temporaryDirectory.append("tmp-parcel-snapshot.txt"); + { + std::ofstream ofs(temporaryFilePath); + ofs << clockValue; + } + std::filesystem::rename(temporaryFilePath, *snapshotPath); } void WatchmanBackend::getEventsSince(Watcher &watcher, std::string *snapshotPath) { From c313651ee8eccd1937c81c50a6b3b44669539d2b Mon Sep 17 00:00:00 2001 From: Pedro Yamada Date: Tue, 28 May 2024 15:43:37 +1000 Subject: [PATCH 2/7] Add manual calls to flush and close (though the destructor should do it) --- src/watchman/WatchmanBackend.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/watchman/WatchmanBackend.cc b/src/watchman/WatchmanBackend.cc index 5933acfe..6044c85f 100644 --- a/src/watchman/WatchmanBackend.cc +++ b/src/watchman/WatchmanBackend.cc @@ -248,6 +248,8 @@ void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *snapshotPath) { std::ofstream ofs(temporaryFilePath); ofs << clockValue; + ofs.flush(); + ofs.close(); } std::filesystem::rename(temporaryFilePath, *snapshotPath); } From 99abe496663c0be7cf5870837d546559310a650d Mon Sep 17 00:00:00 2001 From: Pedro Yamada Date: Tue, 28 May 2024 15:53:30 +1000 Subject: [PATCH 3/7] Update to write to a sibling file rather than a tmp one --- src/watchman/WatchmanBackend.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/watchman/WatchmanBackend.cc b/src/watchman/WatchmanBackend.cc index 6044c85f..159f0ee6 100644 --- a/src/watchman/WatchmanBackend.cc +++ b/src/watchman/WatchmanBackend.cc @@ -238,20 +238,21 @@ std::string WatchmanBackend::clock(Watcher &watcher) { return found->second.stringValue(); } -void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *snapshotPath) { +void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *inputSnapshotPath) { std::unique_lock lock(mMutex); watchmanWatch(watcher.mDir); - auto clockValue = clock(watcher); - auto temporaryDirectory = std::filesystem::temp_directory_path(); - auto temporaryFilePath = temporaryDirectory.append("tmp-parcel-snapshot.txt"); + const auto clockValue = clock(watcher); + const auto snapshotPath = std::filesystem::path(*inputSnapshotPath); + auto temporaryFilePath = std::filesystem::path(snapshotPath); + temporaryFilePath.replace_filename(".parcel-temporary-snapshot.txt"); { std::ofstream ofs(temporaryFilePath); ofs << clockValue; ofs.flush(); ofs.close(); } - std::filesystem::rename(temporaryFilePath, *snapshotPath); + std::filesystem::rename(temporaryFilePath, snapshotPath); } void WatchmanBackend::getEventsSince(Watcher &watcher, std::string *snapshotPath) { From c254d7f2e2778efa1def960d0c6aab341b801129 Mon Sep 17 00:00:00 2001 From: Pedro Yamada Date: Tue, 28 May 2024 16:02:26 +1000 Subject: [PATCH 4/7] Use temporary file approach instead --- src/watchman/WatchmanBackend.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/watchman/WatchmanBackend.cc b/src/watchman/WatchmanBackend.cc index 159f0ee6..d193bba9 100644 --- a/src/watchman/WatchmanBackend.cc +++ b/src/watchman/WatchmanBackend.cc @@ -238,21 +238,20 @@ std::string WatchmanBackend::clock(Watcher &watcher) { return found->second.stringValue(); } -void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *inputSnapshotPath) { +void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *snapshotPath) { std::unique_lock lock(mMutex); watchmanWatch(watcher.mDir); - const auto clockValue = clock(watcher); - const auto snapshotPath = std::filesystem::path(*inputSnapshotPath); - auto temporaryFilePath = std::filesystem::path(snapshotPath); - temporaryFilePath.replace_filename(".parcel-temporary-snapshot.txt"); + auto clockValue = clock(watcher); + auto temporaryDirectory = std::filesystem::temp_directory_path(); + auto temporaryFilePath = temporaryDirectory.append("tmp-parcel-snapshot.txt"); { - std::ofstream ofs(temporaryFilePath); + std::ofstream ofs(*snapshotPath); ofs << clockValue; ofs.flush(); ofs.close(); } - std::filesystem::rename(temporaryFilePath, snapshotPath); + std::filesystem::rename(temporaryFilePath, *snapshotPath); } void WatchmanBackend::getEventsSince(Watcher &watcher, std::string *snapshotPath) { From 1e68eb4af3d7c2b4b1e9b94b99d9cd882bbba142 Mon Sep 17 00:00:00 2001 From: Pedro Yamada Date: Tue, 28 May 2024 16:03:33 +1000 Subject: [PATCH 5/7] Fix typo in snapshot write --- src/watchman/WatchmanBackend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/watchman/WatchmanBackend.cc b/src/watchman/WatchmanBackend.cc index d193bba9..4e79c292 100644 --- a/src/watchman/WatchmanBackend.cc +++ b/src/watchman/WatchmanBackend.cc @@ -246,7 +246,7 @@ void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *snapshotPath) auto temporaryDirectory = std::filesystem::temp_directory_path(); auto temporaryFilePath = temporaryDirectory.append("tmp-parcel-snapshot.txt"); { - std::ofstream ofs(*snapshotPath); + std::ofstream ofs(*temporaryFilePath); ofs << clockValue; ofs.flush(); ofs.close(); From 75df0ac637a6e4aeecfb91cce5f6a3078528f570 Mon Sep 17 00:00:00 2001 From: Pedro Yamada Date: Tue, 28 May 2024 16:03:47 +1000 Subject: [PATCH 6/7] Fix typo --- src/watchman/WatchmanBackend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/watchman/WatchmanBackend.cc b/src/watchman/WatchmanBackend.cc index 4e79c292..6044c85f 100644 --- a/src/watchman/WatchmanBackend.cc +++ b/src/watchman/WatchmanBackend.cc @@ -246,7 +246,7 @@ void WatchmanBackend::writeSnapshot(Watcher &watcher, std::string *snapshotPath) auto temporaryDirectory = std::filesystem::temp_directory_path(); auto temporaryFilePath = temporaryDirectory.append("tmp-parcel-snapshot.txt"); { - std::ofstream ofs(*temporaryFilePath); + std::ofstream ofs(temporaryFilePath); ofs << clockValue; ofs.flush(); ofs.close(); From 4408782f292b5e8bcbdbaa960bf72d9acf7d5c45 Mon Sep 17 00:00:00 2001 From: "pyamada (Remote Dev Environment)" Date: Wed, 29 May 2024 02:47:06 +0000 Subject: [PATCH 7/7] Raise test timeouts --- test/since.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/since.js b/test/since.js index c3db9990..0cccee79 100644 --- a/test/since.js +++ b/test/since.js @@ -68,7 +68,7 @@ describe('since', () => { describe('files', () => { it('should emit when a file is created', async function () { - this.timeout(5000); + this.timeout(10000); let f = getFilename(); await watcher.writeSnapshot(tmpDir, snapshotPath, {backend}); if (isSecondPrecision) {