Azure Durable оркестровка функция запускается дважды - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь реализовать рабочий процесс Azure Durable Function.

Каждые 6 минут у меня есть функция Azure TimerTrigger, которая вызывает функцию оркестровки Azure (OrchestrationTrigger), которая, в свою очередь, запускает ряд функций деятельности (ActivityTrigger),

Иногда, однако, функция Orchestration вызывается дважды в течение нескольких секунд!Это большая проблема, так как мои функции активности не являются идемпотентными!

Ниже описывается, как вызывается мой код.

Функция TimerTriggered:

[FunctionName("StartupFunc")]
public static async Task Run([TimerTrigger("0 */6 * * * *", RunOnStartup = true, UseMonitor = false)]TimerInfo myStartTimer, [OrchestrationClient] DurableOrchestrationClient orchestrationClient, TraceWriter log)
{
    List<OrchestrationModel> ExportModels = await getData();

    string id = await orchestrationClient.StartNewAsync("OrchestratorFunc", ExportModels);
}

Функция оркестровки:

[FunctionName("OrchestratorFunc")]
public static async Task<string> TransformOrchestration([OrchestrationTrigger] DurableOrchestrationContext context, TraceWriter log)
{
    var dataList = context.GetInput<List<OrchestrationModel>>();
    var tasks = new List<Task>();

    foreach (var data in dataList)
    {
        tasks.Add(context.CallActivityAsync<string>("TransformToSql", new TransformModel(data));
    }
    await Task.WhenAll(tasks);
}

Функция деятельности:

[FunctionName("TransformToSql")]
[public static async Task<string> RunTransformation([ActivityTrigger] DurableActivityContext context, TraceWriter log)
{
    TransformModel = context.GetInput<TransformModel>();

    //Do some work with TransformModel
}

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Функция оркестровки будет выполняться чаще, так как она воспроизводится средой Durable Function.Видите ли вы, что ваши функции деятельности также запускаются снова?Если это так, то это действительно странное поведение.

Durable Functions использует очереди хранения и таблицы для управления потоком и состоянием захвата оркестровки.

Каждый раз, когда запускается функция оркестровки (при получении сообщения из очереди управления), она будет воспроизводить оркестровку.Вы можете проверить это в коде, используя свойство IsReplaying в DurableOrchestrationContext.

if (!context.IsReplaying)
{
   // this code will only run during the first execution of the workflow
}

Не используйте IsReplaying, чтобы определить, что нужно выполнять действия, но используйте его для целей регистрации / отладки.

Когда достигается функция действия, появляется сообщениеочередь рабочих элементов.Инфраструктура Durable Functions затем изучит таблицу истории, чтобы определить, выполнялась ли ранее эта функция активности (с заданными параметрами).Если это так, то он больше не будет запускать функцию активности и продолжит работу с остальной частью функции оркестровки.

Функции контрольных точек и воспроизведения Durable Functions работают только тогда, когда код оркестрации является детерминированным.Поэтому никогда не используйте решения, основанные на DateTime или случайных числах.

Дополнительная информация: https://docs.microsoft.com/en-us/azure/azure-functions/durable-functions-checkpointing-and-replay

0 голосов
/ 12 сентября 2018

Это поведение совершенно нормально - именно так Durable Functions работает по своему замыслу.

У вас есть следующая оркестровка:

[FunctionName("OrchestratorFunc")]
public static async Task<string> TransformOrchestration([OrchestrationTrigger] DurableOrchestrationContext context, TraceWriter log)
{
    var dataList = context.GetInput<List<OrchestrationModel>>();
    var tasks = new List<Task>();

    foreach (var data in dataList)
    {
        tasks.Add(context.CallActivityAsync<string>("TransformToSql", new TransformModel(data));
    }
    await Task.WhenAll(tasks);
}

Когда вызывается действие, поток возвращается кКонцепция под названием Диспетчер - это внутреннее существо Durable Functions, отвечающее за поддержание потока вашей оркестровки.Поскольку он ожидает, пока задача не будет завершена, оркестровка временно отменяется.Как только задача завершена, вся оркестровка воспроизводится до тех пор, пока не произойдет следующее await.

Важная вещь, хотя при воспроизведении оркестрации, действие не вызывается еще раз - его результат выбирается изхранение и использование.Для большей ясности рассмотрим следующий пример:

[FunctionName("OrchestratorFunc")]
public static async Task<string> TransformOrchestration([OrchestrationTrigger] DurableOrchestrationContext context, TraceWriter log)
{
    var dataList = context.GetInput<List<OrchestrationModel>>();
    var tasks = new List<Task>();

    foreach (var data in dataList)
    {
        await context.CallActivityAsync<string>("TransformToSql1", new TransformModel(data);
        await context.CallActivityAsync<string>("TransformToSql2", new TransformModel(data);
    }
}

Когда ожидается TransformToSql1, оркестрация освобождается, и весь поток ожидает завершения этой операции.Затем оркестровка воспроизводится - она ​​еще раз ожидает TransformToSql1, но поскольку ее результат сохраняется, она просто возвращается к оркестровке и ожидает TransformToSql2 - затем процесс повторяется.

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