예제 #1
0
        public async Task RunAsync(FabricClient fc, FabricTestAction action, ActionStateBase actionState, ServiceInternalFaultInfo serviceInternalFaultInfo, CancellationToken cancellationToken)
        {
            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Inside RunAsync of Engine, entering state machine", actionState.OperationId);
            try
            {
                do
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    RollbackState readRollbackState = await this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, cancellationToken, FASConstants.OuterLoop).ConfigureAwait(false);

                    // For the non-force case we need to cleanup, so that is why there's no break statement in that case.
                    if (readRollbackState == RollbackState.RollingBackForce)
                    {
                        actionState.StateProgress.Push(StepStateNames.Failed);
                        await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);

                        break;
                    }

                    await this.RunStateMachineAsync(fc, action, actionState, serviceInternalFaultInfo, cancellationToken).ConfigureAwait(false);

                    if (actionState.RollbackState == RollbackState.RollingBackAndWillRetryAction)
                    {
                        actionState.ErrorCausingRollback = 0;
                        int pauseTime = this.random.Next(10, 60);
                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Pausing for {1} seconds before retrying", actionState.OperationId, pauseTime);

                        // Clear the rollback state so it will go forward when it resumes.
                        actionState.RollbackState = RollbackState.NotRollingBack;
                        await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);

                        await Task.Delay(TimeSpan.FromSeconds(pauseTime), cancellationToken).ConfigureAwait(false);
                    }
                }while (actionState.StateProgress.Peek() != StepStateNames.CompletedSuccessfully &&
                        actionState.StateProgress.Peek() != StepStateNames.Failed);
            }
            catch (FabricNotPrimaryException notPrimary)
            {
                FaultAnalysisServiceUtility.TraceFabricNotPrimary(actionState.OperationId, notPrimary);
            }
            catch (FabricObjectClosedException objectClosed)
            {
                FaultAnalysisServiceUtility.TraceFabricObjectClosed(actionState.OperationId, objectClosed);
            }
            catch (Exception e)
            {
                TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} caught exception - {1}", actionState.OperationId, e);
                throw;
            }

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Exiting state machine", actionState.OperationId);
        }
예제 #2
0
        // This method should only run one at a time (controlled by timer)
        public async Task TruncateCallbackInnerAsync()
        {
            bool observedException = false;

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Enter truncate callback");

            try
            {
                long count = await FaultAnalysisServiceUtility.RunAndReportFaultOnRepeatedFailure(
                    Guid.Empty,
                    () => this.GetActionCountAsync(true),
                    this.partition,
                    "GetActionCountAsync",
                    ActionStore.MaxRetries,
                    this.cancellationToken).ConfigureAwait(false);

                TestabilityTrace.TraceSource.WriteInfo(TraceType, "Action store size is {0}", count);
                if (count > this.maxStoredActionCount)
                {
                    await FaultAnalysisServiceUtility.RunAndReportFaultOnRepeatedFailure(
                        Guid.Empty,
                        () => this.TruncateAsync(count),
                        this.partition,
                        "TruncateCallbackInnerAsync",
                        ActionStore.MaxRetries,
                        this.cancellationToken).ConfigureAwait(false);
                }
            }
            catch (FabricNotPrimaryException fnp)
            {
                FaultAnalysisServiceUtility.TraceFabricNotPrimary(Guid.Empty, fnp);
                observedException = true;
            }
            catch (FabricObjectClosedException foc)
            {
                FaultAnalysisServiceUtility.TraceFabricObjectClosed(Guid.Empty, foc);
                observedException = true;
            }
            catch (Exception e)
            {
                TestabilityTrace.TraceSource.WriteInfo(TraceType, "Error: {0}", e.ToString());
                observedException = true;
                throw;
            }

            if (!observedException)
            {
                TestabilityTrace.TraceSource.WriteInfo(TraceType, "Rescheduling timer for {0} seconds", this.storedActionCleanupIntervalInSeconds);
                this.truncateTimer.Change(TimeSpan.FromSeconds(this.storedActionCleanupIntervalInSeconds), Timeout.InfiniteTimeSpan);
            }
        }
        // Launched as a task
        private async Task ConsumeAndRunActionsAsync(CancellationToken cancellationToken)
        {
            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Enter ConsumeAndRunActions");

            using (SemaphoreSlim semaphore = new SemaphoreSlim(this.concurrentRequests, this.concurrentRequests))
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        TestabilityTrace.TraceSource.WriteNoise(TraceType, "DEBUG Waiting for semaphore, max count={0}", this.concurrentRequests);
                        await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);

                        TestabilityTrace.TraceSource.WriteNoise(TraceType, "DEBUG Done waiting for semaphore");
                    }
                    catch (OperationCanceledException e)
                    {
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, e.ToString());
                        break;
                    }

                    ActionStateBase actionState   = null;
                    bool            wasSuccessful = false;
                    try
                    {
                        TestabilityTrace.TraceSource.WriteNoise(TraceType, "Trying to Dequeue");

                        wasSuccessful = this.queue.TryTake(out actionState);
                        if (!wasSuccessful)
                        {
                            TestabilityTrace.TraceSource.WriteNoise(TraceType, "Queue was empty");
                            semaphore.Release();
                            await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);

                            continue;
                        }

                        TestabilityTrace.TraceSource.WriteNoise(TraceType, "Dequeued Name={0} Key={1}", actionState.ActionType, actionState.OperationId);
                    }
                    catch (OperationCanceledException e)
                    {
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, e.ToString());
                        break;
                    }
                    catch (Exception ex)
                    {
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, "TryDequeue failed with={0}", ex.ToString());
                        semaphore.Release();
                        continue;
                    }

                    Task t = null;
                    try
                    {
                        System.Fabric.FaultAnalysis.Service.Actions.FabricTestAction action = await this.ConstructActionAsync(actionState.ActionType, actionState);

                        t = this.engine.RunAsync(this.fabricClient, action, actionState, actionState.ServiceInternalFaultInfo, cancellationToken);
                    }
                    catch (FabricNotPrimaryException notPrimary)
                    {
                        FaultAnalysisServiceUtility.TraceFabricNotPrimary(actionState.OperationId, notPrimary);
                        break;
                    }
                    catch (FabricObjectClosedException objectClosed)
                    {
                        FaultAnalysisServiceUtility.TraceFabricObjectClosed(actionState.OperationId, objectClosed);
                        break;
                    }

                    if (!this.pendingTasks.TryAdd(actionState.OperationId, new ActionCompletionInfo(actionState.OperationId, t, semaphore)))
                    {
                        TestabilityTrace.TraceSource.WriteError(TraceType, "Add of key={0} failed, was it already added?", actionState.OperationId);
                        ReleaseAssert.Failfast("Add of key={0} failed, was it already added?", actionState.OperationId);
                    }
                    else
                    {
                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "Action type={0}, key={1} started", actionState.ActionType, actionState.OperationId);
                    }

                    Interlocked.Increment(ref this.isShuttingDown);
                }

                TestabilityTrace.TraceSource.WriteWarning(TraceType, "Cancellation was requested");

                return;
            }
        }