Beispiel #1
0
 public static TUpgradeableHandle AcquireUpgradeableReadLock <THandle, TUpgradeableHandle>(IInternalDistributedUpgradeableReaderWriterLock <THandle, TUpgradeableHandle> @lock, TimeSpan?timeout, CancellationToken cancellationToken)
     where THandle : class, IDistributedSynchronizationHandle
     where TUpgradeableHandle : class, IDistributedLockUpgradeableHandle =>
 SyncViaAsync.Run(
     state => AcquireUpgradeableReadLockAsync(state.@lock, state.timeout, state.cancellationToken),
     (@lock, timeout, cancellationToken)
     );
Beispiel #2
0
        public static async ValueTask <TResult?> WaitAsync <TState, TResult>(
            TState state,
            Func <TState, CancellationToken, ValueTask <TResult?> > tryGetValue,
            TimeoutValue timeout,
            TimeoutValue minSleepTime,
            TimeoutValue maxSleepTime,
            CancellationToken cancellationToken)
            where TResult : class
        {
            Invariant.Require(minSleepTime.CompareTo(maxSleepTime) <= 0);
            Invariant.Require(!maxSleepTime.IsInfinite);

            var initialResult = await tryGetValue(state, cancellationToken).ConfigureAwait(false);

            if (initialResult != null || timeout.IsZero)
            {
                return(initialResult);
            }

            using var _ = CreateMergedCancellationTokenSourceSource(timeout, cancellationToken, out var mergedCancellationToken);

            var random           = new Random(Guid.NewGuid().GetHashCode());
            var sleepRangeMillis = maxSleepTime.InMilliseconds - minSleepTime.InMilliseconds;

            while (true)
            {
                var sleepTime = minSleepTime.TimeSpan + TimeSpan.FromMilliseconds(random.NextDouble() * sleepRangeMillis);
                try
                {
                    await SyncViaAsync.Delay(sleepTime, mergedCancellationToken).ConfigureAwait(false);
                }
                catch (OperationCanceledException) when(IsTimedOut())
                {
                    // if we time out while sleeping, always try one more time with just the regular token
                    return(await tryGetValue(state, cancellationToken).ConfigureAwait(false));
                }

                try
                {
                    var result = await tryGetValue(state, mergedCancellationToken).ConfigureAwait(false);

                    if (result != null)
                    {
                        return(result);
                    }
                }
                catch (OperationCanceledException) when(IsTimedOut())
                {
                    return(null);
                }
            }

            bool IsTimedOut() =>
            mergedCancellationToken.IsCancellationRequested && !cancellationToken.IsCancellationRequested;
        }
Beispiel #3
0
 public static THandle?TryAcquire <THandle>(IInternalDistributedReaderWriterLock <THandle> @lock, TimeSpan timeout, CancellationToken cancellationToken, bool isWrite)
     where THandle : class, IDistributedSynchronizationHandle =>
 SyncViaAsync.Run(
     state => [email protected](state.timeout, state.cancellationToken, state.isWrite),
     (@lock, timeout, cancellationToken, isWrite)
     );
Beispiel #4
0
 public static THandle Acquire <THandle>(IInternalDistributedLock <THandle> @lock, TimeSpan?timeout, CancellationToken cancellationToken)
     where THandle : class, IDistributedSynchronizationHandle =>
 SyncViaAsync.Run(
     state => AcquireAsync(state.@lock, state.timeout, state.cancellationToken),
     (@lock, timeout, cancellationToken)
     );
Beispiel #5
0
 public static bool TryUpgradeToWriteLock(IDistributedLockUpgradeableHandle handle, TimeSpan timeout, CancellationToken cancellationToken) =>
 SyncViaAsync.Run(t => t.handle.TryUpgradeToWriteLockAsync(t.timeout, t.cancellationToken), (handle, timeout, cancellationToken));