diff options
| author | JPVenson <github@jpb.email> | 2025-09-12 21:57:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-12 13:57:40 -0600 |
| commit | f0e60a7ff332601b4cc955969c09bdf6f1dd0118 (patch) | |
| tree | 86d7bd393e32e37511d8d846eb594e360fb463be /src | |
| parent | a99e67544a82da388ce041f836355f86dbc03609 (diff) | |
Improve optimistic locking behavior (#14779)
Diffstat (limited to 'src')
| -rw-r--r-- | src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs | 24 |
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) { |
