Pull to refresh

Comments 16

А вот в этом всём, меня смущает что logger синхронный, как быть?

Можно использовать polog в асинхронном режиме.

интересно, но маленькая популярность и локальность, конечно напрягает, чтобы такое к себе тащить(

я вот пока в поисках, есть loguru, но там как-то не очень очевидное с await logger.complete(), глянул aiologger, там тоже какой-то await logger.shutdown(), вот еще новое в комментах предложили, пока внимательно не смотрел.

В целом сервис выглядит хорошо, но:

  1. Не хватает тестов.

  2. Не предусмотрены репликация / шардирование.

  3. Что будет, если в процессе загрузки данных в файл выключится электричество на сервере? На диске окажется битый файл, а в БД о нем записей не будет. Со временем при постоянном пользовании сервисом такие файлы неизбежно будут возникать и накапливаться. Одно из возможных решений - писать в файл внутри транзакции БД. Но это порождает риск долгих транзакций, от которого можно избавиться, если хранить не файлы целиком, а чанки (также это может частично решить проблему с фрагментацией диска).

  4. await request.content.read() будто бы таки считывает файл в память полностью, после чего уже записывает на диск. То есть не соблюдается главная гарантия вашего сервиса - что он не держит файлы в памяти целиком.

  5. aiofiles - немного сомнительная библиотека.

  6. Не вижу возможности параметризовать сервис при помощи переменных окружения.

  7. Нет возможности запуска в контейнере.

  8. Инициализация движка БД выглядит странно. Если по итогу все равно создается глобальная переменная, зачем это пихать в функцию?

Спасибо большое за развернутый комментарий. Почемуaiofiles сомнительная библиотека? Какие предлагаете альтернативы?

Есть aiofile, заявляется нативная асинхронная работа с файлами в Linux

По п3. Решение довольно простое. Перед загрузкой файла делать некоторый черновик записи о файле со статусом pending. Загружать файл. Апдейтить запись на статус processed. А дальше в фоне подчищать все, что не в processed статусе и со старой временной меткой.

Это может быть опасно, поскольку неизвесно, сколько точно должна длиться загрузка. Лимитов на размер файлов тут нет, теоретически пользователь может из тайги по GPRS 100-гиговый рип "аватара 2" качать. А если автор запилит еще и возобновление загрузки после обрыва соединения, то вообще.

Можно периодически чекать не изменился ли размер файла с прошлой проверки и уже тогда грохать файл

Я не вижу, чем это проще, нежели организовать код правильно, чтобы запись файлов осуществлялась внутри транзакции БД. Вы предлагаете дополнить проект новыми сущностями, при том, что по итогу гарантий это дает даже меньше.

Ещё раз спасибо за комментарии. Внёс исправления в проект:

  • добавил тесты

  • `await request.content.read()` заменил на `async for data in request.content.iter_any()`

  • библиотеку `aiofiles` заменил на `aiofile`

  • параметризовал сервис переменными окружения

  • добавил запуск проекта в docker'е

  • инициализацию движка БД перенес в область глобальной видимости модуля

  • заменил `logger` на `aiologger`

По оставшимся вопросам:

  • репликация / шардирование постановкой задачи не были предусмотрены. Заранее было оговорено, что сервис работает в рамках локальной сети заказчика и бэкап делается его силами.

  • Если в процессе загрузки данных в файл выключится электричество на сервере, то процесс придется начинать заново. Насколько я себе представляю, чтобы возобновить загрузку файла с определенного места нужно ещё научить клиента понимать, с какого места продолжить байтовый поток. Но клиент в данном кейсе давался уже "как есть". Чтобы избежать ссылок на битые файлы, сохранение данных о новом файле в БД сервиса происходит только после сохранения файла на диске.

При обрыве соединения клиент сможет докачивать только недостающие данные или будет грузить все по новой?

Придется грузить всё по новой. Чтобы была возможность докачки, нужно дорабатывать и код сервера и код клиента. Обновление кода клиента в постановку задачи в рамках данного кейса не входил.

Sign up to leave a comment.

Articles