Случайные тайм-ауты / TaskCanceledException в пределах BotFramework - PullRequest
0 голосов
/ 22 ноября 2018

Описание проблемы

Мы развернули нашего чат-бота в облаке Azure в качестве службы приложений, и в Application Insights мы видим несколько исключений типа TaskCanceledException, которые появляются случайным образом.

После принятияПосмотрите журналы, которые мы определили три строки кода, которые бросают исключения.Я отметил их как TaskCanceledException source #.Вот упрощенная структура нашего контроллера обмена сообщениями для справки:

public async Task<IHttpActionResult> Post([FromBody]BotActivity activity)
{
    try
    {
        var result = await PostInternal(activity).ConfigureAwait(false);

        return result;
    }
    catch (Exception e)
    {
        Logger.Error(e);
        throw;
    }
}

private async Task<IHttpActionResult> PostInternal(BotActivity activity)
{
    // TaskCanceledException source #1.
    await SendTypingIndicator(activity).ConfigureAwait(false);

    var type = activity.GetActivityType();
    if (type == ActivityTypes.Message)
    {
        // TaskCanceledException source #2.
        var flag = await LoadFlagFromBotState(activity).ConfigureAwait(false);

        // Some logic slightly altering flow according to value of 'flag'.

        // TaskCanceledException source #3.
        await Conversation.SendAsync(activity, () => new RootDialog()).ConfigureAwait(false);
    }

    return Ok();
}

private async Task SendTypingIndicator(BotActivity activity)
{
    var reply = activity.CreateReply();
    reply.Type = ActivityTypes.Typing;
    reply.Text = null;
    ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

    await connector.Conversations.ReplyToActivityAsync(reply).ConfigureAwait(false);
}

private async Task<bool> LoadFlagFromBotState(BotActivity activity)
{
    using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
    {
        var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
        var key = Address.FromActivity(activity);
        var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None).ConfigureAwait(false);

        var flag = userData.GetProperty<bool>("TheFlag");
        if (!flag)
        {
            userData.SetProperty("TheFlag", true);
            await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None).ConfigureAwait(false);
            await botDataStore.FlushAsync(key, CancellationToken.None).ConfigureAwait(false);
        }

        return flag;
    }
}

А вот URL внешних зависимостей, время ожидания которых истекло в соответствии с Application Insights:

Дополнительная информация

  • Наш бот размещен в качестве службы приложений в облаке Microsoft Azure.
  • Мы подключили собственный менеджер BotState в соответствии с следующей документацией , чтобы все BotState хранилось вCosmos DB.
  • Наш экземпляр Cosmos DB находится в той же группе ресурсов Azure, что и служба приложений бота.
  • Мы проверили доступность и пропускную способность нашего экземпляра Cosmos DB, и, кажется, все в порядке..
  • Мы используем DirectLine в качестве канала связи.
  • TaskCanceledExceptionпроисходит случайным образом, и, похоже, нет никаких конкретных шагов, которые необходимо выполнить, чтобы воспроизвести это.
  • Мы попытались адаптировать шаблон async-await «надлежащим образом», например, убедившись, что мыне смешивать синхронизирующий и асинхронный код и использовать ConfigureAwait (false) везде, где находится ключевое слово await.

Заключение

Мы пытались выяснить первопричинунекоторое время, однако, мы понятия не имеем, в чем может быть проблема здесь.Мы исключили проблемы с сетью из-за того, что здесь мы используем PaaS Azure.

Буду признателен за любой совет.

...