public async Task <bool> CheckIsStillLockedAsync(DistributedLockSettings settings) { Check.NotNull(settings, nameof(settings)); if (settings is NullLockSettings) { return(await NullLockManager.CheckIsStillLockedAsync(settings).ConfigureAwait(false)); } try { using var scope = _serviceScopeFactory.CreateScope(); return(await CheckIsStillLockedAsync( settings.ResourceName, settings.UniqueId, settings.HeartbeatTimeout, scope.ServiceProvider) .ConfigureAwait(false)); } catch (Exception ex) { _logger.LogFailedToCheckLock(settings, ex); return(false); } }
public async Task <DistributedLock> Acquire(DistributedLockSettings settings, CancellationToken cancellationToken = default) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } _logger.LogInformation("Trying to acquire lock {lockName} ({lockUniqueId})...", settings.ResourceName, settings.UniqueId); var stopwatch = Stopwatch.StartNew(); while (settings.AcquireTimeout == null || stopwatch.Elapsed < settings.AcquireTimeout) { if (await TryAcquireLock(settings)) { _logger.LogInformation("Acquired lock {lockName} ({lockUniqueId}).", settings.ResourceName, settings.UniqueId); return(new DistributedLock(settings, this)); } await Task.Delay(settings.AcquireRetryInterval, cancellationToken); if (cancellationToken.IsCancellationRequested) { break; } } throw new TimeoutException($"Timeout waiting to get the required lock '{settings.ResourceName}'."); }
public async Task ReleaseAsync(DistributedLockSettings settings) { Check.NotNull(settings, nameof(settings)); if (settings is NullLockSettings) { await NullLockManager.ReleaseAsync(settings).ConfigureAwait(false); } var tryCount = 1; while (tryCount <= 3) { try { using var scope = _serviceScopeFactory.CreateScope(); await ReleaseAsync(settings.ResourceName, settings.UniqueId, scope.ServiceProvider) .ConfigureAwait(false); _logger.LogLockReleased(settings); break; } catch (Exception ex) { _logger.LogFailedToReleaseLock(settings, ex); tryCount++; } } }
public async Task <bool> CheckIsStillLockedAsync(DistributedLockSettings settings) { Check.NotNull(settings, nameof(settings)); if (settings is NullLockSettings) { return(await NullLockManager.CheckIsStillLockedAsync(settings).ConfigureAwait(false)); } try { using var scope = _serviceScopeFactory.CreateScope(); return(await CheckIsStillLockedAsync( settings.ResourceName, settings.UniqueId, settings.HeartbeatTimeout, scope.ServiceProvider) .ConfigureAwait(false)); } catch (Exception ex) { _logger.LogError( CoreEventIds.FailedToCheckDistributedLock, ex, "Failed to check lock {lockName} ({lockUniqueId}). See inner exception for details.", settings.ResourceName, settings.UniqueId); return(false); } }
public async Task <bool> SendHeartbeatAsync(DistributedLockSettings settings) { Check.NotNull(settings, nameof(settings)); if (settings is NullLockSettings) { return(await NullLockManager.SendHeartbeatAsync(settings).ConfigureAwait(false)); } try { using var scope = _serviceScopeFactory.CreateScope(); return(await SendHeartbeatAsync(settings.ResourceName, settings.UniqueId, scope.ServiceProvider) .ConfigureAwait(false)); } catch (Exception ex) { _logger.LogDebug( CoreEventIds.FailedToSendDistributedLockHeartbeat, ex, "Failed to send heartbeat for lock {lockName} ({lockUniqueId}). See inner exception for details.", settings.ResourceName, settings.UniqueId); return(false); } }
public DistributedLock(DistributedLockSettings settings, IDistributedLockManager lockManager) { _settings = settings ?? throw new ArgumentNullException(nameof(settings)); _lockManager = lockManager ?? throw new ArgumentNullException(nameof(lockManager)); Status = DistributedLockStatus.Acquired; Task.Run(SendHeartbeats); }
protected DistributedBackgroundService(DistributedLockSettings distributedLockSettings, IDistributedLockManager distributedLockManager, ILogger <DistributedBackgroundService> logger) { _distributedLockSettings = distributedLockSettings ?? new DistributedLockSettings(); _distributedLockManager = distributedLockManager ?? throw new ArgumentNullException(nameof(distributedLockManager)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); if (string.IsNullOrEmpty(_distributedLockSettings.ResourceName)) { _distributedLockSettings.ResourceName = GetType().FullName; } }
/// <summary> /// Initializes a new instance of the <see cref="DistributedBackgroundService" /> class. /// </summary> /// <param name="distributedLockSettings"> /// Customizes the lock mechanism settings. /// </param> /// <param name="distributedLockManager"> /// The <see cref="IDistributedLockManager" />. /// </param> /// <param name="logger"> /// The <see cref="ISilverbackLogger" />. /// </param> protected DistributedBackgroundService( DistributedLockSettings?distributedLockSettings, IDistributedLockManager distributedLockManager, ISilverbackLogger <DistributedBackgroundService> logger) { _distributedLockSettings = distributedLockSettings ?? new DistributedLockSettings(); _distributedLockSettings.EnsureResourceNameIsSet(GetType().FullName); _distributedLockManager = Check.NotNull(distributedLockManager, nameof(distributedLockManager)); _logger = Check.NotNull(logger, nameof(logger)); }
/// <summary> /// Initializes a new instance of the <see cref="DistributedLock" /> class. /// </summary> /// <param name="settings"> /// Specifies all settings of the lock to be acquired. /// </param> /// <param name="lockManager"> /// The <see cref="IDistributedLockManager" /> that generated the lock and can be used to keep it alive /// and finally release it. /// </param> public DistributedLock(DistributedLockSettings settings, IDistributedLockManager lockManager) { _settings = Check.NotNull(settings, nameof(settings)); _lockManager = Check.NotNull(lockManager, nameof(lockManager)); Status = DistributedLockStatus.Acquired; Task.Factory.StartNew( SendHeartbeatsAsync, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
private async Task <bool> AcquireLock(DistributedLockSettings settings, IServiceProvider serviceProvider) { var heartbeatThreshold = GetHeartbeatThreshold(settings.HeartbeatTimeout); var(dbSet, dbContext) = GetDbSet(serviceProvider); if (await dbSet.AsQueryable().AnyAsync(l => l.Name == settings.ResourceName && l.Heartbeat >= heartbeatThreshold)) { return(false); } return(await WriteLock(settings.ResourceName, settings.UniqueId, heartbeatThreshold, dbSet, dbContext)); }
private async Task <bool> TryAcquireLockAsync(DistributedLockSettings settings) { try { using var scope = _serviceScopeFactory.CreateScope(); return(await AcquireLockAsync(settings, scope.ServiceProvider).ConfigureAwait(false)); } catch (Exception ex) { _logger.LogFailedToAcquireLock(settings, ex); } return(false); }
private async Task <bool> TryAcquireLock(DistributedLockSettings settings) { try { using var scope = _serviceProvider.CreateScope(); return(await AcquireLock(settings, scope.ServiceProvider)); } catch (Exception ex) { _logger.LogDebug(ex, "Failed to acquire lock {lockName} ({lockUniqueId}). See inner exception for details.", settings.ResourceName, settings.UniqueId); } return(false); }
public async Task Release(DistributedLockSettings settings) { try { using var scope = _serviceProvider.CreateScope(); await Release(settings.ResourceName, settings.UniqueId, scope.ServiceProvider); _logger.LogInformation("Released lock {lockName} ({lockUniqueId}).", settings.ResourceName, settings.UniqueId); } catch (Exception ex) { _logger.LogWarning( ex, "Failed to release lock '{lockName} ({lockUniqueId})'. See inner exception for details.", settings.ResourceName, settings.UniqueId); } }
public async Task <bool> CheckIsStillLocked(DistributedLockSettings settings) { try { using var scope = _serviceProvider.CreateScope(); return(await CheckIsStillLocked(settings.ResourceName, settings.UniqueId, settings.HeartbeatTimeout, scope.ServiceProvider)); } catch (Exception ex) { _logger.LogError(ex, "Failed to check lock {lockName} ({lockUniqueId}). See inner exception for details.", settings.ResourceName, settings.UniqueId); } return(false); }
/// <inheritdoc cref="IDistributedLockManager.AcquireAsync" /> public async Task <DistributedLock?> AcquireAsync( DistributedLockSettings settings, CancellationToken cancellationToken = default) { Check.NotNull(settings, nameof(settings)); if (string.IsNullOrEmpty(settings.ResourceName)) { throw new InvalidOperationException( "ResourceName cannot be null. Please provide a valid resource name in the settings."); } if (settings is NullLockSettings) { return(await NullLockManager.AcquireAsync(settings, cancellationToken).ConfigureAwait(false)); } _logger.LogInformation( CoreEventIds.AcquiringDistributedLock, "Trying to acquire lock {lockName} ({lockUniqueId})...", settings.ResourceName, settings.UniqueId); var stopwatch = Stopwatch.StartNew(); while (settings.AcquireTimeout == null || stopwatch.Elapsed < settings.AcquireTimeout) { if (await TryAcquireLockAsync(settings).ConfigureAwait(false)) { _logger.LogInformation( CoreEventIds.DistributedLockAcquired, "Acquired lock {lockName} ({lockUniqueId}).", settings.ResourceName, settings.UniqueId); return(new DistributedLock(settings, this)); } await Task.Delay(settings.AcquireRetryInterval, cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { break; } } throw new TimeoutException($"Timeout waiting to get the required lock '{settings.ResourceName}'."); }
public async Task <bool> SendHeartbeat(DistributedLockSettings settings) { try { using var scope = _serviceProvider.CreateScope(); return(await SendHeartbeat(settings.ResourceName, settings.UniqueId, scope.ServiceProvider)); } catch (Exception ex) { _logger.LogDebug(ex, "Failed to send heartbeat for lock {lockName} ({lockUniqueId}). See inner exception for details.", settings.ResourceName, settings.UniqueId); return(false); } }
public async Task ReleaseAsync(DistributedLockSettings settings) { Check.NotNull(settings, nameof(settings)); if (settings is NullLockSettings) { await NullLockManager.ReleaseAsync(settings).ConfigureAwait(false); } var tryCount = 1; while (tryCount <= 3) { try { using var scope = _serviceScopeFactory.CreateScope(); await ReleaseAsync(settings.ResourceName, settings.UniqueId, scope.ServiceProvider) .ConfigureAwait(false); _logger.LogInformation( CoreEventIds.DistributedLockReleased, "Released lock {lockName} ({lockUniqueId}).", settings.ResourceName, settings.UniqueId); break; } catch (Exception ex) { _logger.LogWarning( CoreEventIds.FailedToReleaseDistributedLock, ex, "Failed to release lock '{lockName} ({lockUniqueId})'. See inner exception for details.", settings.ResourceName, settings.UniqueId); tryCount++; } } }
protected DistributedBackgroundService(DistributedLockSettings distributedLockSettings, IDistributedLockManager distributedLockManager, ILogger <DistributedBackgroundService> logger) { _distributedLockSettings = distributedLockSettings ?? throw new ArgumentNullException(nameof(distributedLockSettings)); _distributedLockManager = distributedLockManager ?? throw new ArgumentNullException(nameof(distributedLockManager)); _logger = logger; }
protected RecurringDistributedBackgroundService(TimeSpan interval, DistributedLockSettings distributedLockSettings, IDistributedLockManager distributedLockManager, ILogger <RecurringDistributedBackgroundService> logger) : base(distributedLockSettings, distributedLockManager, logger) { _interval = interval; _logger = logger; }
public Task <DistributedLock> Acquire(DistributedLockSettings settings, CancellationToken cancellationToken = default) => Task.FromResult <DistributedLock>(null);
public Task <bool> CheckIsStillLocked(DistributedLockSettings settings) => Task.FromResult(true);
public Task <bool> SendHeartbeat(DistributedLockSettings settings) => Task.FromResult(true);
public Task Release(DistributedLockSettings settings) => Task.CompletedTask;
public Task <DistributedLock> Acquire(DistributedLockSettings settings, CancellationToken cancellationToken = default) => Acquire(settings.ResourceName, settings.AcquireTimeout, settings.AcquireRetryInterval, settings.HeartbeatTimeout, cancellationToken);