Exemple #1
0
        public async Task InvokeAsync(IQueryContext context)
        {
            if (IsContextIncomplete(context))
            {
                // TODO : resources
                context.Result = QueryResult.CreateError(new QueryError(
                                                             "The execute operation middleware expects the " +
                                                             "query document to be parsed and the operation to " +
                                                             "be resolved."));
            }
            else
            {
                Activity activity = _diagnosticEvents.BeginOperation(context);

                try
                {
                    IExecutionStrategy strategy = _strategyResolver
                                                  .Resolve(context.Operation.Type);
                    IExecutionContext executionContext =
                        CreateExecutionContext(context);

                    context.Result = await strategy.ExecuteAsync(
                        executionContext, executionContext.RequestAborted)
                                     .ConfigureAwait(false);
                }
                finally
                {
                    _diagnosticEvents.EndOperation(activity, context);
                }
            }

            await _next(context).ConfigureAwait(false);
        }
Exemple #2
0
        public async Task <TResponse> Handle(
            TRequest request,
            CancellationToken cancellationToken,
            RequestHandlerDelegate <TResponse> next)
        {
            TResponse response = default(TResponse);
            string    typeName = typeof(TRequest).Name;

            try
            {
                if (_dbContext.HasActiveTransaction)
                {
                    return(await next());
                }

                IExecutionStrategy strategy = _dbContext.Database.CreateExecutionStrategy();

                await strategy.ExecuteAsync(async() =>
                {
                    using (IDbContextTransaction transaction = await _dbContext.BeginTransactionAsync())
                    {
                        response = await next();
                        await _dbContext.CommitTransactionAsync(transaction);
                    }
                });

                return(response);
            }
            catch (Exception)
            {
                throw;
            }
        }
            public async ValueTask <bool> MoveNextAsync()
            {
                try
                {
                    using (_relationalQueryContext.ConcurrencyDetector.EnterCriticalSection())
                    {
                        if (_dataReader == null)
                        {
                            if (_executionStrategy == null)
                            {
                                _executionStrategy = _relationalQueryContext.ExecutionStrategyFactory.Create();
                            }

                            await _executionStrategy.ExecuteAsync(true, InitializeReaderAsync, null, _cancellationToken).ConfigureAwait(false);
                        }

                        var hasNext = await _dataReader.ReadAsync(_cancellationToken).ConfigureAwait(false);

                        Current = hasNext
                            ? _shaper(_relationalQueryContext, _dataReader.DbDataReader, _indexMap)
                            : default;

                        return(hasNext);
                    }
                }
                catch (Exception exception)
                {
                    _queryLogger.QueryIterationFailed(_contextType, exception);

                    throw;
                }
            }
Exemple #4
0
        public async Task <IExecutionResult> ExecuteAsync(
            OperationRequest request,
            CancellationToken cancellationToken)
        {
            var requestTimeoutCts =
                new CancellationTokenSource(_executionTimeout);

            var combinedCts =
                CancellationTokenSource.CreateLinkedTokenSource(
                    requestTimeoutCts.Token, cancellationToken);

            IExecutionContext executionContext =
                CreateExecutionContext(request);

            try
            {
                return(await _strategy.ExecuteAsync(
                           executionContext, combinedCts.Token));
            }
            finally
            {
                executionContext.Dispose();
                combinedCts.Dispose();
                requestTimeoutCts.Dispose();
            }
        }
Exemple #5
0
        private async Task <ObjectResult <T> > GetResultsAsync(
            MergeOption?forMergeOption, IExecutionStrategy executionStrategy, CancellationToken cancellationToken)
        {
            var mergeOption = forMergeOption.HasValue
                                  ? forMergeOption.Value
                                  : QueryState.EffectiveMergeOption;

            if (mergeOption != MergeOption.NoTracking)
            {
                QueryState.ObjectContext.AsyncMonitor.Enter();
            }

            try
            {
                return(await executionStrategy.ExecuteAsync(
                           () => QueryState.ObjectContext.ExecuteInTransactionAsync(
                               () => QueryState.GetExecutionPlan(forMergeOption)
                               .ExecuteAsync <T>(QueryState.ObjectContext, QueryState.Parameters, cancellationToken),
                               /*throwOnExistingTransaction:*/ executionStrategy.RetriesOnFailure,
                               /*startLocalTransaction:*/ false, /*releaseConnectionOnSuccess:*/ !QueryState.EffectiveStreamingBehaviour,
                               cancellationToken),
                           cancellationToken).ConfigureAwait(continueOnCapturedContext: false));
            }
            finally
            {
                if (mergeOption != MergeOption.NoTracking)
                {
                    QueryState.ObjectContext.AsyncMonitor.Exit();
                }
            }
        }
        public async Task InvokeAsync(IQueryContext context)
        {
            if (IsContextIncomplete(context))
            {
                context.Result = QueryResult.CreateError(
                    ErrorBuilder.New()
                    .SetMessage(CoreResources.ExecuteOperationMiddleware_InComplete)
                    .SetCode(ErrorCodes.Execution.Incomplete)
                    .Build());
            }
            else
            {
                Activity activity = _diagnosticEvents.BeginOperation(context);

                try
                {
                    IExecutionStrategy strategy = _strategyResolver
                                                  .Resolve(context.Operation.Type);
                    IExecutionContext executionContext =
                        CreateExecutionContext(context);

                    context.Result = await strategy.ExecuteAsync(
                        executionContext, executionContext.RequestAborted)
                                     .ConfigureAwait(false);
                }
                finally
                {
                    _diagnosticEvents.EndOperation(activity, context);
                }
            }

            await _next(context).ConfigureAwait(false);
        }
Exemple #7
0
        public async Task <IExecutionResult> ExecuteAsync(
            IReadOnlyDictionary <string, IValueNode> variableValues = null,
            object initialValue = null,
            CancellationToken cancellationToken = default)
        {
            var requestTimeoutCts =
                new CancellationTokenSource(_executionTimeout);

            CancellationTokenSource combinedCts =
                CancellationTokenSource.CreateLinkedTokenSource(
                    requestTimeoutCts.Token, cancellationToken);

            try
            {
                IExecutionContext executionContext =
                    CreateExecutionContext(variableValues, initialValue);
                return(await _strategy.ExecuteAsync(
                           executionContext, combinedCts.Token));
            }
            finally
            {
                combinedCts.Dispose();
                requestTimeoutCts.Dispose();
            }
        }
            public async Task <bool> MoveNext(CancellationToken cancellationToken)
            {
                cancellationToken.ThrowIfCancellationRequested();

                try
                {
                    await _relationalQueryContext.Connection.Semaphore.WaitAsync(cancellationToken);

                    if (_buffer == null)
                    {
                        if (_executionStrategy == null)
                        {
                            _executionStrategy = _relationalQueryContext.ExecutionStrategyFactory.Create();
                        }

                        return(await _executionStrategy
                               .ExecuteAsync(_executionStrategy.RetriesOnFailure, _bufferlessMoveNext, null, cancellationToken));
                    }

                    if (_buffer.Count > 0)
                    {
                        Current = _shaper.Shape(_relationalQueryContext, _buffer.Dequeue());

                        return(true);
                    }

                    return(false);
                }
                finally
                {
                    _relationalQueryContext.Connection.Semaphore.Release();
                }
            }
Exemple #9
0
            public async ValueTask <bool> MoveNextAsync()
            {
                try
                {
                    using (_relationalQueryContext.ConcurrencyDetector.EnterCriticalSection())
                    {
                        if (_dataReader == null)
                        {
                            if (_executionStrategy == null)
                            {
                                _executionStrategy = _relationalQueryContext.ExecutionStrategyFactory.Create();
                            }

                            await _executionStrategy.ExecuteAsync(true, InitializeReaderAsync, null, _cancellationToken);
                        }

                        var hasNext = _resultCoordinator.HasNext ?? await _dataReader.ReadAsync(_cancellationToken);

                        Current = default;

                        if (hasNext)
                        {
                            while (true)
                            {
                                _resultCoordinator.ResultReady = true;
                                _resultCoordinator.HasNext     = null;
                                Current = _shaper(
                                    _relationalQueryContext, _dataReader.DbDataReader,
                                    _resultCoordinator.ResultContext, _indexMap, _resultCoordinator);
                                if (_resultCoordinator.ResultReady)
                                {
                                    // We generated a result so null out previously stored values
                                    _resultCoordinator.ResultContext.Values = null;
                                    break;
                                }

                                if (!await _dataReader.ReadAsync(_cancellationToken))
                                {
                                    _resultCoordinator.HasNext = false;
                                    // Enumeration has ended, materialize last element
                                    _resultCoordinator.ResultReady = true;
                                    Current = _shaper(
                                        _relationalQueryContext, _dataReader.DbDataReader,
                                        _resultCoordinator.ResultContext, _indexMap, _resultCoordinator);

                                    break;
                                }
                            }
                        }

                        return(hasNext);
                    }
                }
                catch (Exception exception)
                {
                    _logger.QueryIterationFailed(_contextType, exception);

                    throw;
                }
            }
Exemple #10
0
        private async Task ExecuteTaskAsync(ICakeContext context, IExecutionStrategy strategy, Stopwatch stopWatch, CakeTask task, CakeReport report)
        {
            // Reset the stop watch.
            stopWatch.Reset();
            stopWatch.Start();

            PerformTaskSetup(context, strategy, task, false);

            bool exceptionWasThrown = false;

            try
            {
                // Execute the task.
                await strategy.ExecuteAsync(task, context).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                _log.Error("An error occurred when executing task '{0}'.", task.Name);

                exceptionWasThrown = true;

                // Got an error reporter?
                if (task.ErrorReporter != null)
                {
                    ReportErrors(strategy, task.ErrorReporter, exception);
                }

                // Got an error handler?
                if (task.ErrorHandler != null)
                {
                    HandleErrors(strategy, task.ErrorHandler, exception);
                }
                else
                {
                    // No error handler defined for this task.
                    // Rethrow the exception and let it propagate.
                    throw;
                }
            }
            finally
            {
                if (task.FinallyHandler != null)
                {
                    strategy.InvokeFinally(task.FinallyHandler);
                }

                PerformTaskTeardown(context, strategy, task, stopWatch.Elapsed, false, exceptionWasThrown);
            }

            // Add the task results to the report
            if (IsDelegatedTask(task))
            {
                report.AddDelegated(task.Name, stopWatch.Elapsed);
            }
            else
            {
                report.Add(task.Name, stopWatch.Elapsed);
            }
        }
Exemple #11
0
 /// <summary>
 ///     Executes the specified asynchronous operation.
 /// </summary>
 /// <param name="strategy">The strategy that will be used for the execution.</param>
 /// <param name="operation">A function that returns a started task.</param>
 /// <returns>
 ///     A task that will run to completion if the original task completes successfully (either the
 ///     first time or after retrying transient failures). If the task fails with a non-transient error or
 ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
 /// </returns>
 public static Task ExecuteAsync(
     [NotNull] this IExecutionStrategy strategy,
     [NotNull] Func <Task> operation)
 => strategy.ExecuteAsync(async(operationScoped, ct) =>
 {
     await operationScoped();
     return(true);
 }, operation, default(CancellationToken));
Exemple #12
0
    /// <summary>
    ///     Executes the specified asynchronous operation and returns the result.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see>
    ///     for more information and examples.
    /// </remarks>
    /// <param name="strategy">The strategy that will be used for the execution.</param>
    /// <param name="operation">
    ///     A function that returns a started task of type <typeparamref name="TResult" />.
    /// </param>
    /// <typeparam name="TResult">
    ///     The result type of the <see cref="Task{T}" /> returned by <paramref name="operation" />.
    /// </typeparam>
    /// <returns>
    ///     A task that will run to completion if the original task completes successfully (either the
    ///     first time or after retrying transient failures). If the task fails with a non-transient error or
    ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
    /// </returns>
    public static Task <TResult> ExecuteAsync <TResult>(
        this IExecutionStrategy strategy,
        Func <Task <TResult> > operation)
    {
        Check.NotNull(operation, nameof(operation));

        return(strategy.ExecuteAsync(operation, (operationScoped, ct) => operationScoped(), default));
    }
        /// <summary>
        /// Run samples for Order By queries.
        /// </summary>
        /// <returns>a Task object.</returns>
        private async Task ExecuteAsync(BenchmarkConfig config)
        {
            if (config.CleanupOnStart)
            {
                Database database = this.client.GetDatabase(config.Database);
                await database.DeleteStreamAsync();
            }

            ContainerResponse containerResponse = await this.CreatePartitionedContainerAsync(config);

            Container container = containerResponse;

            int?currentContainerThroughput = await container.ReadThroughputAsync();

            Console.WriteLine($"Using container {config.Container} with {currentContainerThroughput} RU/s");

            int taskCount = config.GetTaskCount(currentContainerThroughput.Value);

            Console.WriteLine("Starting Inserts with {0} tasks", taskCount);
            Console.WriteLine();

            string partitionKeyPath      = containerResponse.Resource.PartitionKeyPath;
            int    numberOfItemsToInsert = config.ItemCount / taskCount;
            string sampleItem            = File.ReadAllText(config.ItemTemplateFile);

            IBenchmarkOperatrion benchmarkOperation = null;

            switch (config.WorkloadType.ToLower())
            {
            case "insert":
                benchmarkOperation = new InsertBenchmarkOperation(
                    container,
                    partitionKeyPath,
                    sampleItem);
                break;

            case "read":
                benchmarkOperation = new ReadBenchmarkOperation(
                    container,
                    partitionKeyPath,
                    sampleItem);
                break;

            default:
                throw new NotImplementedException($"Unsupported workload type {config.WorkloadType}");
            }

            IExecutionStrategy execution = IExecutionStrategy.StartNew(config, benchmarkOperation);
            await execution.ExecuteAsync(taskCount, numberOfItemsToInsert, 0.01);

            if (config.CleanupOnFinish)
            {
                Console.WriteLine($"Deleting Database {config.Database}");
                Database database = this.client.GetDatabase(config.Database);
                await database.DeleteStreamAsync();
            }
        }
Exemple #14
0
 /// <summary>
 ///     Executes the specified asynchronous operation.
 /// </summary>
 /// <param name="strategy">The strategy that will be used for the execution.</param>
 /// <param name="operation">A function that returns a started task.</param>
 /// <param name="state">The state that will be passed to the operation.</param>
 /// <typeparam name="TState">The type of the state.</typeparam>
 /// <returns>
 ///     A task that will run to completion if the original task completes successfully (either the
 ///     first time or after retrying transient failures). If the task fails with a non-transient error or
 ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
 /// </returns>
 public static Task ExecuteAsync <TState>(
     [NotNull] this IExecutionStrategy strategy,
     [NotNull] Func <TState, Task> operation,
     [CanBeNull] TState state)
 => strategy.ExecuteAsync(async(t, ct) =>
 {
     await t.operation(t.state);
     return(true);
 }, new { operation, state }, default(CancellationToken));
Exemple #15
0
        /// <summary>
        ///     Executes the specified asynchronous operation and returns the result.
        /// </summary>
        /// <param name="strategy">The strategy that will be used for the execution.</param>
        /// <param name="state">The state that will be passed to the operation.</param>
        /// <param name="operation">
        ///     A function that returns a started task of type <typeparamref name="TResult" />.
        /// </param>
        /// <typeparam name="TState">The type of the state.</typeparam>
        /// <typeparam name="TResult">
        ///     The result type of the <see cref="Task{T}" /> returned by <paramref name="operation" />.
        /// </typeparam>
        /// <returns>
        ///     A task that will run to completion if the original task completes successfully (either the
        ///     first time or after retrying transient failures). If the task fails with a non-transient error or
        ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
        /// </returns>
        public static Task <TResult> ExecuteAsync <TState, TResult>(
            [NotNull] this IExecutionStrategy strategy,
            [CanBeNull] TState state,
            [NotNull] Func <TState, Task <TResult> > operation)
        {
            Check.NotNull(operation, nameof(operation));

            return(strategy.ExecuteAsync(new { operation, state }, (t, ct) => t.operation(t.state), default));
        }
Exemple #16
0
    /// <summary>
    ///     Executes the specified asynchronous operation and returns the result.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see>
    ///     for more information and examples.
    /// </remarks>
    /// <param name="strategy">The strategy that will be used for the execution.</param>
    /// <param name="operation">
    ///     A function that returns a started task of type <typeparamref name="TResult" />.
    /// </param>
    /// <param name="cancellationToken">
    ///     A cancellation token used to cancel the retry operation, but not operations that are already in flight
    ///     or that already completed successfully.
    /// </param>
    /// <typeparam name="TResult">
    ///     The result type of the <see cref="Task{T}" /> returned by <paramref name="operation" />.
    /// </typeparam>
    /// <returns>
    ///     A task that will run to completion if the original task completes successfully (either the
    ///     first time or after retrying transient failures). If the task fails with a non-transient error or
    ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
    /// </returns>
    /// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
    public static Task <TResult> ExecuteAsync <TResult>(
        this IExecutionStrategy strategy,
        Func <CancellationToken, Task <TResult> > operation,
        CancellationToken cancellationToken)
    {
        Check.NotNull(operation, nameof(operation));

        return(strategy.ExecuteAsync(operation, (operationScoped, ct) => operationScoped(ct), cancellationToken));
    }
Exemple #17
0
        private async Task ExecuteTaskAsync(ICakeContext context, IExecutionStrategy strategy, CancellationTokenSource cts, CakeTask task, CakeReport report)
        {
            _log.Verbose($"Starting task {task.Name}");
            var stopwatch = Stopwatch.StartNew();

            PerformTaskSetup(context, strategy, task, false);

            var execptionWasThrown = false;

            try
            {
                var taskExecutionContext = new TaskExecutionContext(context, task);

                await strategy.ExecuteAsync(task, taskExecutionContext).ConfigureAwait(false);
            }
            catch (TaskCanceledException)
            {
                execptionWasThrown = true;
                throw;
            }
            catch (Exception exception)
            {
                execptionWasThrown = true;
                _log.Error($"An error occurred when executing task '{task.Name}'.");

                if (task.ErrorReporter != null)
                {
                    ReportErrors(strategy, task.ErrorReporter, exception);
                }

                if (task.ErrorHandler != null)
                {
                    HandleErrors(strategy, task.ErrorHandler, exception);
                }
                else
                {
                    cts.Cancel();
                    throw;
                }
            }
            finally
            {
                strategy.InvokeFinally(task.FinallyHandler);

                PerformTaskTeardown(context, strategy, task, stopwatch.Elapsed, false, execptionWasThrown);
            }

            if (isDelegatedTask(task))
            {
                report.AddDelegated(task.Name, stopwatch.Elapsed);
            }
            else
            {
                report.Add(task.Name, stopwatch.Elapsed);
            }
        }
Exemple #18
0
 /// <summary>
 ///     Executes the specified asynchronous operation in a transaction and returns the result. Allows to check whether
 ///     the transaction has been rolled back if an error occurs during commit.
 /// </summary>
 /// <remarks>
 ///     See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see>
 ///     for more information and examples.
 /// </remarks>
 /// <param name="strategy">The strategy that will be used for the execution.</param>
 /// <param name="state">The state that will be passed to the operation.</param>
 /// <param name="operation">
 ///     A function that returns a started task of type <typeparamref name="TResult" />.
 /// </param>
 /// <param name="verifySucceeded">
 ///     A delegate that tests whether the operation succeeded even though an exception was thrown when the
 ///     transaction was being committed.
 /// </param>
 /// <param name="beginTransaction">A delegate that begins a transaction using the given context.</param>
 /// <param name="cancellationToken">
 ///     A cancellation token used to cancel the retry operation, but not operations that are already in flight
 ///     or that already completed successfully.
 /// </param>
 /// <typeparam name="TState">The type of the state.</typeparam>
 /// <typeparam name="TResult">The result type of the <see cref="Task{T}" /> returned by <paramref name="operation" />.</typeparam>
 /// <returns>
 ///     A task that will run to completion if the original task completes successfully (either the
 ///     first time or after retrying transient failures). If the task fails with a non-transient error or
 ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
 /// </returns>
 /// <exception cref="RetryLimitExceededException">
 ///     The operation has not succeeded after the configured number of retries.
 /// </exception>
 /// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
 public static Task <TResult> ExecuteInTransactionAsync <TState, TResult>(
     IExecutionStrategy strategy,
     TState state,
     Func <TState, CancellationToken, Task <TResult> > operation,
     Func <TState, CancellationToken, Task <bool> > verifySucceeded,
     Func <DbContext, CancellationToken, Task <IDbContextTransaction> > beginTransaction,
     CancellationToken cancellationToken = default)
 => strategy.ExecuteAsync(
     new ExecutionStateAsync <TState, TResult>(
         Check.NotNull(operation, nameof(operation)), Check.NotNull(verifySucceeded, nameof(verifySucceeded)), state),
     async(c, s, ct) =>
Exemple #19
0
 /// <summary>
 ///     Executes the specified asynchronous operation and returns the result.
 /// </summary>
 /// <remarks>
 ///     See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see>
 ///     for more information and examples.
 /// </remarks>
 /// <param name="strategy">The strategy that will be used for the execution.</param>
 /// <param name="state">The state that will be passed to the operation.</param>
 /// <param name="operation">
 ///     A function that returns a started task of type <typeparamref name="TResult" />.
 /// </param>
 /// <param name="verifySucceeded">A delegate that tests whether the operation succeeded even though an exception was thrown.</param>
 /// <param name="cancellationToken">
 ///     A cancellation token used to cancel the retry operation, but not operations that are already in flight
 ///     or that already completed successfully.
 /// </param>
 /// <typeparam name="TState">The type of the state.</typeparam>
 /// <typeparam name="TResult">The result type of the <see cref="Task{T}" /> returned by <paramref name="operation" />.</typeparam>
 /// <returns>
 ///     A task that will run to completion if the original task completes successfully (either the
 ///     first time or after retrying transient failures). If the task fails with a non-transient error or
 ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
 /// </returns>
 /// <exception cref="RetryLimitExceededException">
 ///     The operation has not succeeded after the configured number of retries.
 /// </exception>
 /// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
 public static Task <TResult> ExecuteAsync <TState, TResult>(
     this IExecutionStrategy strategy,
     TState state,
     Func <TState, CancellationToken, Task <TResult> > operation,
     Func <TState, CancellationToken, Task <ExecutionResult <TResult> > >?verifySucceeded,
     CancellationToken cancellationToken = default)
 => strategy.ExecuteAsync(
     state,
     (c, s, ct) => operation(s, ct),
     verifySucceeded == null
             ? null
             : (c, s, ct) => verifySucceeded(s, ct), cancellationToken);
        /// <summary>
        ///     Executes the specified asynchronous operation.
        /// </summary>
        /// <param name="strategy">The strategy that will be used for the execution.</param>
        /// <param name="operation">A function that returns a started task.</param>
        /// <returns>
        ///     A task that will run to completion if the original task completes successfully (either the
        ///     first time or after retrying transient failures). If the task fails with a non-transient error or
        ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
        /// </returns>
        public static Task ExecuteAsync(
            [NotNull] this IExecutionStrategy strategy,
            [NotNull] Func <Task> operation)
        {
            Check.NotNull(operation, nameof(operation));

            return(strategy.ExecuteAsync(operation, async(operationScoped, ct) =>
            {
                await operationScoped();
                return true;
            }, default(CancellationToken)));
        }
        /// <summary>
        ///     Executes the specified asynchronous operation.
        /// </summary>
        /// <param name="strategy">The strategy that will be used for the execution.</param>
        /// <param name="state">The state that will be passed to the operation.</param>
        /// <param name="operation">A function that returns a started task.</param>
        /// <typeparam name="TState">The type of the state.</typeparam>
        /// <returns>
        ///     A task that will run to completion if the original task completes successfully (either the
        ///     first time or after retrying transient failures). If the task fails with a non-transient error or
        ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
        /// </returns>
        public static Task ExecuteAsync <TState>(
            [NotNull] this IExecutionStrategy strategy,
            [CanBeNull] TState state,
            [NotNull] Func <TState, Task> operation)
        {
            Check.NotNull(operation, nameof(operation));

            return(strategy.ExecuteAsync(new { operation, state }, async(t, ct) =>
            {
                await t.operation(t.state);
                return true;
            }, default(CancellationToken)));
        }
Exemple #22
0
    /// <summary>
    ///     Executes the specified asynchronous operation.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see>
    ///     for more information and examples.
    /// </remarks>
    /// <param name="strategy">The strategy that will be used for the execution.</param>
    /// <param name="operation">A function that returns a started task.</param>
    /// <returns>
    ///     A task that will run to completion if the original task completes successfully (either the
    ///     first time or after retrying transient failures). If the task fails with a non-transient error or
    ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
    /// </returns>
    public static Task ExecuteAsync(
        this IExecutionStrategy strategy,
        Func <Task> operation)
    {
        Check.NotNull(operation, nameof(operation));

        return(strategy.ExecuteAsync(
                   operation, async(operationScoped, ct) =>
        {
            await operationScoped().ConfigureAwait(false);
            return true;
        }, default));
    }
Exemple #23
0
 public async Task InvokeAsync(IQueryContext context)
 {
     if (IsContextValid(context))
     {
         IExecutionStrategy strategy =
             _strategyResolver.Resolve(context.Operation.Operation);
         IExecutionContext execContext =
             CreateExecutionContext(context);
         context.Result = await strategy.ExecuteAsync(
             execContext, execContext.RequestAborted);
     }
     await _next(context);
 }
Exemple #24
0
    /// <summary>
    ///     Executes the specified asynchronous operation.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see>
    ///     for more information and examples.
    /// </remarks>
    /// <param name="strategy">The strategy that will be used for the execution.</param>
    /// <param name="state">The state that will be passed to the operation.</param>
    /// <param name="operation">A function that returns a started task.</param>
    /// <typeparam name="TState">The type of the state.</typeparam>
    /// <returns>
    ///     A task that will run to completion if the original task completes successfully (either the
    ///     first time or after retrying transient failures). If the task fails with a non-transient error or
    ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
    /// </returns>
    public static Task ExecuteAsync <TState>(
        this IExecutionStrategy strategy,
        TState state,
        Func <TState, Task> operation)
    {
        Check.NotNull(operation, nameof(operation));

        return(strategy.ExecuteAsync(
                   new { operation, state }, async(t, ct) =>
        {
            await t.operation(t.state).ConfigureAwait(false);
            return true;
        }, default));
    }
Exemple #25
0
    /// <summary>
    ///     Executes the specified asynchronous operation.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see>
    ///     for more information and examples.
    /// </remarks>
    /// <param name="strategy">The strategy that will be used for the execution.</param>
    /// <param name="operation">A function that returns a started task.</param>
    /// <param name="cancellationToken">
    ///     A cancellation token used to cancel the retry operation, but not operations that are already in flight
    ///     or that already completed successfully.
    /// </param>
    /// <returns>
    ///     A task that will run to completion if the original task completes successfully (either the
    ///     first time or after retrying transient failures). If the task fails with a non-transient error or
    ///     the retry limit is reached, the returned task will become faulted and the exception must be observed.
    /// </returns>
    /// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
    public static Task ExecuteAsync(
        this IExecutionStrategy strategy,
        Func <CancellationToken, Task> operation,
        CancellationToken cancellationToken)
    {
        Check.NotNull(operation, nameof(operation));

        return(strategy.ExecuteAsync(
                   operation, async(operationScoped, ct) =>
        {
            await operationScoped(ct).ConfigureAwait(false);
            return true;
        }, cancellationToken));
    }
 public async Task ExecuteAsync(Func <Task> action)
 {
     //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
     //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
     IExecutionStrategy strategy = _dbContext.Database.CreateExecutionStrategy();
     await strategy.ExecuteAsync(async() =>
     {
         using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction())
         {
             await action();
             transaction.Commit();
         }
     });
 }
 public static async Task ExecuteAsync <T>(
     this IDatabaseContextFactory <T> contextFactory,
     Func <IDatabaseContextFactory <T>, Task> operation)
     where T : DbContext
 {
     using (var context = contextFactory.Create())
     {
         IExecutionStrategy strategy = context.Database.CreateExecutionStrategy();
         await strategy.ExecuteAsync(async() =>
         {
             await operation(contextFactory);
         });
     }
 }
        /// <summary>
        /// Executes the specified task.
        /// </summary>
        /// <param name="task">The task to execute.</param>
        /// <param name="context">The context.</param>
        /// <returns>Returned Task</returns>
        public Task ExecuteAsync(CakeTask task, ICakeContext context)
        {
            if (task == null)
            {
                return(Task.CompletedTask);
            }

            if (_exclusiveTaskName != null && _exclusiveTaskName != task.Name)
            {
                _default.Skip(task, new CakeTaskCriteria(ctx => true, null));
                return(Task.CompletedTask);
            }
            return(_default.ExecuteAsync(task, context));
        }
                public async Task <ExecutionResult> ExecuteAsync(ExecutionContext context)
                {
                    var key           = typeof(IDependencyInjector).FullName ?? nameof(IDependencyInjector);
                    var outerInjector = context.UserContext[key];

                    try
                    {
                        context.UserContext[key] = _injector;
                        return(await _innerStrategy.ExecuteAsync(context));
                    }
                    finally
                    {
                        context.UserContext[key] = outerInjector;
                    }
                }
                public async Task <ExecutionResult> ExecuteAsync(ExecutionContext context)
                {
                    var outerUserContextWrapper = context.UserContext;
                    var userContext             = (context.UserContext as IUserContextAccessor)?.UserContext;

                    try
                    {
                        context.UserContext = UserContextWrapper.Create(userContext, _injector);
                        return(await _innerStrategy.ExecuteAsync(context));
                    }
                    finally
                    {
                        context.UserContext = outerUserContextWrapper;
                    }
                }