public async Task CleanupSigningWorkflows( [TimerTrigger("0 0 0 * * *")] TimerInfo timerInfo, [DurableClient] IDurableOrchestrationClient orchestrationClient, ILogger log) { var signingRequests = await _db.Requests .Include(r => r.Signers) .Where(r => r.WorkflowCompletedAt != null && EF.Functions.DateDiffDay(r.WorkflowCompletedAt, DateTimeOffset.UtcNow) > 60) .ToListAsync(); foreach (var signingRequest in signingRequests) { foreach (var signer in signingRequest.Signers) { var signerPurgeResult = await orchestrationClient.PurgeInstanceHistoryAsync(signer.WaitForSignatureInstanceId); log.LogInformation( "Purged instance history for signer {SignerId}, {InstancesDeleted} instances deleted", signer.Id, signerPurgeResult.InstancesDeleted); } var requestPurgeResult = await orchestrationClient.PurgeInstanceHistoryAsync(signingRequest.Workflow.Id); log.LogInformation( "Purged instance history for signing request {RequestId}, {InstancesDeleted} instances deleted", signingRequest.Id, requestPurgeResult.InstancesDeleted); } }
private async Task <HttpResponseMessage> HandleDeleteHistoryWithFiltersRequestAsync(HttpRequestMessage request) { IDurableOrchestrationClient client = this.GetClient(request); var queryNameValuePairs = request.GetQueryNameValuePairs(); var createdTimeFrom = GetDateTimeQueryParameterValue(queryNameValuePairs, "createdTimeFrom", DateTime.MinValue); if (createdTimeFrom == DateTime.MinValue) { var badRequestResponse = request.CreateResponse( HttpStatusCode.BadRequest, "Please provide value for 'createdTimeFrom' parameter."); return(badRequestResponse); } var createdTimeTo = GetDateTimeQueryParameterValue(queryNameValuePairs, "createdTimeTo", DateTime.UtcNow); var runtimeStatusCollection = GetIEnumerableQueryParameterValue <OrchestrationStatus>(queryNameValuePairs, "runtimeStatus"); PurgeHistoryResult purgeHistoryResult = await client.PurgeInstanceHistoryAsync(createdTimeFrom, createdTimeTo, runtimeStatusCollection); if (purgeHistoryResult == null || purgeHistoryResult.InstancesDeleted == 0) { return(request.CreateResponse(HttpStatusCode.NotFound)); } return(request.CreateResponse(HttpStatusCode.OK, purgeHistoryResult)); }
public static async Task <HttpResponseMessage> HttpStart( [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestMessage req, [DurableClient] IDurableOrchestrationClient starter, ILogger log) { var request = await req.Content.ReadAsAsync <CrawlRequest>(); if (request?.Host == null) { return(new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, Content = new StringContent("Host must be provided") }); } // Purge history until https://github.com/Azure/azure-functions-durable-extension/issues/892 is available var purgeResult = await starter.PurgeInstanceHistoryAsync(DateTime.MinValue, null, new[] { OrchestrationStatus.Completed, OrchestrationStatus.Canceled, OrchestrationStatus.Failed, OrchestrationStatus.Terminated }); log.LogInformation($"History purge removed {purgeResult.InstancesDeleted} instances"); // Function input comes from the request content. string instanceId = await starter.StartNewAsync("Crawl", request); log.LogInformation($"Started orchestration with ID = '{instanceId}'."); return(starter.CreateCheckStatusResponse(req, instanceId)); }
public static async Task Run([DurableClient] IDurableOrchestrationClient client) { await client.PurgeInstanceHistoryAsync( DateTime.MinValue, null, new [] { OrchestrationStatus.Completed, OrchestrationStatus.Terminated, OrchestrationStatus.Failed }); }
public static void Run([TimerTrigger("0 0 */5 * * *")] TimerInfo myTimer, [DurableClient] IDurableOrchestrationClient client, ILogger log) { client.PurgeInstanceHistoryAsync(DateTime.Now - TimeSpan.FromHours(24), null, new[] { OrchestrationStatus.Canceled, OrchestrationStatus.Completed, OrchestrationStatus.Failed, OrchestrationStatus.Terminated }); log.LogWarning("Purged history"); }
public Task HistoryCleanerFunction( [DurableClient] IDurableOrchestrationClient client, [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer) { return(client.PurgeInstanceHistoryAsync( DateTime.MinValue, DateTime.UtcNow.AddDays(-1), new List <OrchestrationStatus> { OrchestrationStatus.Completed })); }
public async Task Run( [TimerTrigger(PurgeFrequencyVariable)] TimerInfo myTimer, [DurableClient] IDurableOrchestrationClient client, ILogger log, CancellationToken hostCancellationToken) { EnsureArg.IsNotNull(client, nameof(client)); EnsureArg.IsNotNull(myTimer, nameof(myTimer)); EnsureArg.IsNotNull(log, nameof(log)); var orchestrationInstanceIdList = new List <string>(); log.LogInformation("Purging orchestration instance history at: {Timestamp}", _getUtcNow()); if (myTimer.IsPastDue) { log.LogWarning("Current function invocation is later than scheduled."); } // Specify conditions for orchestration instances. var condition = new OrchestrationStatusQueryCondition { RuntimeStatus = _purgeConfig.RuntimeStatuses, CreatedTimeFrom = DateTime.MinValue, CreatedTimeTo = _getUtcNow().AddDays(-_purgeConfig.MinimumAgeDays), ContinuationToken = null }; do { OrchestrationStatusQueryResult listOfOrchestrators = await client.ListInstancesAsync(condition, hostCancellationToken); condition.ContinuationToken = listOfOrchestrators.ContinuationToken; // Loop through the orchestration instances and purge them. foreach (DurableOrchestrationStatus orchestration in listOfOrchestrators.DurableOrchestrationState) { orchestrationInstanceIdList.Add(orchestration.InstanceId); await client.PurgeInstanceHistoryAsync(orchestration.InstanceId); } } while (condition.ContinuationToken != null); if (orchestrationInstanceIdList.Count != 0) { log.LogInformation("{Count} Durable Functions cleaned up successfully.", orchestrationInstanceIdList.Count); log.LogDebug("List of cleaned instance IDs: {list}", string.Join(", ", orchestrationInstanceIdList)); } else { log.LogInformation("No Orchestration instances found within given conditions."); } }
public async Task <object> OrchestratorAsync( [HttpTrigger("get", "post", "delete")] HttpRequest request, [DurableClient] IDurableOrchestrationClient durableOrchestrationClient) { var method = request.Method.ToLower(); if (method == "get") { return(await durableOrchestrationClient.GetInstancesAsync()); } if (method == "delete") { await Task.WhenAll( from i in await durableOrchestrationClient.GetInstancesAsync() where i.RuntimeStatus == OrchestrationRuntimeStatus.Running select durableOrchestrationClient.TerminateAsync(i.InstanceId, "terminate-all") ); return(await Task.WhenAll( from i in await durableOrchestrationClient.GetInstancesAsync() where i.RuntimeStatus != OrchestrationRuntimeStatus.Running select durableOrchestrationClient.PurgeInstanceHistoryAsync(i.InstanceId) )); } var body = await request.Body.ReadAsync(); var functionContext = body.FromJson <FunctionContext>() ?? new FunctionContext(); functionContext.BaseUrl = new Uri(request.GetDisplayUrl()).GetLeftPart(UriPartial.Authority); functionContext.MethodSpecification = functionContext.MethodSpecification ?? request.Query["$method"]; functionContext.Await = functionContext.Await || ((string)request.Query["$await"]).ChangeType <bool>(); functionContext.CallbackUrl = functionContext.CallbackUrl ?? request.Query["$callbackUrl"]; functionContext.Arguments = functionContext.Arguments ?? JToken.FromObject(( from q in request.Query where !q.Key.StartsWith("$") select(q.Key, Value: q.Value.FirstOrDefault() as object) ).ToDictionary()); if (functionContext.Await) { return(await functionContext.InvokeAsync(this.componentContext)); } var instanceId = await durableOrchestrationClient.StartNewAsync("orchestration", functionContext); return(durableOrchestrationClient.CreateHttpManagementPayload(instanceId) as object); }
public async Task CleanupOldWorkflows( [TimerTrigger("0 0 0 * * *")] TimerInfo timerInfo, [DurableClient] IDurableOrchestrationClient orchestrationClient, ILogger log) { var createdTimeFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(365 + 30)); var createdTimeTo = createdTimeFrom.AddDays(30); var runtimeStatus = new List <OrchestrationStatus> { OrchestrationStatus.Completed }; var result = await orchestrationClient.PurgeInstanceHistoryAsync(createdTimeFrom, createdTimeTo, runtimeStatus); log.LogInformation("Scheduled cleanup done, {InstancesDeleted} instances deleted", result.InstancesDeleted); }
private async Task <HttpResponseMessage> HandleDeleteHistoryByIdRequestAsync( HttpRequestMessage request, string instanceId) { IDurableOrchestrationClient client = this.GetClient(request); DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId, showHistory : false); if (status == null) { return(request.CreateResponse(HttpStatusCode.NotFound)); } PurgeHistoryResult purgeHistoryResult = await client.PurgeInstanceHistoryAsync(instanceId); return(request.CreateResponse(HttpStatusCode.OK, purgeHistoryResult)); }
public static async Task Run( [DurableClient] IDurableOrchestrationClient client, [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer, // Run at 12AM each day ILogger log) { log.LogDebug("PurgeInstanceHistory started"); // remove messages older than 30 days var purgeResult = await client.PurgeInstanceHistoryAsync( DateTime.MinValue, DateTime.UtcNow.AddDays(-30), new List <OrchestrationStatus> { OrchestrationStatus.Completed, OrchestrationStatus.Terminated, OrchestrationStatus.Failed }); log.LogInformation($"PurgeInstanceHistory completed, instances deleted: {purgeResult.InstancesDeleted}"); }