internal static async Task StartSearchSync(IDurableOrchestrationClient starter, ILogger log, SyncType syncType) { var model = new SearchSyncInput(syncType); var existingInstance = await starter.GetStatusAsync(model.InstanceId); if (existingInstance == null) { log.LogInformation($"start new instance of {syncType}"); await starter.StartNewAsync(SearchSyncName, model.InstanceId, model); return; } if (existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Failed) { log.LogInformation($"terminate existing instance"); await starter.TerminateAsync(model.InstanceId, "the status failed"); } if (existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Running) { if (existingInstance.LastUpdatedTime < DateTime.UtcNow.AddHours(-1)) { log.LogError($"issue with {syncType}"); await starter.TerminateAsync(model.InstanceId, $"issue with {syncType}"); } else { log.LogInformation($"{model.InstanceId} is in status {existingInstance.RuntimeStatus}"); return; } } await starter.StartNewAsync(SearchSyncName, model.InstanceId, model); }
public async Task <IActionResult> TerminateInstance( [DurableClient] IDurableOrchestrationClient client, [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req) { string reason = req.Query["reason"]; var taskItem = await base.GetTaskItem(req); var taskId = _service.TaskId(taskItem); if (string.IsNullOrWhiteSpace(taskId)) { return(new OkObjectResult("orchestratorId missing")); } DurableOrchestrationStatus status = await client.GetStatusAsync(taskId); if (status.RuntimeStatus == OrchestrationRuntimeStatus.Completed) { return(new OkObjectResult("Already completed")); } if (status.RuntimeStatus == OrchestrationRuntimeStatus.Terminated) { return(new OkObjectResult("Already terminated")); } await client.TerminateAsync(taskId, reason); return(new OkObjectResult("Teminated")); }
private async Task <HttpResponseMessage> HandleTerminateInstanceRequestAsync( HttpRequestMessage request, string instanceId) { IDurableOrchestrationClient client = this.GetClient(request); DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId); if (status == null) { return(request.CreateResponse(HttpStatusCode.NotFound)); } switch (status.RuntimeStatus) { case OrchestrationRuntimeStatus.Failed: case OrchestrationRuntimeStatus.Canceled: case OrchestrationRuntimeStatus.Terminated: case OrchestrationRuntimeStatus.Completed: return(request.CreateResponse(HttpStatusCode.Gone)); } string reason = request.GetQueryNameValuePairs()["reason"]; await client.TerminateAsync(instanceId, reason); return(request.CreateResponse(HttpStatusCode.Accepted)); }
public static async Task TimerStart( [TimerTrigger("0 0 8 * * *")] TimerInfo myTimer, [DurableClient] IDurableOrchestrationClient starter, ILogger log) { const string instanceName = "UpdateEmail"; var existingInstance = await starter.GetStatusAsync(instanceName); if (existingInstance == null) { await starter.StartNewAsync("EmailUpdateFunction", "UpdateEmail"); return; } var types = new[] { OrchestrationRuntimeStatus.Running, OrchestrationRuntimeStatus.Pending }; if (types.Contains(existingInstance.RuntimeStatus)) { if (existingInstance.LastUpdatedTime < DateTime.UtcNow.AddHours(-6)) { await starter.TerminateAsync(instanceName, "Taking too long "); } else { log.LogInformation($"{instanceName} is in status {existingInstance.RuntimeStatus}"); return; } } await starter.StartNewAsync("EmailUpdateFunction", "UpdateEmail"); }
public virtual async Task <string> runAction(IDurableOrchestrationClient starter, ILogger log) { var entLookup = Environment.GetEnvironmentVariable("LCU-ENTERPRISE-LOOKUP"); try { var listInstanceQuery = new OrchestrationStatusQueryCondition() { PageSize = 1000, RuntimeStatus = new[] { OrchestrationRuntimeStatus.Running, OrchestrationRuntimeStatus.Pending } }; var instances = await starter.ListInstancesAsync(listInstanceQuery, new System.Threading.CancellationToken()); var running = new HashSet <string>(instances.DurableOrchestrationState.Select(instance => instance.InstanceId)); var terminateTasks = running.Select(instanceId => { return(starter.TerminateAsync(instanceId, "Cleanup")); }); await Task.WhenAll(terminateTasks); while (running.Count > 0) { var results = await Task.WhenAll(instances.DurableOrchestrationState.Select(instance => starter.GetStatusAsync(instance.InstanceId))); foreach (var status in results) { // Remove any terminated or completed instances from the hashset if (status != null && status.RuntimeStatus != OrchestrationRuntimeStatus.Pending && status.RuntimeStatus != OrchestrationRuntimeStatus.Running) { running.Remove(status.InstanceId); } } await Task.Delay(TimeSpan.FromMilliseconds(1000)); } var instanceId = await starter.StartAction("RenewCertificatesOrchestration", new StateDetails() { EnterpriseLookup = entLookup }, new ExecuteActionRequest() { Arguments = new { EnterpriseLookup = entLookup }.JSONConvert <MetadataModel>() }, log); return(instanceId); } catch (Exception ex) { return(null); } }
public static async Task Run([DurableClient] IDurableOrchestrationClient client) { var all = await client.ListInstancesAsync(new OrchestrationStatusQueryCondition { RuntimeStatus = new[] { OrchestrationRuntimeStatus.Pending, OrchestrationRuntimeStatus.Running, OrchestrationRuntimeStatus.ContinuedAsNew } }, CancellationToken.None); await Task.WhenAll(all.DurableOrchestrationState.Select(async o => await client.TerminateAsync(o.InstanceId, "Clean up test data."))); }
private static async Task StopRunningOrchestratorAsync(string instanceIdPattern, string teamId, IDurableOrchestrationClient starter) { var instanceId = string.Format(instanceIdPattern, teamId); var status = await starter.GetStatusAsync(instanceId).ConfigureAwait(false); if (status?.RuntimeStatus == OrchestrationRuntimeStatus.Running || status?.RuntimeStatus == OrchestrationRuntimeStatus.Pending) { await starter.TerminateAsync(instanceId, nameof(StopTrigger)).ConfigureAwait(false); } }
public static async Task <IActionResult> StopPeriodicTask( [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, [DurableClient] IDurableOrchestrationClient client, ILogger log) { var instanceId = "PeriodicTask"; // use a fixed id, making it easier for us to terminate await client.TerminateAsync(instanceId, "User requested termination"); return(new OkResult()); }
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 <IActionResult> TaskSchedulerRunner( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, [DurableClient] IDurableOrchestrationClient client, ILogger log) { if (client is null) { throw new ArgumentNullException(nameof(client)); } var taskItem = await GetTaskItem(req); if (taskItem == null) { return(new OkObjectResult($"TaskItem argument not valid")); } var orchestratorInstanceId = _service.TaskId(taskItem); if (string.IsNullOrWhiteSpace(orchestratorInstanceId.ToString())) { return(new OkObjectResult("orchestratorId missing")); } DurableOrchestrationStatus status = await client.GetStatusAsync(orchestratorInstanceId); if (status != null && status.RuntimeStatus == OrchestrationRuntimeStatus.Running) { return(new OkObjectResult(status)); } if (status != null && status.RuntimeStatus == OrchestrationRuntimeStatus.Pending) { await client.TerminateAsync(orchestratorInstanceId, "New scheduler time"); } string instanceId = await client.StartNewAsync <TaskItem>(nameof(StartOrchestratorScheduler), orchestratorInstanceId, taskItem); var result = client.CreateCheckStatusResponse(req, instanceId); return(result); }
public async Task <IActionResult> ProcessFlow( BeginRequestData beginRequestData, HttpRequestMessage request, IDurableOrchestrationClient client) { await client.StartNewAsync(Constants.MyOrchestration, beginRequestData.Id, beginRequestData); _log.LogInformation($"Started orchestration with ID = '{beginRequestData.Id}'."); TimeSpan timeout = TimeSpan.FromSeconds(7); TimeSpan retryInterval = TimeSpan.FromSeconds(1); await client.WaitForCompletionOrCreateCheckStatusResponseAsync( request, beginRequestData.Id, timeout, retryInterval); var data = await client.GetStatusAsync(beginRequestData.Id); // timeout if (data.RuntimeStatus != OrchestrationRuntimeStatus.Completed) { await client.TerminateAsync(beginRequestData.Id, "Timeout something took too long"); return(new ContentResult() { Content = "{ error: \"Timeout something took too long\" }", ContentType = "application/json", StatusCode = (int)HttpStatusCode.InternalServerError }); } var output = data.Output.ToObject <MyOrchestrationDto>(); var completeResponseData = new CompleteResponseData { BeginRequestData = output.BeginRequest, Id2 = output.BeginRequest.Id + ".v2", MyActivityTwoResult = output.MyActivityTwoResult }; return(new OkObjectResult(completeResponseData)); }
private async Task HandleMonitoringAsync(IDurableOrchestrationClient durableClient, string currentUserId) { try { var entity = await this.monitoringRepository.FindAsync(currentUserId); if (entity != null && entity.MonitoringInstanceId != null) { await durableClient.TerminateAsync(entity.MonitoringInstanceId, "Drank early enough."); } // Start timer to remind user about entering his next drink. var monitoringInstanceId = await durableClient.StartNewAsync(nameof(DrinkReminderFunction), currentUserId); await this.monitoringRepository.SaveAsync(currentUserId, monitoringInstanceId); } catch (Exception ex) { logger.LogError(ex, "Error managing monitoring function"); } }
public static async Task <IActionResult> TriggerResetRun( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "reset/{instanceId}")] HttpRequestMessage req, [DurableClient] IDurableEntityClient entityClient, [DurableClient] IDurableOrchestrationClient durableClient, string instanceId, ILogger log) { try { log.LogInformation($"Stop orchestrator with instanceId: {instanceId}"); await durableClient.TerminateAsync(instanceId, "Due to reset"); log.LogInformation("Start entity reset."); var entityId = new EntityId("ContainerInstanceStatusEntity", "ContainerInstanceStatusEntity"); await entityClient.SignalEntityAsync(entityId, "Reset"); } catch (Exception) { return(new BadRequestResult()); } return(new AcceptedResult()); }
public static async Task <HttpResponseMessage> ResetDeviceStatus( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "v1/devices/{deviceId}/status/reset")] HttpRequestMessage req, string deviceId, [DurableClient] IDurableOrchestrationClient starter, ILogger log) { var instanceId = deviceId; var existingInstance = await starter.GetStatusAsync(instanceId); if (existingInstance != null) { await starter.TerminateAsync(instanceId, "reset command called."); //await starter.PurgeInstanceHistoryAsync(instanceId); // これを呼ぶとInstanceの情報すべてが削除される。この場合StartNewAsyncとWaitForCompletionOrCreateCheckStatusResponseAsyncの必要はない await starter.StartNewAsync( "UpdateDeviceStatus", instanceId, new InputData { State = existingInstance?.CustomStatus?.ToObject <DeviceState>(), Input = new[] { new { Type = "terminate" } } }); var output = await starter.WaitForCompletionOrCreateCheckStatusResponseAsync( req, instanceId, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(1)); } return(req.CreateResponse(HttpStatusCode.OK)); }