Backport pull request #17982 from jellyfin/release-12.z

Fix SimilarItemsManager concurrency

Original-merge: 47ba387eb3

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Cody Robibero <cody@robibe.ro>
This commit is contained in:
Shadowghost authored and Cody Robibero committed 2026-09-15 11:16:17 -04:00
1 parent d898bb3767
commit 7d5d448742
1 file changed
+27 -2
@@ -651,7 +651,13 @@ public class SimilarItemsManager : ISimilarItemsManager
try
{
var stream = File.OpenRead(cachePath);
var stream = new FileStream(
cachePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite | FileShare.Delete,
IODefaults.FileStreamBufferSize,
FileOptions.Asynchronous | FileOptions.SequentialScan);
await using (stream.ConfigureAwait(false))
{
var cache = await JsonSerializer.DeserializeAsync<SimilarItemsCache>(stream, JsonDefaults.Options, cancellationToken).ConfigureAwait(false);
@@ -675,6 +681,7 @@ public class SimilarItemsManager : ISimilarItemsManager
private async Task SaveSimilarItemsCacheAsync(string cachePath, List<SimilarItemReference> references, TimeSpan cacheDuration, CancellationToken cancellationToken)
{
string? tempPath = null;
try
{
var directory = Path.GetDirectoryName(cachePath);
@@ -689,16 +696,34 @@ public class SimilarItemsManager : ISimilarItemsManager
ExpiresAt = DateTime.UtcNow.Add(cacheDuration)
};
var stream = File.Create(cachePath);
tempPath = cachePath + "." + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture) + ".tmp";
var stream = File.Create(tempPath);
await using (stream.ConfigureAwait(false))
{
await JsonSerializer.SerializeAsync(stream, cache, JsonDefaults.Options, cancellationToken).ConfigureAwait(false);
}
File.Move(tempPath, cachePath, true);
tempPath = null;
}
catch (IOException ex)
{
_logger.LogWarning(ex, "Failed to save similar items cache to {CachePath}", cachePath);
}
finally
{
if (tempPath is not null)
{
try
{
File.Delete(tempPath);
}
catch (IOException ex)
{
_logger.LogDebug(ex, "Failed to delete temporary similar items cache file {TempPath}", tempPath);
}
}
}
}
private sealed class SimilarItemsCache