예제 #1
0
        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);
        }
예제 #2
0
        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));
        }
예제 #4
0
        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");
        }
예제 #5
0
        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());
        }
예제 #9
0
        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));
        }
예제 #12
0
        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());
        }
예제 #14
0
        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));
        }