/// <inheritdoc />
 public Task <IDisposable> TryAcquireAsync(string resource, LockOptions options,
                                           CancellationToken cancellationToken = default)
 {
     return(options.WaitTime.HasValue
                         ? TryRepeatAsync(resource, options, cancellationToken)
                         : _innerLock.TryAcquireAsync(resource, options.ExpiryTime, cancellationToken));
 }
        /// <inheritdoc />
        public async Task <IDisposable> AcquireAsync(string resource, LockOptions options,
                                                     CancellationToken cancellationToken = default)
        {
            IDisposable acquiredLock = await TryAcquireAsync(resource, options, cancellationToken);

            return(acquiredLock ?? throw new DistributedLockNotAcquiredException(resource));
        }
        private async Task <IDisposable> TryRepeatAsync(string resource, LockOptions options,
                                                        CancellationToken cancellationToken)
        {
            TimeSpan wait   = options.WaitTime ?? TimeSpan.Zero;
            TimeSpan retry  = options.RetryTime ?? TimeSpan.FromMilliseconds(50);
            TimeSpan expiry = options.ExpiryTime;

            cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(
                new CancellationTokenSource(wait).Token,
                cancellationToken
                ).Token;

            try
            { return(await RepeatAsync(resource, retry, expiry, cancellationToken)); }
            catch (TaskCanceledException) { return(null); }
            catch (OperationCanceledException) { return(null); }
        }