/// <summary> /// Tries to acquire an auto setup lock. /// </summary> /// <param name="distributedLock"> /// The distributed lock. /// </param> /// <param name="lockOptions"> /// The auto setup lock options. /// </param> /// <returns> /// The <see cref="ILocker"/> and <c>true</c> if successfully acquired. /// </returns> public static Task <(ILocker locker, bool locked)> TryAcquireAutoSetupLockAsync(this IDistributedLock distributedLock, LockOptions lockOptions) { TimeSpan timeout, expiration; if (distributedLock is ILocalLock) { // If it is a local lock, don't use any timeout and expiration. timeout = expiration = TimeSpan.MaxValue; } else { // If it is a distributed lock, use the configured timeout and expiration. var lockTimeout = lockOptions?.LockTimeout ?? 0; if (lockTimeout <= 0) { lockTimeout = 60_000; } var lockExpiration = lockOptions?.LockExpiration ?? 0; if (lockExpiration <= 0) { lockExpiration = 60_000; } timeout = TimeSpan.FromMilliseconds(lockTimeout); expiration = TimeSpan.FromMilliseconds(lockExpiration); } return(distributedLock.TryAcquireLockAsync("AUTOSETUP_LOCK", timeout, expiration)); }
public Task UpdateAtomicAsync(Func <Task <TDocument> > updateAsync) { if (updateAsync == null) { return(Task.CompletedTask); } _updateDelegateAsync += () => updateAsync(); _documentStore.AfterCommitSuccess <TDocument>(async() => { (var locker, var locked) = await _distributedLock.TryAcquireLockAsync(_lockKey, LockTimeout, LockExpiration); if (!locked) { return; } await using var acquiredLock = locker; TDocument document = null; foreach (var d in _updateDelegateAsync.GetInvocationList()) { document = await((UpdateDelegate)d)(); } document.Identifier ??= IdGenerator.GenerateId(); await SetInternalAsync(document); }); return(Task.CompletedTask); }
/// <summary> /// Tries to acquire a lock on the background task if it is atomic and if the lock service is not a local lock, otherwise returns true with a null locker. /// </summary> public static Task <(ILocker locker, bool locked)> TryAcquireBackgroundTaskLockAsync(this IDistributedLock distributedLock, BackgroundTaskSettings settings) { if (distributedLock is ILocalLock || !settings.IsAtomic) { return(Task.FromResult <(ILocker, bool)>((null, true))); } return(distributedLock.TryAcquireLockAsync( settings.Name + "_LOCK", TimeSpan.FromMilliseconds(settings.LockTimeout), TimeSpan.FromMilliseconds(settings.LockExpiration))); }
/// <summary> /// Tries to acquire a lock before resuming this workflow instance, but only /// if it is an atomic workflow, otherwise returns true with a null locker. /// </summary> public static Task <(ILocker locker, bool locked)> TryAcquireWorkflowLockAsync( this IDistributedLock distributedLock, Workflow workflow) { if (workflow.IsAtomic) { return(distributedLock.TryAcquireLockAsync( "WFI_" + workflow.WorkflowId + "_LOCK", TimeSpan.FromMilliseconds(workflow.LockTimeout), TimeSpan.FromMilliseconds(workflow.LockExpiration))); } return(Task.FromResult <(ILocker, bool)>((null, true))); }
public Task UpdateAtomicAsync(Func <Task <TDocument> > updateAsync, Func <TDocument, Task> afterUpdateAsync = null) { if (updateAsync == null) { return(Task.CompletedTask); } _updateDelegateAsync += () => updateAsync(); if (afterUpdateAsync != null) { _afterUpdateDelegateAsync += document => afterUpdateAsync(document); } DocumentStore.AfterCommitSuccess <TDocument>(async() => { (var locker, var locked) = await _distributedLock.TryAcquireLockAsync( _options.CacheKey + "_LOCK", TimeSpan.FromMilliseconds(_options.LockTimeout), TimeSpan.FromMilliseconds(_options.LockExpiration)); if (!locked) { return; } await using var acquiredLock = locker; TDocument document = null; foreach (var d in _updateDelegateAsync.GetInvocationList()) { document = await((UpdateDelegate)d)(); } document.Identifier ??= IdGenerator.GenerateId(); await SetInternalAsync(document); if (_afterUpdateDelegateAsync != null) { foreach (var d in _afterUpdateDelegateAsync.GetInvocationList()) { await((AfterUpdateDelegate)d)(document); } } }); return(Task.CompletedTask); }
public Task UpdateAtomicAsync(Func <Task <TDocument> > updateAsync, Func <TDocument, Task> afterUpdateAsync = null, TimeSpan?lockAcquireTimeout = null, TimeSpan?lockExpirationTime = null) { if (updateAsync == null) { return(Task.CompletedTask); } _updateDelegateAsync += () => updateAsync(); if (afterUpdateAsync != null) { _afterUpdateDelegateAsync += document => afterUpdateAsync(document); } _documentStore.AfterCommitSuccess <TDocument>(async() => { var timeout = lockAcquireTimeout ?? DefaultLockTimeout; var expiration = lockExpirationTime ?? DefaultLockExpiration; (var locker, var locked) = await _distributedLock.TryAcquireLockAsync(_lockKey, timeout, expiration); if (!locked) { return; } await using var acquiredLock = locker; TDocument document = null; foreach (var d in _updateDelegateAsync.GetInvocationList()) { document = await((UpdateDelegate)d)(); } document.Identifier ??= IdGenerator.GenerateId(); await SetInternalAsync(document); if (_afterUpdateDelegateAsync != null) { foreach (var d in _afterUpdateDelegateAsync.GetInvocationList()) { await((AfterUpdateDelegate)d)(document); } } }); return(Task.CompletedTask); }
/// <summary> /// Tries to acquire a lock before starting an instance of this workflow type, if it is /// a singleton or if the event is exclusive, otherwise returns true with a null locker. /// </summary> public static Task <(ILocker locker, bool locked)> TryAcquireWorkflowTypeLockAsync( this IDistributedLock distributedLock, WorkflowType workflowType, bool isExclusiveEvent = false) { if (workflowType.IsSingleton || isExclusiveEvent) { return(distributedLock.TryAcquireLockAsync( "WFT_" + workflowType.WorkflowTypeId + "_LOCK", TimeSpan.FromMilliseconds(20_000), TimeSpan.FromMilliseconds(20_000))); } return(Task.FromResult <(ILocker, bool)>((null, true))); }