Запустить задачу, когда список задач выполнен

У меня есть ряд файлов, которые мне нужно загрузить. Когда каждый файл загружен, над ним будет выполняться операция. Когда все файлы загружены, я хочу выполнить задачу для всех типов файлов. Технически процесс может выполняться после загрузки любого файла, но если я загружу сотню файлов, я не хочу, чтобы он запускался 100 раз.

Я использую функции Azure, поэтому это должно быть каким-то образом срабатывать, либо с помощью BLOB-объектов, таблиц, очереди или триггеров таймера (или какого-либо другого триггера).

Вот мои мысли о том, как бы я этого добился:

  • Отправить новый файл в хранилище BLOB-объектов
  • Blob trigger is activated
    • File processed
    • Отправить тип файла в хранилище таблиц
    • Очистить очередь
    • Поставить флаг в очередь с задержкой видимости в 1 минуту
  • Queue triggered, with IQueryable<TableEntity> as additional input
    • Get all table entries
    • Выполнить задачу для каждого типа файла (запись в таблице)
    • Удалить обработанные записи из таблицы

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

Я все время думаю, что триггер blob с задержкой видимости может иметь больше смысла, но, насколько я знаю, этого не существует.

Так это правильный способ решить эту проблему с помощью того, что есть в наличии? Есть ли способ лучше?


person Dan Friedman    schedule 31.12.2016    source источник
comment
Можете ли вы объяснить, что делает действие, которое вы хотите выполнить для отдельного типа файла? Обновляет ли он файлы? Прочитать файлы? Можно ли запускать его для одного и того же файла более одного раза?   -  person Anthony Chu    schedule 02.01.2017
comment
Допустим, исследовательская лаборатория сбрасывает файлы. Триггер большого двоичного объекта просматривает все новые файлы и стандартизирует их. Когда вся стандартизация завершена, мы начинаем выполнять более сложную обработку и аналитику для каждого исследования (и может быть обновлено несколько исследований). Могу ли я запустить аналитику n раз для m исследований? Наверное. Но я бы сэкономил кучу денег и ресурсов, просто обработав m раз. Это также упрощает историю мониторинга, поэтому, если возникает ошибка, мы не получаем n ошибок для одного и того же исследования.   -  person Dan Friedman    schedule 02.01.2017
comment
Я думаю, что у вас довольно странный дизайн. Как вы собираетесь быть уверены, что файлы, загруженные в течение 1-минутного окна, принадлежат к одному и тому же набору файлов? Что, если два исследователя загружают файлы одновременно? Возможно, вам следует загрузить наборы файлов в разные папки или просто загрузить все файлы вместе в виде zip (если размер файла позволяет это)   -  person sjkp    schedule 02.01.2017
comment
Я знаю, какие файлы к какому набору принадлежат, в зависимости от их имени файла. Одновременная загрузка на самом деле не проблема. Я действую из-за определенных ограничений со стороны бизнеса. Я не контролирую, как я получаю файлы, а только то, как я их обрабатываю.   -  person Dan Friedman    schedule 05.01.2017


Ответы (1)


Проблема здесь в том, что у вас есть некоторая «полная» задача, которую вы хотите запустить после загрузки файлов; но явного события «загрузка завершена» нет. Вы хотите оптимизировать лучше, чем просто запускать полную задачу после каждой загрузки файла.

Вот несколько вариантов:

  1. Атрибут [Singleton] (https://github.com/Azure/azure-webjobs-sdk/wiki/Singleton) дает вам возможность гарантировать, что функция запускается только один раз (например, распределенная блокировка). Итак, если вы потратите 100 минут на загрузку BLOB-объектов; а выполнение полной задачи занимает 5 минут; вы бы запустили его только 20 раз, а не 100 раз.

  2. Есть предварительная версия Durable Functions, https://github.com/Azure/azure-functions-durable-extension, что позволяет лучше организовать такие вещи. По сути, он позволяет выполнять Task.WhenAll в Функциях Azure.

  3. У вас может быть какой-то механизм задержки, который запускает задачу Complete только после N минут отсутствия новых загрузок. Триггер Blob может а) писать в общий BLOB-объект приема с текущим временем, б) отправлять сообщение очереди с задержкой видимости N минут, и содержимое соответствует квитанции BLOB-объекта. При запуске очереди игнорируйте, если время не совпадает - так как это означает, что другая операция загрузки большого двоичного объекта перезаписала квитанцию ​​в течение вашего N-минутного окна, и поэтому загрузка большого двоичного объекта может быть «последней».

person Mike S    schedule 17.07.2017