コード例 #1
0
    public static async Task Run(
        [OrchestrationTrigger] DurableOrchestrationContextBase context,
        ILogger log)
    {
        var input = context.GetInput <MessageInput>();

        var smsKey = await context.CallActivityAsync <string>("A_SaveTwilioMapping", context.InstanceId);

        input.SmsKey = smsKey;

        await context.CallActivityAsync <string>("A_SendTwilioText", input);

        var status = await context.WaitForExternalEvent <string>("TwilioCallback");

        log.LogWarning("Got a status from Twilio! " + status);
    }
コード例 #2
0
ファイル: CartOrchestrator.cs プロジェクト: lulzzz/durashop
        public static async Task <List <CartData> > Run([OrchestrationTrigger] DurableOrchestrationContextBase context, TraceWriter log)
        {
            var cart = context.GetInput <List <CartData> >() ?? new List <CartData>();

            var addItemTask     = context.WaitForExternalEvent <CartData>(CartEvents.AddItem);
            var removeItemTask  = context.WaitForExternalEvent <CartData>(CartEvents.RemoveItem);
            var isCompletedTask = context.WaitForExternalEvent <bool>(CartEvents.IsCompleted);
            var setCartReminder = context.WaitForExternalEvent <CartReminderData>(CartEvents.SetReminder);

            // Wait for any external event
            var resultingEvent = await Task.WhenAny(addItemTask, removeItemTask, isCompletedTask, setCartReminder);

            // Add item to cart
            if (resultingEvent == addItemTask)
            {
                cart.Add(addItemTask.Result);
                context.SetCustomStatus("readynow");
                if (!context.IsReplaying)
                {
                    log.Info($"Added {addItemTask.Result.ItemName} to the Shopping Cart.");
                }
            }

            // Remove Item from cart
            else if (resultingEvent == removeItemTask)
            {
                cart.Remove(cart.Find(x => x.ItemId == removeItemTask.Result.ItemId));
                context.SetCustomStatus("readynow");
                if (!context.IsReplaying)
                {
                    log.Info($"Removed {removeItemTask.Result.ItemName} from the Shopping Cart.");
                }
            }

            // Add reminder for cart (used to notify user of waiting cart with items)
            else if (resultingEvent == setCartReminder)
            {
                var provisionTask = context.CallSubOrchestratorAsync("SetCartNotificationTimer", setCartReminder.Result);
                if (!context.IsReplaying)
                {
                    log.Info($"Added timer ({setCartReminder.Result.RemindInMinutes} minutes) for Shopping Cart.");
                }
            }

            // Complete cart or stay running ?
            if (resultingEvent == isCompletedTask && isCompletedTask.Result)
            {
                if (!context.IsReplaying)
                {
                    log.Info("Completed the Shopping Cart.");
                }
            }
            else
            {
                context.ContinueAsNew(cart); // the magic line
                if (!context.IsReplaying)
                {
                    log.Info($"cartList Count: {cart.Count}");
                }
            }

            return(await Task.FromResult(cart));
        }
コード例 #3
0
        public static async Task <string> GetApprovalOrchestrator([OrchestrationTrigger]
                                                                  DurableOrchestrationContextBase ctx, ILogger log)
        {
            var    approvalConfig = ctx.GetInput <ApprovalConfig>();
            string result;
            var    expireAt = ctx.CurrentUtcDateTime.AddMinutes(approvalConfig.TimeoutMinutes);

            for (var n = 0; n < approvalConfig.ApproverCount; n++)
            {
                // todo: send a message to each approver
                if (!ctx.IsReplaying)
                {
                    log.LogInformation($"Requesting approval from Approver {n + 1}");
                }
            }

            var cts       = new CancellationTokenSource();
            var timerTask = ctx.CreateTimer(expireAt, cts.Token);

            var approvers = new HashSet <string>();

            while (true)
            {
                var externalEventTask = ctx.WaitForExternalEvent <ApprovalResult>(ApprovalResultEventName);
                var completed         = await Task.WhenAny(timerTask, externalEventTask);

                if (completed == timerTask)
                {
                    result = $"Timed out with {approvers.Count} approvals so far";
                    if (!ctx.IsReplaying)
                    {
                        log.LogWarning(result);
                    }
                    break; // end orchestration
                }
                else if (completed == externalEventTask)
                {
                    var approver = externalEventTask.Result.Approver;
                    if (externalEventTask.Result.Approved)
                    {
                        approvers.Add(approver);
                        if (!ctx.IsReplaying)
                        {
                            log.LogInformation($"Approval received from {approver}");
                        }
                        if (approvers.Count >= approvalConfig.RequiredApprovals)
                        {
                            result = $"Approved ({approvers.Count} approvals received)";
                            if (!ctx.IsReplaying)
                            {
                                log.LogInformation(result);
                            }
                            break;
                        }
                    }
                    else
                    {
                        result = $"Rejected by {approver}";
                        if (!ctx.IsReplaying)
                        {
                            log.LogWarning(result);
                        }
                        break;
                    }
                }
                else
                {
                    throw new InvalidOperationException("Unexpected result from Task.WhenAny");
                }
            }
            cts.Cancel();
            return(result);
        }
        public static async Task <OrderResult> ProcessOrder(
            [OrchestrationTrigger] DurableOrchestrationContextBase ctx,
            ILogger log)
        {
            var order = ctx.GetInput <Order>();

            order.OrchestrationId = ctx.InstanceId;

            if (!ctx.IsReplaying)
            {
                log.LogInformation($"Processing order #{order.Id}");
            }

            var total = order.Items.Sum(i => i.Amount);

            await ctx.CallActivityAsync("A_SaveOrderToDatabase", order);

            if (total > 1000)
            {
                if (!ctx.IsReplaying)
                {
                    log.LogWarning($"Need approval for {ctx.InstanceId}");
                }

                ctx.SetCustomStatus("Needs approval");
                await ctx.CallActivityAsync("A_RequestOrderApproval", order);

                var approvalResult = await ctx.WaitForExternalEvent <string>("OrderApprovalResult", TimeSpan.FromSeconds(180), null);

                ctx.SetCustomStatus(""); // clear the needs approval flag

                if (approvalResult != "Approved")
                {
                    // timed out or got a rejected
                    if (!ctx.IsReplaying)
                    {
                        log.LogWarning($"Not approved [{approvalResult}]");
                    }
                    await ctx.CallActivityAsync("A_SendNotApprovedEmail", order);

                    return(new OrderResult {
                        Status = "NotApproved"
                    });
                }
            }

            string[] downloads = null;
            try
            {
                // create files in parallel
                var tasks = new List <Task <string> >();
                foreach (var item in order.Items)
                {
                    tasks.Add(ctx.CallActivityAsync <string>("A_CreatePersonalizedPdf", (order, item)));
                }

                downloads = await Task.WhenAll(tasks);
            }
            catch (Exception ex)
            {
                if (!ctx.IsReplaying)
                {
                    log.LogError($"Failed to create files", ex);
                }
            }

            if (downloads != null)
            {
                await ctx.CallActivityWithRetryAsync("A_SendOrderConfirmationEmail",
                                                     new RetryOptions(TimeSpan.FromSeconds(30), 3),
                                                     (order, downloads));

                return(new OrderResult {
                    Status = "Success", Downloads = downloads
                });
            }
            await ctx.CallActivityWithRetryAsync("A_SendProblemEmail",
                                                 new RetryOptions(TimeSpan.FromSeconds(30), 3),
                                                 order);

            return(new OrderResult {
                Status = "Problem"
            });
        }
コード例 #5
0
        public static async Task <List <string> > E1_HelloSequenceWithSuborchestrator(
            [OrchestrationTrigger] DurableOrchestrationContextBase context)
        {
            Task <dynamic> cancellationTask = context.WaitForExternalEvent <dynamic>("CancelSequence");

            var outputs = new List <string>();
            //context.GetInput();
            await context.CallActivityAsync("SignalRAddUserToGroup", null);

            // STEP 1
            var step1 = context.CallSubOrchestratorAsync <SubOrchestratorExampleOutput>("SubOrchestratorExample", new SubOrchestratorExampleModel {
                Input    = "Seattle",
                Progress = 20
            });
            Task winner = await Task.WhenAny(cancellationTask, step1);

            if (winner == cancellationTask)
            {
                var x = cancellationTask.Result;
                outputs.Add("Canceled during step 1");
                await context.CallActivityAsync <string>("SendSignalRMessageActivity", new SignalRDto { id = context.InstanceId, message = $"Result: {String.Join(" ", outputs)}", progress = 100 });

                return(outputs);
            }
            outputs.Add(step1.Result.Message);

            // STEP 2
            var step2 = context.CallSubOrchestratorAsync <SubOrchestratorExampleOutput>("SubOrchestratorExample", new SubOrchestratorExampleModel
            {
                Input    = "Utrecht",
                Progress = 40
            });

            winner = await Task.WhenAny(cancellationTask, step2);

            if (winner == cancellationTask)
            {
                outputs.Add("Canceled during step 2");
                await context.CallActivityAsync <string>("SendSignalRMessageActivity", new SignalRDto { id = context.InstanceId, message = $"Result: {String.Join(" ", outputs)}", progress = 100 });

                return(outputs);
            }
            outputs.Add(step2.Result.Message);

            // STEP 3
            var step3 = context.CallSubOrchestratorAsync <SubOrchestratorExampleOutput>("SubOrchestratorExample", new SubOrchestratorExampleModel
            {
                Input    = "Future Tech",
                Progress = 60
            });

            winner = await Task.WhenAny(cancellationTask, step3);

            if (winner == cancellationTask)
            {
                outputs.Add("Canceled during step 3");
                await context.CallActivityAsync <string>("SendSignalRMessageActivity", new SignalRDto { id = context.InstanceId, message = $"Result: {String.Join(" ", outputs)}", progress = 100 });

                return(outputs);
            }
            outputs.Add(step3.Result.Message);

            await context.CallActivityAsync <string>("SendSignalRMessageActivity", new SignalRDto { id = context.InstanceId, message = $"Result: {String.Join(" ", outputs)}", progress = 100 });

            return(outputs);
        }
コード例 #6
0
 public static async Task DurableFunctionWithExternalEvent(
     [OrchestrationTrigger] DurableOrchestrationContextBase context)
 {
     await context.WaitForExternalEvent(ExternalEventName);
 }
コード例 #7
0
 public static async Task DurableFunctionWithExternalEventTimeout(
     [OrchestrationTrigger] DurableOrchestrationContextBase context)
 {
     var timeout = context.GetInput <TimeSpan>();
     await context.WaitForExternalEvent(ExternalEventName, timeout);
 }