Azure Функция Durable Timer не активируется до тех пор, пока приложение не будет затронуто - PullRequest
7 голосов
/ 10 февраля 2020

У меня есть Durable Orchestration, который масштабируется вверх и вниз Azure Пропускная способность Cosmos DB по запросу. Масштабирование запускается через HTTP, а уменьшение происходит позже через Durable Timer , который должен активировать функцию Azure в конце текущего или следующего часа. Вот функция Orchestrator:

public static class CosmosDbScalerOrchestrator
{
    [FunctionName(nameof(CosmosDbScalerOrchestrator))]
    public static async Task RunOrchestrator(
        [OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var cosmosDbScalerRequestString = context.GetInput<string>();

        var didScale = await context.CallActivityAsync<bool>(nameof(ScaleUpActivityTrigger), cosmosDbScalerRequestString);

        if (didScale)
        {
            var minutesUntilLastMinuteOfHour = 59 - context.CurrentUtcDateTime.Minute;
            var minutesUntilScaleDown = minutesUntilLastMinuteOfHour < 15
                ? minutesUntilLastMinuteOfHour + 60
                : minutesUntilLastMinuteOfHour;
            var timeUntilScaleDown = context.CurrentUtcDateTime.Add(TimeSpan.FromMinutes(minutesUntilScaleDown));
            await context.CreateTimer(timeUntilScaleDown, CancellationToken.None);
            await context.CallActivityAsync(nameof(ScaleDownActivityTrigger), cosmosDbScalerRequestString);
        }
    }
}

Вот ScaleUpActivityTrigger:

public class ScaleUpActivityTrigger
{
    [FunctionName(nameof(ScaleUpActivityTrigger))]
    public static async Task<bool> Run([ActivityTrigger] string cosmosDbScalerRequestString, ILogger log)
    {
        var cosmosDbScalerRequest =
            StorageFramework.Storage.Deserialize<CosmosDbScalerRequest>(cosmosDbScalerRequestString);

        var scaler = new ContainerScaler(cosmosDbScalerRequest.ContainerId);
        var currentThroughputForContainer = await scaler.GetThroughputForContainer();

        // Return if would scale down
        if (currentThroughputForContainer > cosmosDbScalerRequest.RequestedThroughput) return false;

        var newThroughput = cosmosDbScalerRequest.RequestedThroughput < 25000
            ? cosmosDbScalerRequest.RequestedThroughput
            : 25000;
        await scaler.Scale(newThroughput);

        return true;
    }
}

и ScaleDownActivityTrigger:

public class ScaleDownActivityTrigger
{
    [FunctionName(nameof(ScaleDownActivityTrigger))]
    public static async Task Run([ActivityTrigger] string cosmosDbScalerRequestString, ILogger log)
    {
        var cosmosDbScalerRequest =
            StorageFramework.Storage.Deserialize<CosmosDbScalerRequest>(cosmosDbScalerRequestString);
        var scaler = new ContainerScaler(cosmosDbScalerRequest.ContainerId);
        var minimumRusForContainer = await scaler.GetMinimumRusForContainer();
        await scaler.Scale(minimumRusForContainer);
    }
}

Однако, что я обратите внимание, что функция не пробуждается, пока что-то еще не запускает длительную оркестровку. Обратите внимание на разницу в отметках времени, когда это было запланировано, и когда это произошло.

Azure Portal screenshot showing different timestamps

Это тот факт, что до тех пор он не проснулся или ошибка? Если это по замыслу, как я могу разбудить его, когда я действительно хочу?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...