aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs4
-rw-r--r--src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/SqliteDatabaseProvider.cs6
-rw-r--r--src/Jellyfin.Drawing/ImageProcessor.cs35
-rw-r--r--src/Jellyfin.Drawing/Properties/AssemblyInfo.cs2
4 files changed, 40 insertions, 7 deletions
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
index 76ffa5a9ea..29a073ff74 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
@@ -88,13 +88,13 @@ public class OptimisticLockBehavior : IEntityFrameworkCoreLockingBehavior
/// <inheritdoc/>
public void OnSaveChanges(JellyfinDbContext context, Action saveChanges)
{
- _writePolicy.ExecuteAndCapture(saveChanges);
+ _writePolicy.Execute(saveChanges);
}
/// <inheritdoc/>
public async Task OnSaveChangesAsync(JellyfinDbContext context, Func<Task> saveChanges)
{
- await _writeAsyncPolicy.ExecuteAndCaptureAsync(saveChanges).ConfigureAwait(false);
+ await _writeAsyncPolicy.ExecuteAsync(saveChanges).ConfigureAwait(false);
}
private sealed class TransactionLockingInterceptor : DbTransactionInterceptor
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/SqliteDatabaseProvider.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/SqliteDatabaseProvider.cs
index 044fd0131f..8020fe1f93 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/SqliteDatabaseProvider.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/SqliteDatabaseProvider.cs
@@ -63,7 +63,11 @@ public sealed class SqliteDatabaseProvider : IJellyfinDatabaseProvider
var sqliteConnectionBuilder = new SqliteConnectionStringBuilder
{
DataSource = GetOption(customOptions, "path", e => e, () => Path.Combine(_applicationPaths.DataPath, "jellyfin.db")),
- Cache = GetOption(customOptions, "cache", Enum.Parse<SqliteCacheMode>, () => SqliteCacheMode.Default),
+ // Private, not Default: sqlite3_enable_shared_cache is process-global, so a plugin
+ // enabling it makes these connections share a cache too. Contention then surfaces as
+ // SQLITE_LOCKED ("database table is locked"), which the busy handler does not cover,
+ // so busy_timeout is skipped and the command fails at CommandTimeout instead.
+ Cache = GetOption(customOptions, "cache", Enum.Parse<SqliteCacheMode>, () => SqliteCacheMode.Private),
Pooling = GetOption(customOptions, "pooling", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), () => true),
DefaultTimeout = GetOption(customOptions, "command-timeout", int.Parse, () => 60)
};
diff --git a/src/Jellyfin.Drawing/ImageProcessor.cs b/src/Jellyfin.Drawing/ImageProcessor.cs
index 6ffb022842..ad1b216970 100644
--- a/src/Jellyfin.Drawing/ImageProcessor.cs
+++ b/src/Jellyfin.Drawing/ImageProcessor.cs
@@ -31,7 +31,7 @@ namespace Jellyfin.Drawing;
public sealed class ImageProcessor : IImageProcessor, IDisposable
{
// Increment this when there's a change requiring caches to be invalidated
- private const char Version = '3';
+ private const char Version = '4';
private static readonly HashSet<string> _transparentImageTypes
= new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".png", ".webp", ".gif", ".svg" };
@@ -251,6 +251,33 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
/// <summary>
/// Gets the cache file path based on a set of parameters.
/// </summary>
+ /// <param name="originalPath">The original image path.</param>
+ /// <param name="dateModified">The source image modification date.</param>
+ /// <param name="format">The output format.</param>
+ /// <param name="options">The image processing options.</param>
+ /// <returns>The transformed image cache path.</returns>
+ internal string GetCacheFilePath(
+ string originalPath,
+ DateTime dateModified,
+ ImageFormat format,
+ ImageProcessingOptions options)
+ => GetCacheFilePath(
+ originalPath,
+ options.Width,
+ options.Height,
+ options.MaxWidth,
+ options.MaxHeight,
+ options.FillWidth,
+ options.FillHeight,
+ options.Quality,
+ dateModified,
+ format,
+ options.PercentPlayed,
+ options.UnplayedCount,
+ options.Blur,
+ options.BackgroundColor,
+ options.ForegroundLayer);
+
private string GetCacheFilePath(
string originalPath,
int? width,
@@ -318,13 +345,13 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
if (percentPlayed > 0)
{
- filename.Append(",p=");
- filename.Append(percentPlayed);
+ filename.Append(",pp=");
+ filename.Append(percentPlayed.ToString(CultureInfo.InvariantCulture));
}
if (unwatchedCount.HasValue)
{
- filename.Append(",p=");
+ filename.Append(",uc=");
filename.Append(unwatchedCount.Value);
}
diff --git a/src/Jellyfin.Drawing/Properties/AssemblyInfo.cs b/src/Jellyfin.Drawing/Properties/AssemblyInfo.cs
index 3851bf9241..3d39372313 100644
--- a/src/Jellyfin.Drawing/Properties/AssemblyInfo.cs
+++ b/src/Jellyfin.Drawing/Properties/AssemblyInfo.cs
@@ -1,4 +1,5 @@
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@@ -12,6 +13,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
+[assembly: InternalsVisibleTo("Jellyfin.Server.Integration.Tests")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from