/t2

Primary LanguageGo

Описание

О задании

"Хранилище файлов с доступом по http"

Реализовать демон, который предоставит HTTP API для загрузки (upload) , скачивания (download) и удаления файлов.

Upload: Готово
Download: Готово
Delete: Готово

Основные требования: Параллельная обработка запросов. - Готово (каждый реквест автоматически запускается в отдельной горутине)
Сервис должен гарантировать сохранение загруженного файла, если ответил клиенту HTTP 200/201. - Готово
Предусмотреть обработку ошибок, которые могут возникнуть в процессе выполнения таких действий. - Готово
Предусмотреть возможность вызова callback'ов для pre- и -post-обрабоки загружаемых файлов. - Не до конца понял, что такое пре/пост обработка загружаемых файлов. В коде указал комментарии:
// @todo place precallback here
// @todo place postcallback here
Возможно это что-то наподобие - пожать большое изображение перед сохранением файла и т.д.

Дополнительные требования ( усложнение задания, выполняются по желанию )

  • Добавить контроль целостности файлов:
    сервис не должен отдавать клиенту файл, если его локальная копия "побилась" - Готово (Перед отдачей файла считается его контрольная сумма и сверяется с хешем)
  • клиент при загрузке (upload) может опционально указать один или несколько хешей (md5/sha1/sha256/...). Сервер должен проконтролировать, что хеши совпадают с реальным содержимым, и не сохранять файл (вернуть ошибку), если хотя бы один из хешей не совпадает. - Готово (сделана проверка на три хеша - md5/sha1/sha256)
  • Добавить взаимодействие с redis-сервером: хранить в redis метаданные загруженных файлов - имя, размер, дата загрузки/удаления, кол-во скачиваний. - Готово (Сделано в виде хеша и сортированного множества, в котором хранится количество скачиваний файла. Данное множество также используется при автоочистке для выбора самых редкоиспользуемых файлов)
  • Добавить функциональность автоматического удаления наиболее редко используемых файлов, если суммарный размер файлов превышает N байт. - Готово
  • Limit-ы на кол-во одновременных соединений с одного ip, download/upload/delete rate (rps), maximum download/upload/delete bytes per ip. - Готово (Лимиты для простоты сделаны в виде мап, которые покрыты мютексами)
  • Реализовать сервис в виде отдельной библиотеки с возможностью добавлять новые команды, таким образом расширяя функциональность. - Готово (Сейчас только одна команда daemon, можно будет рядом добавлять другие)
    Также покрыл исходный код тестами (более 80% покрытия). Написание тестов заняло гораздо большее время, чем написание самого кода.
    Всего на таск потратил в районе 16ч
    К сожалению не успел написать комментарии к коду, посчитал, что покрыть код тестами будет лучше

Как проверить

Установка
go get github.com/tmp1test/t2/cmd/daemon

Перейти в папку
cd $GOPATH/src/github.com/tmp1test/t2/

Собрать бинарник:
go build -o=./cmd/daemon/daemon ./cmd/daemon

Для правильной работы приложения необходим конфигурационный файл. В репозитории есть пример конфига (example.json.dist). Для тестовых целей можно использовать его, только при этом необходимо чтобы редис слушал свой стандратный порт (6379). Если дефолтная конфигурация не подходит, необходимо создать свой собственный json-файл (конфигурационные файлы в .gitignore)

Чтобы запустить приложение, необходимо (используется пример конфига):
./cmd/daemon/daemon -cfg=./cmd/daemon/example.json.dist

Для тестирования приложения можно воспользоваться примерами curl-запросов, посмотреть их можно следующим образом:
cat cmd/daemon/mocks/examples/requests.txt

Для того, чтобы проверить покрытие тестами, нужно запустить команду:
go test ./cmd/daemon -coverprofile=cp.out

Посмотреть полученный результат можно следующим образом:
go tool cover -html=cp.out

Должен появиться подобный результат:
ok github.com/tmp1test/t2/cmd/daemon 2.887s coverage: 83.9% of statements