public static async Task SubOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context) { var userId = context.GetInput <string>(); var folderId = await context.CallActivityAsync <string>("GetFolderId", new RequestData { UserId = userId }); var messages = await context.CallActivityAsync <List <ConversationHistoryTableStorage> >("GetMessages", new RequestData { UserId = userId, ConversationHistoryId = folderId }); if (messages.Count > 0) { await context.CallActivityAsync("InsertIntoStorageTable", messages); } }
public static async Task <string> SayHelloWithActivityForRewind([OrchestrationTrigger] DurableOrchestrationContext ctx) { string input = ctx.GetInput <string>(); string output = await ctx.CallActivityAsync <string>(nameof(TestActivities.Hello), input); if (SayHelloWithActivityForRewindShouldFail) { SayHelloWithActivityForRewindShouldFail = false; throw new Exception("Simulating Orchestration failure..."); } return(output); }
public static async Task Factorial([OrchestrationTrigger] DurableOrchestrationContext ctx) { int n = ctx.GetInput <int>(); long result = 1; for (int i = 1; i <= n; i++) { result = await ctx.CallFunctionAsync <int>(nameof(Activities.Multiply), new[] { result, i }); } ctx.SetOutput(result); }
public static async Task RunOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) { var myDateTimeOffset = context.GetInput <Input>().MyDateTimeOffset; if (!context.IsReplaying) { log.LogError($"Orchestrator received input: {myDateTimeOffset}"); log.LogInformation("Calling Activity"); } await context.CallActivityAsync("Function2_Hello", myDateTimeOffset); }
public static async Task <string> RunOrchestrator([OrchestrationTrigger] DurableOrchestrationContext context) { var name = context.GetInput <string>(); // retrieves the list of data by invoking a separate Activity Function. var books = await context.CallActivityAsync <List <Book> >("GetAllData", name); if (books.Count > 0) { //Saving the retrieved data to table await context.CallActivityAsync("SaveData", books); } return(context.InstanceId); }
public static async Task <string> RunOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context) { var userInfo = context.GetInput <UserInfo>(); var timeGreeting = await context.CallActivityAsync <string>("TimeGreeting", userInfo.Name); var locationGreeting = await context.CallActivityAsync <string>("LocationGreeting", userInfo.Location); string output = $"{timeGreeting} {locationGreeting}"; return(output); }
public static async Task <ResponseModel> RunDurableJob( [OrchestrationTrigger] DurableOrchestrationContext context, ILogger log, ExecutionContext execContext) { var config = JobFunction.GetConfiguration(execContext); JobModel model = JsonConvert.DeserializeObject <JobModel>(context.GetInput <string>()); ResponseModel response = await context.CallActivityAsync <ResponseModel>("RunJob", model); return(response); }
public static async Task <long> Factorial([OrchestrationTrigger] DurableOrchestrationContext ctx) { int n = ctx.GetInput <int>(); long result = 1; for (int i = 1; i <= n; i++) { result = await ctx.CallActivityAsync <int>(nameof(TestActivities.Multiply), new[] { result, i }); } return(result); }
public static async Task ThrowOrchestrator([OrchestrationTrigger] DurableOrchestrationContext ctx) { string message = ctx.GetInput <string>(); if (string.IsNullOrEmpty(message) || message.Contains("null")) { // This throw happens directly in the orchestration. throw new ArgumentNullException(nameof(message)); } // This throw happens in the implementation of an activity. await ctx.CallActivityAsync(nameof(TestActivities.ThrowActivity), message); }
public static async Task <List <string> > RunOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context) { var outputs = new List <string>(); string ExcelFileName = context.GetInput <string>(); List <Employee> employees = await context.CallActivityAsync <List <Employee> >("ReadExcel_AT", ExcelFileName); await context.CallActivityAsync <string>("ScaleRU_AT", 500); await context.CallActivityAsync <string>("ImportData_AT", employees); return(outputs); }
public async Task Run([OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) { var clearScheduleModel = context.GetInput <ClearScheduleModel>(); var pastWeeks = clearScheduleModel.PastWeeks ?? _options.PastWeeks; var futureWeeks = clearScheduleModel.FutureWeeks ?? _options.FutureWeeks; var timeZoneInfoId = await TimeZoneHelper.GetAndUpdateTimeZoneAsync(clearScheduleModel.TeamId, _timeZoneService, _scheduleConnectorService, _scheduleSourceService); timeZoneInfoId ??= _options.TimeZone; clearScheduleModel.StartDate = context.CurrentUtcDateTime.Date .StartOfWeek(_options.StartDayOfWeek) .AddWeeks(-pastWeeks) .ApplyTimeZoneOffset(timeZoneInfoId); clearScheduleModel.EndDate = context.CurrentUtcDateTime.Date .StartOfWeek(_options.StartDayOfWeek) .AddWeeks(futureWeeks + 1) .ApplyTimeZoneOffset(timeZoneInfoId); if (!context.IsReplaying) { log.LogClearStart(clearScheduleModel); } var tasks = Enumerable.Range(0, clearScheduleModel.EndDate.Subtract(clearScheduleModel.StartDate).Days) .Select(offset => new ClearScheduleModel { StartDate = clearScheduleModel.StartDate.AddDays(offset), EndDate = clearScheduleModel.StartDate.AddDays(offset).AddHours(23).AddMinutes(59), TeamId = clearScheduleModel.TeamId }) .Select(model => context.CallSubOrchestratorAsync(nameof(ClearShiftsDayOrchestrator), model)); await Task.WhenAll(tasks); // at this stage, we should have deleted all the shifts for each of the days in the period, apart from those // that span midnight on any day, so we need to execute a final ClearShiftsDayOrchestrator for the full date // range plus 24 hours in order to include those remaining shifts clearScheduleModel.QueryEndDate = clearScheduleModel.EndDate.AddHours(24); await context.CallSubOrchestratorAsync(nameof(ClearShiftsDayOrchestrator), clearScheduleModel); if (clearScheduleModel.ClearSchedulingGroups) { await context.CallActivityAsync(nameof(ClearSchedulingGroupsActivity), clearScheduleModel.TeamId); } await context.CallActivityAsync(nameof(ClearCacheActivity), clearScheduleModel); }
public static async Task <object> NewWorker( [OrchestrationTrigger] DurableOrchestrationContext ctx, TraceWriter log ) { int retryattempts = 1; var query = ctx.GetInput <string>(); var retryOptions = new RetryOptions( firstRetryInterval: TimeSpan.FromSeconds(5), maxNumberOfAttempts: retryattempts); var getcookietask = ctx.CallActivityWithRetryAsync <string>("Authenticate", retryOptions, "credentials"); getcookietask.ContinueWith(t => { return("Failed"); }, TaskContinuationOptions.OnlyOnFaulted); await getcookietask; var cookiesjsonb64 = getcookietask.Result; var cookies = CookieConverter.DecodeCookie(cookiesjsonb64); if (!ctx.IsReplaying) { log.Warning($"Successfully retrieved {cookies.Length} cookies."); } var querygurutask = ctx.CallActivityWithRetryAsync <int>("QueryGuru", retryOptions, new Tuple <string, string>(query, cookiesjsonb64)); querygurutask.ContinueWith(t => { return("Failed"); }, TaskContinuationOptions.OnlyOnFaulted); var pages = await querygurutask; if (!ctx.IsReplaying) { log.Warning($"Query successfully returned {pages}."); } var workload = await ctx.CallActivityAsync <List <int> >("CreateWorkload", pages); //log.Warning(ctx.InstanceId); var worker = ctx.CallSubOrchestratorAsync("WorkerWork", new WorkerWorkArgs { query = query, cookiestext = cookiesjsonb64, workload = workload, total = workload.Count }); string result = await ctx.WaitForExternalEvent <string>("Finished"); return(result); }
public static async Task Run([OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) { log.LogInformation($"[START ORCHESTRATOR] --> {FunctionNames.OrderWorkflowFunction}"); var order = context.GetInput <Order>(); log.LogTrace($"Adding Order {order}"); var addResult = await context.CallActivityWithRetryAsync <bool>(FunctionNames.AddOrderFunction, new RetryOptions(TimeSpan.FromSeconds(1), 10), order); if (addResult) { DateTime orderDeadline = GetOrderDeadLine(context); var orderPaidEvent = context.WaitForExternalEvent(Events.OrderPaid); var orderCancelledEvent = context.WaitForExternalEvent(Events.OrderCancelled); var cancelTimer = context.CreateTimer(orderDeadline, CancellationToken.None); var taskCompleted = await Task.WhenAny(orderPaidEvent, orderCancelledEvent, cancelTimer); if (taskCompleted == orderCancelledEvent || taskCompleted == cancelTimer) { log.LogWarning($"Order Cancelled : {order}"); order = await context.CallActivityAsync <Order>(FunctionNames.FinalizeOrderFunction, new OrderStateChange() { NewOrderState = OrderStatus.Cancelled, OrderId = order.Id }); } else if (taskCompleted == orderPaidEvent) { log.LogTrace($"Order Paid : {order}"); order = await context.CallActivityAsync <Order>(FunctionNames.FinalizeOrderFunction, new OrderStateChange() { NewOrderState = OrderStatus.Paid, OrderId = order.Id }); await context.CallActivityAsync <string>(FunctionNames.GenerateInvoiceFunction, order); } if (order != null) { var sendMailResult = await context.CallActivityAsync <bool>(FunctionNames.SendMailFunction, order); log.LogTrace($"Sendmail result : {sendMailResult}"); } } }
public static async Task <StartJobDto> DurableFunctionsOrchestration( [OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) { StartJobDto input = context.GetInput <StartJobDto>(); input.InstanceId = context.InstanceId; await context.CallActivityAsync(nameof(CallChildApi), input); var result = await context.WaitForExternalEvent <StartJobDto>(input.JobId.ToString()); return(result); }
public static async Task <bool> Run([OrchestrationTrigger] DurableOrchestrationContext context) { var phoneNumber = context.GetInput <string>(); if (string.IsNullOrEmpty(phoneNumber)) { throw new ArgumentNullException(nameof(phoneNumber), "A phone number input is required."); } // Send SMS with challengecode var challengeCode = await context.CallActivityAsync <int>("SendSMSChallenge", phoneNumber); using (var timeoutCts = new CancellationTokenSource()) { // Give the user 90 seconds to respond var expiration = context.CurrentUtcDateTime.AddSeconds(90); var timeoutTask = context.CreateTimer(expiration, timeoutCts.Token); var authorized = false; for (var retryCount = 0; retryCount <= 3; retryCount++) { Task <int> challengeResponseTask = context.WaitForExternalEvent <int>("SmsChallengeResponse"); var winner = await Task.WhenAny(challengeResponseTask, timeoutTask); if (winner == challengeResponseTask) { // A response. Compare with the challenge code. if (challengeResponseTask.Result == challengeCode) { authorized = true; break; } } else { // Timeout expired break; } } if (!timeoutTask.IsCompleted) { // All pending timers must be complete or canceled before the function exits. timeoutCts.Cancel(); } return(authorized); } }
public static async Task RunOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context, TraceWriter log) { var document = context.GetInput <Document>(); var alertResults = await RunAlerts(context, document); var triggeredAlerts = alertResults.Where(x => x.Triggered); foreach (var alert in triggeredAlerts) { log.Warning($"Triggered alert {alert.AlertName}: {alert.AlertMessage}"); } }
public static async Task <List <string> > RunOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context) { var outputs = new List <string>(); var blobName = context.GetInput <string>(); var(message, face) = (await context.CallActivityAsync <(string, Face)>("EmojiMatchFunction_AnalyseFace", blobName)); outputs.Add(message); return(outputs); }
public static async Task <IList <Error> > Start([OrchestrationTrigger] DurableOrchestrationContext context) { var person = context.GetInput <Person>(); var tasks = new[] { context.CallActivityAsync <Error>(nameof(CheckFirstName), person), context.CallActivityAsync <Error>(nameof(CheckLastName), person) }; var errors = await Task.WhenAll(tasks); return(errors.Where(e => e != null).ToList()); }
public static async Task OrchestrateConsumersFunc([OrchestrationTrigger] DurableOrchestrationContext ctx) { var changedProducts = ctx.GetInput <IEnumerable <string> >(); var retryOptions = new RetryOptions(firstRetryInterval: TimeSpan.FromSeconds(5), maxNumberOfAttempts: 3); var consumers = Environment.GetEnvironmentVariable("CONSUMERS", EnvironmentVariableTarget.Process) ?.Split('|'); var parallelTasks = consumers.Select(x => CallSendToConsumerActivityAsync(ctx, retryOptions, x, changedProducts)); await Task.WhenAll(parallelTasks); }
public static async Task Run( [OrchestrationTrigger] DurableOrchestrationContext ctx, TraceWriter log) { var input = ctx.GetInput <string>(); var orderDetail = JsonConvert.DeserializeObject <OrderDetail>(input); await ctx.CallActivityAsync("WriteToDatabase", orderDetail); if (await ctx.CallActivityAsync <bool>("UpdateInventoryApi", orderDetail)) { await ctx.CallActivityAsync <OrderDetail>("SendEmail", orderDetail); } }
public async Task <IEnumerable <string> > CrawlingMainAsync([OrchestrationTrigger] DurableOrchestrationContext context, ILogger logger) { var uri = context.GetInput <Uri>(); // We use an activity function to download HTML from the URI specified as input. We use an extension method that incorporates // a default retry logic, because we can't be sure that the resource is aways available. var html = await context.CallActivityWithDefaultRetryAsync <string>(Names.DownloadHtml, uri); // Links are parsed in another activity function. This is done without retry logic, because the activity function does not rely // on external resources. This also shows how you can call activity functions without retry logic. var links = await context.CallActivityAsync <IEnumerable <string> >(Names.ParseLinks, html); return(links); }
public static async Task ProcessOrderOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) { var policy = context.GetInput <WhatIfDemoDbDataContext.Policy>(); // Configuring retries for SavePolicyToDb activity var retryOptions = new RetryOptions(TimeSpan.FromSeconds(5), 3); policy = await context.CallActivityWithRetryAsync <WhatIfDemoDbDataContext.Policy>(nameof(SavePolicyToDb), retryOptions, policy); // Now let's start charging the customer via a sub-orchestration await context.CallSubOrchestratorAsync(nameof(ProcessOrderSubOrchestrator), policy); }
public static async Task RunOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) { log.LogDebug("Processor starting"); Queue <string> queuedJobs = context.GetInput <Queue <string> >(); string jobId = queuedJobs.Dequeue(); await context.CallActivityAsync("JobProcessor_StartJob", jobId); Task <string> jobCompletedEvent = context.WaitForExternalEvent <string>(JobCompletedEventName); Task <string> timeoutTask = context.CreateTimer(context.CurrentUtcDateTime.AddMinutes(5), jobId, CancellationToken.None); //todo: add a timer to timeout our wait for the job to complete. while (true) { Task <string> queuedEvent = context.WaitForExternalEvent <string>(JobQueuedEventName); Task <string> completedTask = await Task.WhenAny(jobCompletedEvent, queuedEvent, timeoutTask); if (completedTask == queuedEvent) { string queuedJobId = completedTask.Result; log.LogDebug($"Job queued {queuedJobId}"); queuedJobs.Enqueue(queuedJobId); } else { //todo: check that job id matches the one we're waiting for to complete. if (completedTask == timeoutTask) { //todo: do some logging or retry logic here. log.LogDebug($"Job timed out {jobId}"); } else { log.LogDebug($"Job completed {jobId}"); } if (queuedJobs.Count > 0) { context.ContinueAsNew(queuedJobs); //This is required to keep the execution history from growing indefinitely. } break; } } }
public static async Task ProcessMessage([OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) { var trigger = context.GetInput <MessageTrigger>(); var approvalResult = ApprovalResult.Unknown; string emailAddress = null; try { log.LogWarning("Getting email address from database."); emailAddress = await context.CallActivityAsync <string>(Activities.GetEmail, trigger.Id); log.LogWarning($"Sending email to: {emailAddress}"); await context.CallActivityAsync(Activities.SendEmail, new SendEmailData { Email = emailAddress, Id = context.InstanceId }); using (var cts = new CancellationTokenSource()) { var timeout = context.CurrentUtcDateTime.AddMinutes(5); var timeoutTask = context.CreateTimer(timeout, cts.Token); var approvalTask = context.WaitForExternalEvent <string>(Events.ApprovalResult); log.LogWarning("Waiting for user action"); var finishedTask = await Task.WhenAny(timeoutTask, approvalTask); if (finishedTask == approvalTask) { approvalResult = approvalTask.Result == "Approved" ? ApprovalResult.Approved : ApprovalResult.Rejected; cts.Cancel(); } else { approvalResult = ApprovalResult.Rejected; } } } catch (Exception ex) { log.LogError($"Exception thrown while processing message: {ex.Message}"); await context.CallActivityAsync(Activities.PostResultOnQueue, new ApprovalResultOutput { Email = emailAddress, Id = trigger.Id.ToString(), Result = ApprovalResult.Unknown }); } log.LogWarning("Posting result message"); await context.CallActivityAsync(Activities.PostResultOnQueue, new ApprovalResultOutput { Email = emailAddress, Id = trigger.Id.ToString(), Result = approvalResult }); }
public static async Task Run( [OrchestrationTrigger] DurableOrchestrationContext context, [Table("ApprovaOrdineCliente")] CloudTable approvaOrdineTables, Microsoft.Extensions.Logging.ILogger logger) { logger.UseSerilog(); Log.Information($"SubOrchestrator Instance: {context.InstanceId}"); OrdiniAcquistoModel ordineAcquisto = context.GetInput <OrdiniAcquistoModel>(); Log.Information($"Pending Order {ordineAcquisto.IdOrdine}"); await SendMail(context, ordineAcquisto); string status = string.Empty; using (var timeoutCts = new CancellationTokenSource()) { DateTime dueTime = context.CurrentUtcDateTime.AddHours(5); Task durableTimeout = context.CreateTimer(dueTime, timeoutCts.Token); Task <bool> approvalTask = context.WaitForExternalEvent <bool>(Workflow.EventoApprova); //Attendo un evento o un timer if (approvalTask == await Task.WhenAny(approvalTask, durableTimeout)) { timeoutCts.Cancel(); if (await approvalTask) { status = "Approvato"; } } else { timeoutCts.Cancel(); status = "TempoScaduto"; } Log.Warning(status); } var approvaOrdine = new ApprovaOrdineTable { PartitionKey = context.InstanceId, RowKey = "PendingApproval", OrdineId = ordineAcquisto.IdOrdine, IdConfirmation = context.InstanceId, Status = status }; TableOperation insertOperation = TableOperation.InsertOrReplace(approvaOrdine); await approvaOrdineTables.ExecuteAsync(insertOperation); }
public static async Task BuildNnf([OrchestrationTrigger] DurableOrchestrationContext ctx) { var input = ctx.GetInput <NnfInputData>(); var levelIndex = input.LevelIndex; var settings = input.Settings; var mappings = input.Mappings; var nnfs = input.SplittedNnfNames; var inpaintArea = input.InpaintAreaName; var imageName = input.Image; var container = input.Container; var tasks = new Task[mappings.Length]; var isForward = true; for (var pmIteration = 0; pmIteration < settings.PatchMatch.IterationsAmount; pmIteration++) { // process in parallel if (mappings.Length > 1) { for (int mapIndex = 0; mapIndex < mappings.Length; mapIndex++) { // TODO: this looks ugly var pminput = NnfInputData.From(nnfs[mapIndex], container, imageName, settings, mappings[mapIndex], inpaintArea, isForward, levelIndex, settings.MeanShift.K, nnfs, mappings); pminput.PatchMatchIteration = pmIteration; tasks[mapIndex] = ctx.CallActivityAsync(NnfBuildActivity.Name, pminput); } await Task.WhenAll(tasks); // TODO: merge nnf into one await ctx.CallActivityAsync(NnfMergeActivity.Name, (nnfs : nnfs, mappings : mappings, resultNnf : input.NnfName, container : input.Container, input.Mapping)); } else { var pminput = NnfInputData.From(input.NnfName, container, imageName, settings, input.Mapping, inpaintArea, isForward, levelIndex, settings.MeanShift.K, nnfs, mappings); pminput.PatchMatchIteration = pmIteration; await ctx.CallActivityAsync(NnfBuildActivity.Name, pminput); } isForward = !isForward; } }
public static async Task <List <string> > Run( [OrchestrationTrigger] DurableOrchestrationContext context) { // Parse data var data = JObject.Parse(context.GetInput <string>()); var status = data["status"].Value <string>(); var output = new List <string>(); // Retrieve lifecycle status id var lifeCycleId = await context.CallActivityAsync <long>("GetLifeCycleStatusId", status); output.Add($"Lifecycle id is {lifeCycleId}."); // Split ids in batches var ids = data["ids"].ToObject <List <long> >(); var batches = ids.SplitIntoBatches(25); foreach (var batch in batches) { if (!batch.Any()) { continue; } // Process all entries in a single batch in parallel var parallelTasks = new List <Task <IList <string> > >(); foreach (var id in batch) { var obj = new JObject() { new JProperty("lifeCycleId", lifeCycleId), new JProperty("id", id) }; var value = JsonConvert.SerializeObject(obj); var task = context.CallActivityAsync <IList <string> >("SetLifeCycleStatus", value); parallelTasks.Add(task); } await Task.WhenAll(parallelTasks); parallelTasks.Select(d => d.Result).ToList().ForEach(d => output.AddRange(d)); } return(output); }
public static async Task <string> RunOrchestrator( [OrchestrationTrigger] DurableOrchestrationContext context, TraceWriter log) { string output = ""; JObject jobProperties = JObject.Parse(context.GetInput <string>()); int duration = (int)jobProperties["duration"]; int frequency = (int)jobProperties["frequency"]; int secondsPerBatch = Convert.ToInt16(Environment.GetEnvironmentVariable("secondsPerBatch")); int numOfBatches = duration * 60 / secondsPerBatch; int numOfMessages = frequency * 60 * duration; var endTime = context.CurrentUtcDateTime.AddMinutes(duration); while (context.CurrentUtcDateTime < endTime) { var nextBatchTime = context.CurrentUtcDateTime.AddSeconds(secondsPerBatch); switch ((string)jobProperties["messageMethod"]) { case "eventhub": await context.CallActivityAsync <string>("Job_SendEventHubMessageBatch", jobProperties.ToObject <EventHubJobProperties>()); break; case "storagequeue": output = await context.CallActivityAsync <string>("Job_SendStorageQueueMessageBatch", jobProperties.ToObject <JobProperties>()); break; case "servicebus": output = await context.CallActivityAsync <string>("Job_SendServiceBusMessageBatch", jobProperties.ToObject <ServiceBusJobProperties>()); break; case "eventgrid": await context.CallActivityAsync <string>("Job_SendEventGridMessageBatch", jobProperties.ToObject <EventGridJobProperties>()); break; default: output = "invalid messageMethod"; break; } await context.CreateTimer(nextBatchTime, CancellationToken.None); } log.Info($"finished sending {numOfMessages} messages"); return($"finished sending {numOfMessages} messages to your {jobProperties["messageMethod"]}"); }
public static async Task ActivityWithRetry_NullRetryOptions([OrchestrationTrigger] DurableOrchestrationContext ctx) { string message = ctx.GetInput <string>(); if (string.IsNullOrEmpty(message)) { // This throw happens directly in the orchestration. throw new ArgumentNullException(nameof(message)); } RetryOptions options = null; // This throw happens in the implementation of an activity. await ctx.CallActivityWithRetryAsync(nameof(TestActivities.ThrowActivity), options, message); }
public static async Task <string> FanOutFanIn( [OrchestrationTrigger] DurableOrchestrationContext context) { int parallelTasks = context.GetInput <int>(); var tasks = new Task[parallelTasks]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = context.CallActivityAsync <string>(nameof(TestActivities.Hello), i.ToString("000")); } await Task.WhenAll(tasks); return("Done"); }