Пример #1
0
        /// <summary>
        /// Builds a bulkhead isolation <see cref="Policy" />, which limits the maximum concurrency of actions executed through the policy.  Imposing a maximum concurrency limits the potential of governed actions, when faulting, to bring down the system.
        /// <para>When an execution would cause the number of actions executing concurrently through the policy to exceed <paramref name="maxParallelization" />, the policy allows a further <paramref name="maxQueuingActions" /> executions to queue, waiting for a concurrent execution slot.  When an execution would cause the number of queuing actions to exceed <paramref name="maxQueuingActions" />, a <see cref="BulkheadRejectedException" /> is thrown.</para>
        /// </summary>
        /// <param name="maxParallelization">The maximum number of concurrent actions that may be executing through the policy.</param>
        /// <param name="maxQueuingActions">The maximum number of actions that may be queuing, waiting for an execution slot.</param>
        /// <param name="onBulkheadRejectedAsync">An action to call asynchronously, if the bulkhead rejects execution due to oversubscription.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">maxParallelization;Value must be greater than zero.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">maxQueuingActions;Value must be greater than or equal to zero.</exception>
        /// <exception cref="System.ArgumentNullException">onBulkheadRejectedAsync</exception>
        public static BulkheadPolicy BulkheadAsync(int maxParallelization, int maxQueuingActions, Func <Context, Task> onBulkheadRejectedAsync)
        {
            if (maxParallelization <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxParallelization), "Value must be greater than zero.");
            }
            if (maxQueuingActions < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxQueuingActions), "Value must be greater than or equal to zero.");
            }
            if (onBulkheadRejectedAsync == null)
            {
                throw new ArgumentNullException(nameof(onBulkheadRejectedAsync));
            }

            SemaphoreSlim maxParallelizationSemaphore = SemaphoreSlimFactory.CreateSemaphoreSlim(maxParallelization);

            var maxQueuingCompounded = maxQueuingActions <= int.MaxValue - maxParallelization
                ? maxQueuingActions + maxParallelization
                : int.MaxValue;
            SemaphoreSlim maxQueuedActionsSemaphore = SemaphoreSlimFactory.CreateSemaphoreSlim(maxQueuingCompounded);

            return(new BulkheadPolicy((action, context, cancellationToken, continueOnCapturedContext) =>
                                      BulkheadEngine.ImplementationAsync(
                                          async(ctx, ct) => { await action(ctx, ct).ConfigureAwait(continueOnCapturedContext); return EmptyStruct.Instance; },
                                          context,
                                          onBulkheadRejectedAsync,
                                          maxParallelizationSemaphore,
                                          maxQueuedActionsSemaphore,
                                          cancellationToken,
                                          continueOnCapturedContext),
                                      maxParallelization,
                                      maxQueuingActions,
                                      maxParallelizationSemaphore,
                                      maxQueuedActionsSemaphore
                                      ));
        }
Пример #2
0
        /// <summary>
        /// Builds a bulkhead isolation <see cref="Policy" />, which limits the maximum concurrency of actions executed through the policy.  Imposing a maximum concurrency limits the potential of governed actions, when faulting, to bring down the system.
        /// <para>When an execution would cause the number of actions executing concurrently through the policy to exceed <paramref name="maxParallelization" />, the policy allows a further <paramref name="maxQueuingActions" /> executions to queue, waiting for a concurrent execution slot.  When an execution would cause the number of queuing actions to exceed <paramref name="maxQueuingActions" />, a <see cref="BulkheadRejectedException" /> is thrown.</para>
        /// </summary>
        /// <param name="maxParallelization">The maximum number of concurrent actions that may be executing through the policy.</param>
        /// <param name="maxQueuingActions">The maxmimum number of actions that may be queuing, waiting for an execution slot.</param>
        /// <param name="onBulkheadRejectedAsync">An action to call asynchronously, if the bulkhead rejects execution due to oversubscription.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">maxParallelization;Value must be greater than zero.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">maxQueuingActions;Value must be greater than or equal to zero.</exception>
        /// <exception cref="System.ArgumentNullException">onBulkheadRejectedAsync</exception>
        public static BulkheadPolicy <TResult> BulkheadAsync <TResult>(int maxParallelization, int maxQueuingActions, Func <Context, Task> onBulkheadRejectedAsync)
        {
            if (maxParallelization <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxParallelization), "Value must be greater than zero.");
            }
            if (maxQueuingActions < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxQueuingActions), "Value must be greater than or equal to zero.");
            }
            if (onBulkheadRejectedAsync == null)
            {
                throw new ArgumentNullException(nameof(onBulkheadRejectedAsync));
            }

            SemaphoreSlim maxParallelizationSemaphore = new SemaphoreSlim(maxParallelization, maxParallelization);

            var maxQueuingCompounded = maxQueuingActions <= int.MaxValue - maxParallelization
                ? maxQueuingActions + maxParallelization
                : int.MaxValue;
            SemaphoreSlim maxQueuedActionsSemaphore = new SemaphoreSlim(maxQueuingCompounded, maxQueuingCompounded);

            return(new BulkheadPolicy <TResult>(
                       (action, context, cancellationToken, continueOnCapturedContext) => BulkheadEngine.ImplementationAsync(
                           action,
                           context,
                           onBulkheadRejectedAsync,
                           maxParallelizationSemaphore,
                           maxQueuedActionsSemaphore,
                           cancellationToken,
                           continueOnCapturedContext),
                       maxParallelization,
                       maxQueuingActions,
                       maxParallelizationSemaphore,
                       maxQueuedActionsSemaphore
                       ));
        }