diff options
| author | Dan Engelbrecht <[email protected]> | 2022-05-09 22:03:45 +0200 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2022-05-09 22:04:23 +0200 |
| commit | 5ef2b317ef1965121ab0090d86962d3eea4a357e (patch) | |
| tree | 6db991bf5abce49c36de9034245d65340fc6ad95 /zenserver/cache/structuredcachestore.cpp | |
| parent | Merge pull request #89 from EpicGames/de/namespaces (diff) | |
| download | zen-5ef2b317ef1965121ab0090d86962d3eea4a357e.tar.xz zen-5ef2b317ef1965121ab0090d86962d3eea4a357e.zip | |
Make sure CacheBucket::PutStandaloneCacheValue cleans up the temp file if we fail to move the it into place
Diffstat (limited to 'zenserver/cache/structuredcachestore.cpp')
| -rw-r--r-- | zenserver/cache/structuredcachestore.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index 05c80c5bf..411717e61 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -1819,6 +1819,14 @@ ZenCacheDiskLayer::CacheBucket::PutStandaloneCacheValue(const IoHash& HashKey, c RetryCount--; } while (RetryCount > 0); + // Once we have called MoveTemporaryIntoPlace we no longer will automatically clean up the temp file + // as the file handle has already been closed + std::filesystem::remove(DataFile.GetPath(), Ec); + if (Ec) + { + ZEN_WARN("Failed to clean up temporary file '{}' for put in '{}', reason '{}'", DataFile.GetPath(), m_BucketDir, Ec.message()); + } + throw std::system_error(Ec, fmt::format("Failed to finalize file '{}' for put in '{}'", DataFilePath.ToUtf8(), m_BucketDir)); } @@ -2971,6 +2979,46 @@ TEST_CASE("z$.threadedinsert") // * doctest::skip(true)) } } +# if ZEN_PLATFORM_WINDOWS +TEST_CASE("z$.blocked.disklayer.put") +{ + // On Windows platform we can't overwrite a standalone file that + // is open for read at the same time. + // Make sure the retry path runs and we get an exception + + ScopedTemporaryDirectory TempDir; + + GcStorageSize CacheSize; + + const auto CreateCacheValue = [](size_t Size) -> CbObject { + std::vector<uint8_t> Buf; + Buf.resize(Size); + + CbObjectWriter Writer; + Writer.AddBinary("Binary"sv, Buf.data(), Buf.size()); + return Writer.Save(); + }; + + CasGc Gc; + ZenCacheNamespace Zcs(Gc, TempDir.Path() / "cache"); + + CbObject CacheValue = CreateCacheValue(64 * 1024 + 64); + + IoBuffer Buffer = CacheValue.GetBuffer().AsIoBuffer(); + Buffer.SetContentType(ZenContentType::kCbObject); + + size_t Key = Buffer.Size(); + IoHash HashKey = IoHash::HashBuffer(&Key, sizeof(uint32_t)); + Zcs.Put("test_bucket", HashKey, {.Value = Buffer}); + + ZenCacheValue BufferGet; + CHECK(Zcs.Get("test_bucket", HashKey, BufferGet)); + + MemoryView ValueView = BufferGet.Value.GetView(); + CHECK_THROWS(Zcs.Put("test_bucket", HashKey, {.Value = Buffer})); +} +# endif + #endif void |