public static async Task <List <bool> > RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { var contract = context.GetInput <BulkCreateTasksContract>(); var outputs = new List <bool>(); List <Task <bool> > tasks = new List <Task <bool> >(); foreach (var i in Enumerable.Range(1, contract.NumberOfTasks.Value)) { tasks.Add(context.CallActivityAsync <bool>("BulkCreateAndSimulateTasks_CreateTask", null)); } await Task.WhenAll(tasks.ToArray()); await context.CallActivityAsync <bool>("BulkCreateAndSimulateTasks_ProgressRandomTask", null); while (await context.CallActivityAsync <bool>("BulkCreateAndSimulateTasks_ProgressRandomTask", null)) { await context.CreateTimer(context.CurrentUtcDateTime.AddMilliseconds(1000), CancellationToken.None); } ; return(tasks.Select(o => o.Result).ToList()); }
public static async Task AccrueInterestForAllAccounts ([OrchestrationTrigger] IDurableOrchestrationContext context) { IEnumerable <string> allAccounts = await context.CallActivityAsync <IEnumerable <string> >(nameof(ListAllBankAccounts), null); if (null != allAccounts) { var accrualTasks = new List <Task <Tuple <string, bool> > >(); foreach (string accountNumber in allAccounts) { Task <Tuple <string, bool> > accrualTask = context.CallActivityAsync <Tuple <string, bool> >(nameof(AccrueInterestForSpecificAccount), accountNumber); accrualTasks.Add(accrualTask); } // Perform all the accruals in parrallel await Task.WhenAll(accrualTasks); List <string> failedAccruals = new List <string>(); foreach (var accrualTask in accrualTasks) { if (!accrualTask.Result.Item2) { failedAccruals.Add(accrualTask.Result.Item1); } } // Try a second pass - using failedAccruals.Count ? if (failedAccruals.Count > 0) { throw new Exception("Not all account accruals succeeded"); } } }
public async Task <bool> RefreshJobGroupOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context) { _ = context ?? throw new ArgumentNullException(nameof(context)); var socRequest = context.GetInput <SocRequestModel>(); await context.CallActivityAsync(nameof(PurgeSocActivity), socRequest.SocId).ConfigureAwait(true); var upsertResult = await context.CallActivityAsync <HttpStatusCode>(nameof(TransformItemActivity), socRequest.Url).ConfigureAwait(true); if (upsertResult == HttpStatusCode.OK || upsertResult == HttpStatusCode.Created) { var eventGridPostRequest = new EventGridPostRequestModel { ItemId = socRequest.SocId, Api = $"{eventGridClientOptions.ApiEndpoint}/{socRequest.SocId}", DisplayText = $"LMI transformed into job-group from {socRequest.Url}", EventType = socRequest.IsDraftEnvironment ? EventTypeForDraft : EventTypeForPublished, }; await context.CallActivityAsync(nameof(PostTransformationEventActivity), eventGridPostRequest).ConfigureAwait(true); return(true); } return(false); }
public static async Task ApplyAccruedInterestCommandStep ([OrchestrationTrigger] IDurableOrchestrationContext context) { CommandAttribute payload = context.GetInput <CommandAttribute>(); Command cmdApplyAccruedInterest = null; if (payload == null) { cmdApplyAccruedInterest = new Command(payload); } else { cmdApplyAccruedInterest = new Command(new CommandAttribute("Bank", "Apply Accrued Interest")); } int overdraftEventSequence = await context.CallActivityAsync <int>(nameof(SetOverdraftForInterestCommandStep), cmdApplyAccruedInterest.AsAttribute()); bool success = await context.CallActivityAsync <bool>(nameof(PayInterestCommandStep), cmdApplyAccruedInterest.AsAttribute()); }
public static async Task <string> RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { //Gets the orchestration input var submission = context.GetInput <Submission>(); submission.InstanceId = context.InstanceId; //For each content url, starts a new activity to download their contents var downloadActivityTasks = new List <Task <SubmittedContent> >(); foreach (var submittedContent in submission.Contents) { downloadActivityTasks.Add( context.CallActivityAsync <SubmittedContent>( "SubmissionApprovalProcess_DownloadFileActivity", submittedContent)); } //When all download activities completes, recover their contents await Task.WhenAll(downloadActivityTasks); foreach (var task in downloadActivityTasks) { SubmittedContent downloadSubmittedContent = task.Result; submission.Contents.First(c => c.Url == downloadSubmittedContent.Url).Content = downloadSubmittedContent.Content; } //Notifies the approver by mail to approve or decline the submission await context.CallActivityAsync( "SubmissionApprovalProcess_SubmitForApproval", submission); //Waits for the approval or declining by the approver, or, if no action is taken in two minutes //finish the process setting the submission status as ignored using (var timeoutCts = new CancellationTokenSource()) { DateTime dueTime = context.CurrentUtcDateTime.AddMinutes(5); Task durableTimeout = context.CreateTimer(dueTime, timeoutCts.Token); Task <bool> approval = context.WaitForExternalEvent <bool>("SubmissionApprovalEvent"); if (approval == await Task.WhenAny(approval, durableTimeout)) { timeoutCts.Cancel(); submission.Status = approval.Result ? "APPROVED" : "DECLINED"; } else { submission.Status = "IGNORED"; } } //Set a custom status for this process context.SetCustomStatus(new { ApprovalStatus = submission.Status }); //Notify the requester of the process completion await context.CallActivityAsync( "SubmissionApprovalProcess_NotifyCompletionActivity", submission); //Return the status of the submission and completes the process return(submission.Status); }
public static async Task RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { var fileName = context.GetInput <string>(); await context.CallActivityAsync("Monitor_StartLongTask", fileName); var timeoutAt = context.CurrentUtcDateTime.AddMinutes(30); while (true) { if (context.CurrentUtcDateTime > timeoutAt) { context.SetCustomStatus("Timeout has been exceeded."); break; // You must cancel long task if it's possible } if (await context.CallActivityAsync <bool>("Monitor_IsFinishedLongTask", fileName)) { context.SetCustomStatus("Long running task has finished."); context.SetOutput($"http://somewhere.io/{fileName}"); break; } var fireAt = context.CurrentUtcDateTime.AddSeconds(15); await context.CreateTimer(fireAt, CancellationToken.None); } }
public static async Task RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, CancellationToken token) { var timeSince = DateTime.UtcNow.AddDays(-1); bool needToContinue; var page = 0; do { needToContinue = false; //TODO check assignment var query = new GetUpdatesEmailUsersQuery(timeSince, page++); var result = await context.CallActivityAsync <IEnumerable <UpdateUserEmailDto> >("EmailUpdateFunction_UserQuery", query); foreach (var emailDto in result) { if (token.IsCancellationRequested) { break; } needToContinue = true; emailDto.Since = timeSince; await context.CallActivityAsync <string>("EmailUpdateFunction_Process", emailDto); } } while (needToContinue); }
public static async Task <string> RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { var tasks = new List <Task <string> >(); tasks.Add(context.CallActivityAsync <string>("FanOutSayHelloActivity", "Tokyo")); tasks.Add(context.CallActivityAsync <string>("FanOutSayHelloActivity", "Seattle")); tasks.Add(context.CallActivityAsync <string>("FanOutSayHelloActivity", "London")); await Task.WhenAll(tasks); var builder = new StringBuilder(); foreach (var task in tasks) { builder.AppendFormat("{0}, ", task.Result); } // returns "Hello Tokyo!, Hello Seattle!, Hello London!" var output = builder.ToString(); log.LogInformation($"Output {output.Substring(0, output.Length - 1)}"); return(output.Substring(0, output.Length - 1)); }
public async Task RunOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context) { if (!context.IsReplaying) { _logger.LogInformation("[LearnerMatchingOrchestrator] Learner matching process started"); } var collectionPeriod = await context.CallActivityAsync <CollectionPeriod>(nameof(GetActiveCollectionPeriod), null); if (collectionPeriod.IsInProgress) { _logger.LogInformation("Learner match not performed as payment run is in process."); return; } var apprenticeshipIncentives = await context.CallActivityAsync <List <ApprenticeshipIncentiveOutput> >(nameof(GetAllApprenticeshipIncentives), null); _logger.LogInformation("[LearnerMatchingOrchestrator] {count} apprenticeship incentives found", apprenticeshipIncentives.Count); var tasks = apprenticeshipIncentives.Select(incentive => context.CallSubOrchestratorAsync(nameof(LearnerMatchingApprenticeshipOrchestrator), incentive)).ToList(); await Task.WhenAll(tasks); if (!context.IsReplaying) { _logger.LogInformation("[LearnerMatchingOrchestrator] Learner matching process completed"); } }
public async Task Run( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger) { var threatAlert = context.GetInput <NewAlertEvent>(); var saveResult = await context.CallActivityAsync <SaveThreatAlertResult>( nameof(SaveNewAlertEventActivity), threatAlert); var notificationRulesForCompany = await context.CallActivityAsync <IEnumerable <NotificationRule> >( nameof(GetNotificationRulesActivity), threatAlert.CompanyId); if (threatAlert.AlertType == AlertType.Single) { var extractRuleDataTasks = new List <Task>(); // TODO GetFullThreatData var threatData = new Alert(); foreach (var notificationRule in notificationRulesForCompany) { var input = new Tuple <NotificationRule, Alert>(notificationRule, threatData); extractRuleDataTasks.Add(context.CallActivityAsync <Tuple <NotificationRule, string> >( nameof(ExtractDataForNotificationRuleActivity), input)); } await Task.WhenAll(extractRuleDataTasks); } }
public static async Task <IEnumerable <string> > Orchestrator_DurableFuncForIsReplaying( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { if (!context.IsReplaying) { log.LogInformation("Retrieve data from the DB."); } string[] cities = await context.CallActivityAsync <string[]>(nameof(Activity_GetCities), null); var outputs = new List <string>(); // NOTE: IsReplaying became false IF the CallActivityAsync is called AND the activity kicks off. if (!context.IsReplaying) { log.LogInformation("Start to say hello to the cities."); } foreach (string city in cities) { outputs.Add(await context.CallActivityAsync <string>(nameof(Activity_DurableFuncForIsReplaying), city)); } return(outputs); }
public static async Task <string> BlockIPWafOrchestration( [OrchestrationTrigger] IDurableOrchestrationContext context) { Payload data = context.GetInput <Payload>(); RequestParam reqparam = new RequestParam { action = "add", blockips = new List <string> { $"{data.blockip}" } }; //var output1 = await context.CallActivityAsync<string>("UpdateWafPolicy", reqparam); //var output2 = await context.CallActivityAsync<string>("InsertToDB", reqparam); //run parallel var tasks = new Task <string> [2]; tasks[0] = context.CallActivityAsync <string>("UpdateWafPolicy", reqparam); tasks[1] = context.CallActivityAsync <string>("InsertToDB", reqparam); await Task.WhenAll(tasks); return(tasks[0].Result); }
public static async Task <string> Run( [OrchestrationTrigger] IDurableOrchestrationContext context) { try { var potentialLumpia = await context.CallActivityAsync <string>("ScoopFillingOntoWrapper", null); var rolledLumpia = await context.CallActivityAsync <string>("FoldAndRoll", potentialLumpia); var sealedLumpia = await context.CallActivityAsync <string>("AddEggWhiteSeal", rolledLumpia); return(await context.CallActivityAsync <string>("FryThatSucker", sealedLumpia)); } catch (FormatException imperfectRoll) { var disapprovalFromMom = new FormatException($"What is this?! Don't you know how to roll these by now? {imperfectRoll.InnerException}"); throw disapprovalFromMom; } catch (ArgumentOutOfRangeException tooMuchFilling) { var structuralIntegrityWarning = new ArgumentOutOfRangeException($"Warning: This much filling will prevent proper rolling and closure of lumpia. {tooMuchFilling.InnerException}"); throw structuralIntegrityWarning; } }
protected override async Task <PullRequestStateContext> ExecuteAsync(IDurableOrchestrationContext context, PullRequestStateContext pullRequestDetailContext, PRCommentCreated comment, JObject parentReviewComment, EntityId entityId) { if (!pullRequestDetailContext.HasCreatedWorkItem(comment.comment.id)) { WorkItem createdWorkItem = await context.CallActivityAsync <WorkItem>(nameof(CreateWorkItemCommand) + "_CreateWorkItem", (parentReviewComment, pullRequestDetailContext)); pullRequestDetailContext.Add( new CreatedWorkItem() { CommentId = comment.comment.id }); var createReplyparameter = new CreateReplyParamter() { PullRequestNumber = comment.pull_request.number, InReplyTo = (int)parentReviewComment["Id"], WorkItem = createdWorkItem }; await context.CallActivityAsync(nameof(CreateWorkItemCommand) + "_CreateReplyComment", createReplyparameter); } return(pullRequestDetailContext); }
public static async Task AdxExportOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { log = context.CreateReplaySafeLogger(log); var input = context.GetInput <Tuple <string, string> >(); string path = await context.CallActivityAsync <string>(nameof(AdxExportStatusCheck), input.Item1); if (path == null) { // If export not yet completed, we create timer (=sleep) til we retry var nextCheck = context.CurrentUtcDateTime.AddSeconds(10); log.LogInformation($"Export not completed yet. Next check at {nextCheck.ToString("o")}"); await context.CreateTimer(nextCheck, CancellationToken.None); context.StartNewOrchestration(nameof(AdxExportOrchestrator), input); } else if (path == "Error") { log.LogError("Could not retrieve export result. Giving up"); } else { log.LogInformation("Retrieve path from export. Sending email to user now"); await context.CallActivityAsync(nameof(SendCompletionEmail), new Tuple <string, string>(path, input.Item2)); } }
public async Task RunWithFanOutFanIn( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { var names = context.GetInput <IEnumerable <string> >(); var taskList = new List <Task <Function1Result> >(); foreach (var name in names) { var task = context.CallActivityAsync <Function1Result>( nameof(ActivityFunction1), name); taskList.Add(task); } // Wait for all tasks to complete var function1Result = await Task.WhenAll(taskList); // Wait for one task that is completed //var function1Result = await Task.WhenAny(taskList); await context.CallActivityAsync <Function2Result>( nameof(ActivityFunction2), function1Result); }
public async Task <SignerResult> WaitForSign( [OrchestrationTrigger] IDurableOrchestrationContext context) { WaitForSignParameters input = context.GetInput <WaitForSignParameters>(); // Update this sub-orchestrator data to DB so event can be sent to this instance // Note this could also be done differently; // We could define the instance id in the parent orchestrator and store it in DB there await context.CallActivityAsync(nameof(SetEventOrchestratorInfo), new SetEventOrchestratorInfoParameters { InstanceId = context.InstanceId, RequestId = input.RequestId, SignerEmail = input.SignerEmail }); try { // Wait for user to sign for 5 days // Note this does not actually make the function wait here for 5 days // The function is completely suspended until something happens // You can't put more than 6 days of wait time here though // Leaving out the timeout makes the wait _indefinite_ SigningEvent ev = await context.WaitForExternalEvent <SigningEvent>(SignEvent, TimeSpan.FromDays(5)); if (ev.Email != input.SignerEmail) { throw new Exception("Wrong signer"); } // Update decision info to DB await context.CallActivityAsync(nameof(SetSigningDataForSigner), new SetSigningDataForSignerParameters { RequestId = input.RequestId, SignerEmail = input.SignerEmail, Signed = ev.Signed, DecidedAt = ev.DecidedAt }); return(new SignerResult { Result = ev.Signed ? SigningDecision.Signed : SigningDecision.Rejected, SignerEmail = input.SignerEmail, DecidedAt = ev.DecidedAt }); } catch (TimeoutException) { // User did not respond within 5 days return(new SignerResult { Result = SigningDecision.Expired, DecidedAt = context.CurrentUtcDateTime, SignerEmail = input.SignerEmail }); // Note above we get the current time from the context // This is important since orchestrators must be _deterministic_ // DateTimeOffset.UtcNow is not deterministic since the value is different on each run // CurrentUtcDateTime is derived from the history table used by Durable Functions } }
public async Task <List <string> > Orchestration_W3C( [OrchestrationTrigger] IDurableOrchestrationContext context) { if (!(CorrelationTraceContext.Current is W3CTraceContext correlationContext)) { throw new InvalidOperationException($"This sample expects a correlation trace context of {nameof(W3CTraceContext)}, but the context isof type {CorrelationTraceContext.Current.GetType()}"); } var trace = new TraceTelemetry( $"Activity Id: {correlationContext.TraceParent} ParentSpanId: {correlationContext.ParentSpanId}"); trace.Context.Operation.Id = correlationContext.TelemetryContextOperationId; trace.Context.Operation.ParentId = correlationContext.TelemetryContextOperationParentId; this.telemetryClient.Track(trace); var outputs = new List <string> { await context.CallActivityAsync <string>(nameof(this.Hello_W3C), "Tokyo"), await context.CallActivityAsync <string>(nameof(this.Hello_W3C), "Seattle"), await context.CallActivityAsync <string>(nameof(this.Hello_W3C), "London"), }; // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"] return(outputs); }
public static async Task <long> FanInOut_Orchestrator( [OrchestrationTrigger] IDurableOrchestrationContext backupContext) { string rootDirectory = backupContext.GetInput <string>()?.Trim(); if (string.IsNullOrEmpty(rootDirectory)) { rootDirectory = Directory.GetParent(typeof(FanInOut).Assembly.Location).FullName; } rootDirectory = rootDirectory.Remove(rootDirectory.Length - 4); rootDirectory = Path.Combine(rootDirectory, "Logs"); string[] files = await backupContext.CallActivityAsync <string[]>("FanInOut_GetFileList", rootDirectory); var tasks = new Task <long> [files.Length]; for (int i = 0; i < files.Length; i++) { tasks[i] = backupContext.CallActivityAsync <long>("FanInOut_CopyFileToBlob", files[i]); } await Task.WhenAll(tasks); long totalBytes = tasks.Sum(t => t.Result); return(totalBytes); }
public async Task <List <string> > AMS_EncodeOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { var input = context.GetInput <string>(); var outputs = new List <string>(); try { var encode = await context.CallActivityAsync <Task>("AMS_Encode", input); Job job = await context.CallActivityAsync <Job>("AMS_Job", input); var streamingUrl = await context.CallActivityAsync <string>("AMS_StreamingURL", input); outputs.Add($"Streaming URL : {streamingUrl}"); var manifest = await context.CallActivityAsync <Amsv3Manifest>("AMS_Finalize", input); return(outputs); } catch (Exception ex) { log.LogError(ex.Message); log.LogInformation(ex.StackTrace); outputs.Add($"Error : {ex.Message}"); return(outputs); } }
public async Task RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { try { var command = context.GetInput <RecompensateApplicationProcessCommand>(); log.LogInformation( $"Starting recompensation process(instanceId: {context.InstanceId} for ${command.Id}"); var deleteCvCommand = new DeleteFileCommand( _fileNameProvider.GetFileName(command.Id, command.Cv.Extension), FileStore.CvsContainer); var deletePhotoCommand = new DeleteFileCommand( _fileNameProvider.GetFileName(command.Id, command.Photo.Extension), FileStore.PhotosContainer); await context.CallActivityAsync(nameof(FileDeleter), deleteCvCommand); await context.CallActivityAsync(nameof(FileDeleter), deletePhotoCommand); log.LogInformation( $"Finished recompensation process(instanceId: {context.InstanceId} for ${command.Id}"); } catch (Exception) { // Allow somebody from support to handle it manually throw; } }
public static async Task <VideoFileInfo[]> TranscodeVideo( [OrchestrationTrigger] IDurableOrchestrationContext ctx, ILogger log) { var videoLocation = ctx.GetInput <string>(); var bitRates = await ctx.CallActivityAsync <int[]>("A_GetTranscodeBitrates", null); var transcodeTasks = new List <Task <VideoFileInfo> >(); foreach (var bitRate in bitRates) { var info = new VideoFileInfo() { Location = videoLocation, BitRate = bitRate }; var task = ctx.CallActivityAsync <VideoFileInfo>("A_TranscodeVideo", info); // Creates a list of tasks transcodeTasks.Add(task); } // Pararel execution of all tasks. Returns an array. Wait for all tasks to be executed var transcodeResults = await Task.WhenAll(transcodeTasks); return(transcodeResults); }
public async Task TriggeredCommunicationOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { var message = context.GetInput <Message>(); string deserializedBody = Helpers.DeserializeServiceBusMessage(message); if (message.UserProperties.TryGetValue("topicSource", out var topicSource)) { // TODO: store config json as durable entity so we don't have to read the blob every time var sendRequests = (await context.CallActivityAsync <List <CustomerCommunicationUseCase> >("Activities-GetActivities", "Config.json")) .Where(a => a.IsEnabled) .Where(a => a.Type.ToLower() == "triggered") .Where(a => a.TriggerTopic == (string)topicSource) .Where(a => ApplyFilter(a, deserializedBody)) .Select(a => GetSendRequest(a, deserializedBody)).ToList(); if (sendRequests.Any()) { var contactInfo = await context.CallActivityAsync <List <CommunicationSendRequest> >( "Activities-GetUserContactInfo", sendRequests); await context.CallActivityAsync <List <CommunicationSendRequest> >("Activities-SendEmail", contactInfo); } } }
public static async Task <ShippingPrice> RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { var input = context.GetInput <SagaContext>(); // activity to check if we ship to the specified continent if (!await context.CallActivityAsync <bool>("IsContinentSupported", input.Continent)) { return(new ShippingPrice() { Shippable = false, Message = "We aren't able to ship to your location" }); } // activity to get proper orchestrator for continent for shipping partner var supplierOrchestratorToRun = await context.CallActivityAsync <string>("GetSupplierOrchestratorForContinent", input.Continent); // orchestrator to get the price for the shipping address var priceForShipment = await context.CallSubOrchestratorAsync <decimal>($"{supplierOrchestratorToRun}Orchestrator", input); // activity to publish event for Sales / marketing await context.CallActivityAsync("PublishCalculatedPriceActivity", (input, priceForShipment)); return(new ShippingPrice() { Shippable = true, Price = priceForShipment }); }
public async Task <RepoModel> Run( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger) { if (!context.IsReplaying) { logger.LogInformation("Starting Orchestrator..."); } var inputData = context.GetInput <InputDataModel>(); // No input data provided? Fall back to AppSettings, // for the local environment it's stored in local.settings.json string gitHubOrgName = inputData?.GitHubOrgName ?? _appConfig.GitHubOrgName; var repoModel = await context.CallActivityAsync <RepoModel>(nameof(GetGitHubData), gitHubOrgName); if (repoModel != null) { await context.CallActivityAsync(nameof(SaveToDatabase), repoModel); return(repoModel); } return(null); }
public static async Task <List <string> > RunOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context) { var parallelTasks = new List <Task <double> >(); var outputs = new List <string>(); string[] products = await context.CallActivityAsync <string[]>("GetAvailableItems", "Mi Band 4, Optical Mouse - red"); outputs.Add($"No of products in the request - {products.Count()}"); for (int i = 0; i < products.Length; i++) { Task <double> task = context.CallActivityAsync <double>("GetInvoiceLineAmount", products[i]); parallelTasks.Add(task); outputs.Add($"Product - {products[i]}"); } await Task.WhenAll(parallelTasks); double sum = parallelTasks.Sum(t => t.Result); await context.CallActivityAsync("PrintInvoice", sum); outputs.Add($"Invoice total - {sum}"); return(outputs); }
public async Task RunAsync( [OrchestrationTrigger] IDurableOrchestrationContext orchestrationContext, ILogger log) { ILogger replaySafeLogger = orchestrationContext.CreateReplaySafeLogger(log); TenantedFunctionData <BatchReadStatusUpdateRequestItem[]> request = orchestrationContext.GetInput <TenantedFunctionData <BatchReadStatusUpdateRequestItem[]> >(); try { await orchestrationContext.CallActivityAsync( nameof(StartLongRunningOperationActivity), (request.LongRunningOperationId !.Value, request.TenantId)); // Fan out to update each notification IEnumerable <Task> updateStatusTasks = request.Payload .Select(x => orchestrationContext.CallActivityAsync( nameof(UpdateNotificationReadStatusActivity), new TenantedFunctionData <BatchReadStatusUpdateRequestItem>(request.TenantId, x))); await Task.WhenAll(updateStatusTasks); await orchestrationContext.CallActivityAsync( nameof(CompleteLongRunningOperationActivity), (request.LongRunningOperationId !.Value, request.TenantId)); } catch (FunctionFailedException) { await orchestrationContext.CallActivityAsync( nameof(FailLongRunningOperationActivity), (request.LongRunningOperationId !.Value, request.TenantId)); } }
public async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger) { var message = context.GetInput <MyMessage>(); var firstMessage = await context.CallActivityWithRetryAsync <MyMessage>( nameof(FirstMessageActivity), new RetryOptions(TimeSpan.FromSeconds(10), 5), message); var secondMessage = await context.CallActivityWithRetryAsync <MyMessage>( nameof(SecondMessageActivity), new RetryOptions(TimeSpan.FromSeconds(10), 5), message); var messages = new List <MyMessage> { firstMessage, secondMessage }; foreach (var msg in messages) { logger.LogInformation($"{msg}"); } await context.CallActivityAsync(nameof(StoreProcessedEventActivity), firstMessage); await context.CallActivityAsync(nameof(StoreProcessedEventActivity), secondMessage); await context.CallActivityAsync(nameof(SendNotificationActivity), firstMessage); await context.CallActivityAsync(nameof(SendNotificationActivity), secondMessage); }
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { // Obtain the orchestration input range. var input = context.GetInput <Range>(); // Create a collection of asynchronous tasks that will call an activity function to determine // the number of primes in a part of the full range. var parallelTasks = new List <Task <List <int> > >(); const int ChunkSize = 10000; var count = input.From; while (count <= input.To) { var task = context.CallActivityAsync <List <int> >("FindPrimesActivity", new Range { From = count, To = count + ChunkSize, }); parallelTasks.Add(task); count += ChunkSize; } // Execute the tasks (fan-out) and collate the responses (fan-in). // Given each task returns a list of integers (the primes found) the collated results will be an array of lists. var taskResults = await Task.WhenAll(parallelTasks); // Collapse the results into an output structure and write to blob storage. await context.CallActivityAsync("WriteResultsActivity", new Result { Primes = taskResults.SelectMany(x => x).ToList() }); }
public async Task RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { var outputs = new List <BulkImportJobStatus>(); var input = context.GetInput <BulkImportStatus>(); int pollingInterval = 5; while (input.BulkImportJobs.Any(s => s.Status != "Complete")) { outputs.Clear(); foreach (var bulkImportJob in input.BulkImportJobs.ToList()) { outputs.Add(await context.CallActivityAsync <BulkImportJobStatus>("MonitorBulkImport_Job", bulkImportJob)); } input.BulkImportJobStatus = outputs; await context.CallActivityAsync <BulkImportJob>("MonitorBulkImport_Report", input); if (input.BulkImportJobStatus.All(s => s.Status == "Complete")) { break; } // Orchestration sleeps until this time. var nextCheck = context.CurrentUtcDateTime.AddSeconds(pollingInterval); await context.CreateTimer(nextCheck, CancellationToken.None); } }