Как загружать файлы и обрабатывать и проверять - общий обзор?

Проблема под рукой

  1. У меня есть приложение для рельсов.
  2. Пользователи будут загружать файлы. От 1 до 3000 файлов. Иногда это zip-файлы, а иногда нет. Я не хочу задерживать сервер загрузкой этих файлов, поэтому ищу решение этой проблемы.
  3. Заархивированные файлы необходимо разархивировать.
  4. Затем я хочу проверить, загружал ли пользователь ранее те же файлы? то есть, если пользователь уже загрузил тот же файл (2) неделю назад, то это проблема: (i) либо мы не разрешаем загрузку этого конкретного файла, либо мы спрашиваем пользователя: вы уверены, что хотите загрузить тот же файл еще раз?
  5. Затем я хочу сохранить ключи / ссылки на файлы в соответствующих моделях / записях на задней панели.

Было интересно, какой может быть лучший рабочий процесс для решения вышеупомянутого: то есть очень общий обзор: другими словами, могут ли облачные вычисления AWS Lambda / Google и т. Д. И т. Д. Лучше всего использовать для решения вышеуказанной проблемы? Как нам лучше всего справиться с этой ситуацией с помощью драгоценного камня Святыни? Имеет ли смысл использовать AWS Lambda вместо фоновых заданий?

Я предпочитаю использовать для загрузки драгоценный камень Shrine.

Мои идеи:

  1. На стороне клиента пользователь перетаскивает файлы, которые пользователь хочет загрузить.
  2. Затем все файлы загружаются (заархивированные или иным образом) во временное хранилище через гем Shrine.
  3. ЕСЛИ zip-файлы загружены, возможно, необходимо запустить лямбда-функцию AWS для распаковки файлов. Если это так, то в конце дня ключи для этих файлов должны каким-то образом быть возвращены клиенту для решения проблем с проверкой - но тогда как лямбда-функция AWS сможет вернуть этот запрос исходной стороне клиента? откуда поступил запрос? Или, скорее, следует ли генерировать лямбда-функцию AWS на стороне клиента, передавая идентификаторы распакованных больших двоичных объектов?
  4. Затем нам нужно выполнить некоторые проверки: мы хотим справиться с ситуацией, когда есть повторяющиеся файлы. Нам нужно будет проверить с помощью наших рельсов, были ли эти файлы уже загружены.
  5. После того, как эти проблемы проверки будут обработаны, пользователь отправляет форму, и все ключи сохраняются в соответствующих записях.

Эти идеи ни в коем случае не носят предписывающий характер.

Я ищу несколько очень общих советов о том, как лучше всего сделать все это. Я ни в коем случае не ограничен AWS: с таким же успехом я мог бы использовать Google или Azure. Будем очень признательны за любые рекомендации по вышеизложенному.

Конкретные вопросы:

  1. Как будет срабатывать лямбда-функция AWS?
  2. Как можно будет вернуть клиенту ключи загруженных файлов?

Что я имею в виду под общим обзором?

Вот несколько примеров общих обзоров:

(1) Загрузка и распаковка файлов в S3 через Rails, размещенный на Heroku?

(2) https://www.quora.com/How-do-I-extract-large-zip-files-in-AWS-Lambda

Будем очень признательны за любые указатели в правильном направлении.

Ваше здоровье!


person BKSpurgeon    schedule 16.12.2019    source источник
comment
Что вы имеете в виду под ключами? В Shrine вы храните очень мало информации. Основная информация, которую вы храните, - это имя файла в вашей корзине S3. Я не уверен, что это то, что вы называете ключом. В противном случае то, чего вы пытаетесь достичь, будет довольно сложно. Первый вопрос, на который нужно ответить: достаточно ли у меня мощности внешнего сервера, чтобы пользователи могли загружать файлы на S3 через приложение Rails? Если вы загружаете через приложение, вы можете разархивировать и проверить, не дублируются ли, но это также будет держать ваш поток Puma занятым, а также, если вы размещаете в Heroku, вы можете быть ограничены 30-секундным таймаутом ..   -  person Maxence    schedule 16.12.2019
comment
Также в отношении UX это будет сложно. например, я не знаю ни одной библиотеки загрузки JS (Uppy ..), которая допускает условную загрузку, например, вы действительно хотите загрузить этот файл? после проверки приложением rails. Вероятно, лучше сделать это в асинхронном задании и добавить флажок рядом с загруженным файлом, который может быть дубликатом. Также я не совсем уверен, как помечать дубликаты .. (то же имя? Или точно такие же данные?) Может потребоваться время, чтобы сравнить один файл с другими уже загруженными 2000 файлами. Тогда обязательно рекомендую async   -  person Maxence    schedule 16.12.2019


Ответы (1)


Это не очень сложная проблема для решения, если вы хотите немного изменить поток процесса.

На стороне клиента пользователь перетаскивает файлы, которые пользователь хочет загрузить.

Когда пользователь запрашивает начало операции загрузки, вы можете выполнять HTTP-запросы GET к конечной точке API-шлюза с поддержкой Lambda. Lambda может запрашивать предыдущие файлы, загруженные клиентом, и отправлять обратно набор результатов, показывающий, какие файлы уже существуют. Затем вы отфильтровываете их и отправляете от клиента на сервер только то, что считается новым. Это сэкономит время пользователя при ожидании загрузки и сэкономит ваше время на стороне S3 / Lambda, так как вам не нужно хранить дубликаты или обрабатывать их. Это не заменяет проверку на стороне сервера, вы все равно захотите это сделать. Для легальных клиентов это сэкономит вам и им много трафика и хранилища.

Затем все файлы загружаются (заархивированные или иным образом) во временное хранилище через гем Shrine.

Это работает. Когда они входят во временную корзину, используйте Lambda с событием S3., чтобы обработать файлы, разархивировать файлы, передать все необходимые метаданные в DynamoDb и удалить файлы из временного контейнера. Во временном ведре я бы поместил файлы в папку, уникальную для каждого запроса и пользователя. Я бы взял идентификатор пользователя / клиента и какой-либо UUID и сделал бы это имя вашей папки. Например, Johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f, или закодируйте это значение в строку Base64 и сделайте это именем своей папки. Сохраните это в DynamoDb с каждым файлом, загруженным в вашу постоянную корзину, где хэш-ключ является идентификатором пользователя / clientid, ключ сортировки - это полный путь к папке + имя файла и дополнительный атрибут IsProcessed. Атрибут IsProcessed будет обновлен вашей лямбдой, которая обрабатывает файлы и перемещает их в постоянную корзину S3. Если есть ошибки, вы можете указать их в этом поле. В случае успеха вы помещаете его в это поле.

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

Исходный запрос API на отправку файлов во временную корзину S3 сможет вернуть клиенту имя папки johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f. Допустим, вы отправили HTTP-запрос /jobs. Вы вернетесь обратно 201 Created с заголовком HTTP Location /jobs/johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f. После этого ваш клиент может начать опрашивать /jobs/johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f статус процесса.

Ваш ответ на /jobs/johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f может вернуть записи DynamoDB. Это будет включать все записи DynamoDB для HashKey, соответствующие имени папки. Ваша клиентская сторона может просмотреть все объекты в наборе результатов и проверить атрибут IsProcessed, чтобы убедиться, что все сработало нормально или возникли проблемы.

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

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

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

Все это будет происходить асинхронно, начиная с момента отправки формы пользователем. Клиентская сторона должна иметь возможность обрабатывать это, отправляя HTTP-запросы GET к конечной точке, упомянутой выше, проверяя статус процесса. Это дает вам больше гибкости, так как вы также можете публиковать сообщения SNS при сбоях, например, отправлять электронное письмо клиентам, если они загружают 3000 файлов, и вам нужно потратить 30 минут на их обработку.

person Johnathon Sullinger    schedule 17.12.2019
comment
Очень интересное решение. Я рассмотрю реализацию более подробно, но вы правильно ответили на исходный вопрос, и я благодарю вас. Вероятно, ваш ответ поможет и многим другим! - person BKSpurgeon; 18.12.2019
comment
Можете ли вы отметить это как ответ, если это касается вашего вопроса о происхождении? - person Johnathon Sullinger; 22.12.2019