< Summary

Information
Class: Services.SearchServices.OrderSearch.OrderSearchIndexOperationLock
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/SearchServices/OrderSearch/OrderSearchIndexOperationLock.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 23
Coverable lines: 23
Total lines: 70
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%210%
.ctor(...)100%210%
TryAcquire()100%210%
.ctor(...)100%210%
Dispose()100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/SearchServices/OrderSearch/OrderSearchIndexOperationLock.cs

#LineLine coverage
 1using Hangfire;
 2using Hangfire.Storage;
 3using Microsoft.Extensions.Logging;
 4using Services.HangfireService;
 5
 6namespace Services.SearchServices.OrderSearch;
 7
 8/// <summary>
 9/// Общая распределённая блокировка для операций, временно меняющих состав индекса заказов.
 10/// </summary>
 11public interface IOrderSearchIndexOperationLock
 12{
 13    /// <summary>Пытается получить блокировку; возвращает <see langword="null"/>, если она уже занята.</summary>
 14    IDisposable? TryAcquire();
 15}
 16
 17public sealed class OrderSearchIndexOperationLock : IOrderSearchIndexOperationLock
 18{
 19    public const string LockKey = "order-search:index-operation";
 20
 021    private static readonly TimeSpan LockTimeout = TimeSpan.FromMilliseconds(1);
 22    private readonly ILogger<OrderSearchIndexOperationLock> _logger;
 23
 024    public OrderSearchIndexOperationLock(ILogger<OrderSearchIndexOperationLock> logger)
 25    {
 026        _logger = logger;
 027    }
 28
 29    public IDisposable? TryAcquire()
 30    {
 031        IStorageConnection? connection = null;
 032        IDisposable? distributedLock = null;
 33
 34        try
 35        {
 036            connection = JobStorage.Current.GetConnection();
 037            distributedLock = connection.AcquireDistributedLock(LockKey, LockTimeout);
 38
 039            var handle = new LockHandle(distributedLock, connection, _logger);
 040            distributedLock = null;
 041            connection = null;
 042            return handle;
 43        }
 044        catch (DistributedLockTimeoutException)
 45        {
 046            return null;
 47        }
 48        finally
 49        {
 050            HangfireDistributedLockHelper.SafeDispose(ref distributedLock, ref connection, _logger);
 051        }
 052    }
 53
 54    private sealed class LockHandle : IDisposable
 55    {
 56        private readonly ILogger _logger;
 57        private IStorageConnection? _connection;
 58        private IDisposable? _distributedLock;
 59
 060        public LockHandle(IDisposable distributedLock, IStorageConnection connection, ILogger logger)
 61        {
 062            _distributedLock = distributedLock;
 063            _connection = connection;
 064            _logger = logger;
 065        }
 66
 67        public void Dispose() =>
 068            HangfireDistributedLockHelper.SafeDispose(ref _distributedLock, ref _connection, _logger);
 69    }
 70}