Example #1
0
        public async Task WaitForExternalEvent_Should_Return_Successful_When_Task_Faster_Than_Timeout(int taskDelay, int timeoutDelay)
        {
            Sources source = Sources.Validator;
            string  externalEventReturn = "FakeEvent";
            var     fakeTimeout         = TimeSpan.FromSeconds(timeoutDelay);

            var ctx = CreateMockedOrquestratorContext(taskDelay, timeoutDelay, externalEventReturn);

            string testEventNameReturn =
                await DurableOrchestrationContextExtensions
                .WaitForExternalEventWithTimeout <string>(ctx.Object, source, fakeTimeout);

            Assert.Equal(externalEventReturn, testEventNameReturn);
        }
Example #2
0
        public async Task <SagaState> OrchestrateAsync(TransactionItem input, IDurableOrchestrationContext context, ILogger log)
        {
            bool sagaSatePersisted = await SagaStatePersisters[nameof(SagaState.Pending)]();

            if (!sagaSatePersisted)
            {
                return(SagaState.Fail);
            }

            ActivityResult <ProducerResult> validateTransferCommandResult = await CommandProducers[nameof(ValidateTransferCommand)]();

            if (!validateTransferCommandResult.Valid)
            {
                await SagaStatePersisters[nameof(SagaState.Fail)]();
                return(SagaState.Fail);
            }

            string validatorEventName = await DurableOrchestrationContextExtensions
                                        .WaitForExternalEventWithTimeout <string>(context, Sources.Validator, ValidatorTimeout);

            if (validatorEventName != nameof(TransferValidatedEvent))
            {
                log.LogError(string.Format(ConstantStrings.DurableOrchestratorErrorMessage, validatorEventName, Sources.Validator, context.InstanceId));
                await SagaStatePersisters[nameof(SagaState.Fail)]();

                return(SagaState.Fail);
            }

            ActivityResult <ProducerResult> transferCommandResult = await CommandProducers[nameof(TransferCommand)]();

            if (!transferCommandResult.Valid)
            {
                await SagaStatePersisters[nameof(SagaState.Fail)]();
                return(SagaState.Fail);
            }

            string transferEventName = await DurableOrchestrationContextExtensions
                                       .WaitForExternalEventWithTimeout <string>(context, Sources.Transfer, TransferTimeout);

            if (transferEventName != nameof(TransferSucceededEvent))
            {
                log.LogError(string.Format(ConstantStrings.DurableOrchestratorErrorMessage, transferEventName, Sources.Transfer, context.InstanceId));

                await SagaStatePersisters[nameof(SagaState.Fail)]();
                return(SagaState.Fail);
            }

            ActivityResult <ProducerResult> issueReceiptCommandResult = await CommandProducers[nameof(IssueReceiptCommand)]();

            if (!issueReceiptCommandResult.Valid)
            {
                await SagaStatePersisters[nameof(SagaState.Fail)]();
                return(SagaState.Fail);
            }

            string receiptEventName = await DurableOrchestrationContextExtensions
                                      .WaitForExternalEventWithTimeout <string>(context, Sources.Receipt, ReceiptTimeout);

            if (receiptEventName != nameof(ReceiptIssuedEvent))
            {
                log.LogError(string.Format(ConstantStrings.DurableOrchestratorErrorMessage, receiptEventName, Sources.Receipt, context.InstanceId));

                ActivityResult <ProducerResult> cancelTransferCommandResult = await CommandProducers[nameof(CancelTransferCommand)]();

                if (!cancelTransferCommandResult.Valid)
                {
                    await SagaStatePersisters[nameof(SagaState.Fail)]();
                    return(SagaState.Fail);
                }

                string compensatedTransferEventName = await DurableOrchestrationContextExtensions
                                                      .WaitForExternalEventWithTimeout <string>(context, Sources.Transfer, TransferTimeout);

                if (compensatedTransferEventName == nameof(TransferCanceledEvent))
                {
                    await SagaStatePersisters[nameof(SagaState.Cancelled)]();
                    return(SagaState.Cancelled);
                }

                await SagaStatePersisters[nameof(SagaState.Fail)]();
                return(SagaState.Fail);
            }

            await SagaStatePersisters[nameof(SagaState.Success)]();

            log.LogInformation($@"Saga '{context.InstanceId}' finished successfully.");

            return(SagaState.Success);
        }