示例#1
0
        public void StatusTest()
        {
            DateTime t1 = new DateTime(1950, 12, 1);

            // Stale heart beat is abandoned
            var entity = new InstanceTableEntity
            {
                RowKey    = Guid.NewGuid().ToString(),
                StartTime = t1,
                FunctionInstanceHeartbeatExpiry = t1, // stale heartbeat
            };

            var item = entity.ToFunctionLogItem();

            Assert.Equal(FunctionInstanceStatus.Abandoned, item.GetStatus());

            // recent heartbeat means running .
            entity.FunctionInstanceHeartbeatExpiry = DateTime.UtcNow.AddMinutes(2);
            item = entity.ToFunctionLogItem();
            Assert.Equal(FunctionInstanceStatus.Running, item.GetStatus());

            // endtime means complete
            entity.EndTime = DateTime.UtcNow;
            item           = entity.ToFunctionLogItem();
            Assert.Equal(FunctionInstanceStatus.CompletedSuccess, item.GetStatus());
        }
示例#2
0
        public static async Task InitialMenu(
            [ActivityTrigger] ChatMessage chat, 
            [Table("RunningInstances")] CloudTable table, 
            ILogger log)
        {

            InstanceTableEntity session = new InstanceTableEntity
            {
                PartitionKey = chat.ChatId,
                RowKey = chat.InstanceId,
                ETag = "*"
            };

            if (chat.MessageId.HasValue)
            {
                await DurableChatBot.botClient.DeleteMessageAsync(chat.ChatId, chat.MessageId.Value);
            }
            await table.ExecuteAsync(TableOperation.Delete(session));

            await DurableChatBot.botClient.SendTextMessageAsync(
                chatId: chat.ChatId,
                text: "Your session timed out. You can create a new session for a new menu");
        }
        public static async Task <HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [Table("RunningInstances")] CloudTable tableInput,
            [Table("RunningInstances")] IAsyncCollector <InstanceTableEntity> tableOutput,
            [OrchestrationClient] DurableOrchestrationClient starter,
            ILogger log)
        {
            string requestBody = await req.Content.ReadAsStringAsync();

            try
            {
                Update update = JsonConvert.DeserializeObject <Update>(requestBody);

                string chatId = update.GetChatId();

                TableQuery <InstanceTableEntity> sessionQuery = new TableQuery <InstanceTableEntity>().Where(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, chatId));

                TableQuerySegment <InstanceTableEntity> sessions = await tableInput.ExecuteQuerySegmentedAsync(sessionQuery, null);

                if ((update.Message?.Entities?.Length ?? 0) != 0 &&
                    (update.Message?.Entities?.First().Type ?? MessageEntityType.Unknown) == MessageEntityType.BotCommand &&
                    (update.Message?.EntityValues?.First()?.ToLowerInvariant().Equals("/cancel") ?? false))
                {
                    //Cancel current user session and reset all state!
                    foreach (var entity in sessions)
                    {
                        await tableInput.ExecuteAsync(TableOperation.Delete(entity));
                    }

                    await botClient.SendTextMessageAsync(
                        chatId : chatId,
                        text : $"All running ({sessions.Count()}) sessions have now been purged");
                }
                else
                {
                    bool didContinueASession = false;
                    if (sessions.Count() > 0)
                    {
                        foreach (InstanceTableEntity session in sessions)
                        {
                            OrchestrationRuntimeStatus status = (await starter.GetStatusAsync(session.RowKey)).RuntimeStatus;
                            if (status == OrchestrationRuntimeStatus.Failed ||
                                status == OrchestrationRuntimeStatus.Canceled ||
                                status == OrchestrationRuntimeStatus.Completed ||
                                status == OrchestrationRuntimeStatus.Terminated ||
                                status == OrchestrationRuntimeStatus.Unknown)
                            {
                                log.LogInformation($"Removing session with ID = '{session.RowKey}' because it was terminated");
                                await tableInput.ExecuteAsync(TableOperation.Delete(session));

                                await botClient.SendTextMessageAsync(
                                    chatId : chatId,
                                    text : $"FYI: I purged a old session with ID {session.RowKey} that had status: {status.ToString()} (Was started at UTC: {session.Timestamp.UtcDateTime.ToShortDateString()})");
                            }
                            else
                            {
                                if (update.CallbackQuery != null)
                                {
                                    //One should not have more than 1 running session, but I will not crash because of it. So just continue all the session until they get cleaned up.
                                    await starter.RaiseEventAsync(session.RowKey, "Callback", update);

                                    log.LogInformation($"Continuing on session with ID = '{session.RowKey}'");
                                    didContinueASession = true;
                                }
                            }
                        }
                    }

                    if (!didContinueASession)
                    {
                        var newInstance = new InstanceTableEntity
                        {
                            PartitionKey = chatId,
                            RowKey       = await starter.StartNewAsync("BotBrainFunction", update)
                        };

                        await tableOutput.AddAsync(newInstance);

                        log.LogInformation($"Started orchestration with ID = '{newInstance.RowKey}'.");
                    }
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex, $"Could not parse update data. {ex.Message}");
                log.LogInformation(requestBody);
            }


            // Function input comes from the request content.
            //string instanceId = await starter.StartNewAsync("Function2", null);

            //log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            //return starter.CreateCheckStatusResponse(req, instanceId);


            HttpResponseMessage response = req.CreateResponse(HttpStatusCode.OK);

            //await Task.Delay(1);
            return(response);
        }