aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
index 9395b2e2d..b90a2e056 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
@@ -1,6 +1,7 @@
using System;
using System.Data.Common;
using System.Linq;
+using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@@ -28,15 +29,34 @@ public class OptimisticLockBehavior : IEntityFrameworkCoreLockingBehavior
TimeSpan[] sleepDurations = [
TimeSpan.FromMilliseconds(50),
TimeSpan.FromMilliseconds(50),
+ TimeSpan.FromMilliseconds(50),
+ TimeSpan.FromMilliseconds(50),
+ TimeSpan.FromMilliseconds(250),
TimeSpan.FromMilliseconds(250),
+ TimeSpan.FromMilliseconds(250),
+ TimeSpan.FromMilliseconds(150),
+ TimeSpan.FromMilliseconds(150),
TimeSpan.FromMilliseconds(150),
TimeSpan.FromMilliseconds(500),
+ TimeSpan.FromMilliseconds(150),
TimeSpan.FromMilliseconds(500),
+ TimeSpan.FromMilliseconds(150),
TimeSpan.FromSeconds(3)
];
+
+ Func<int, Context, TimeSpan> backoffProvider = (index, context) =>
+ {
+ var backoff = sleepDurations[index];
+ return backoff + TimeSpan.FromMilliseconds(RandomNumberGenerator.GetInt32(0, (int)(backoff.TotalMilliseconds * .5)));
+ };
+
_logger = logger;
- _writePolicy = Policy.HandleInner<Exception>(e => e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase)).WaitAndRetry(sleepDurations, RetryHandle);
- _writeAsyncPolicy = Policy.HandleInner<Exception>(e => e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase)).WaitAndRetryAsync(sleepDurations, RetryHandle);
+ _writePolicy = Policy
+ .HandleInner<Exception>(e => e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase))
+ .WaitAndRetry(sleepDurations.Length, backoffProvider, RetryHandle);
+ _writeAsyncPolicy = Policy
+ .HandleInner<Exception>(e => e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase))
+ .WaitAndRetryAsync(sleepDurations.Length, backoffProvider, RetryHandle);
void RetryHandle(Exception exception, TimeSpan timespan, int retryNo, Context context)
{