Веб-сервис для скачивания файлов по ссылкам с поддержкой graceful shutdown и восстановления состояния.
Сервис позволяет пользователям отправлять задачи со списками ссылок на файлы для скачивания. Файлы сохраняются в локальную папку, а статус задач можно отслеживать через REST API.
- Параллельная обработка: Настраиваемое количество воркеров для одновременного скачивания
- Graceful shutdown: Корректное завершение работы с сохранением состояния
- Персистентность: Сохранение и восстановление задач при перезапуске
- Мониторинг: Отслеживание статуса выполнения задач
- Таймауты: Защита от зависших загрузок
Проект следует принципам чистой архитектуры:
internal/
├── domain/ # Бизнес-логика и интерфейсы
├── usecase/ # Use cases / сценарии использования
└── infrastructure/ # Внешние зависимости
├── config/ # Конфигурация
├── handlers/ # HTTP обработчики
├── storage/ # Реализации хранилищ
└── workerpool/ # Worker Pool
- Dependency Injection: Внедрение зависимостей через конструкторы
- Repository Pattern: Абстракция хранилища файлов через интерфейс
Storage - Worker Pool: Пул воркеров для параллельной обработки задач
- Graceful Shutdown: Корректное завершение работы с сохранением состояния
- Context Cancellation: Использование контекста для управления жизненным циклом
pending- задача создана, ожидает обработкиrunning- задача выполняетсяcompleted- задача успешно завершенаfailed- задача завершилась с ошибкой
- Go 1.24+
- Доступ к интернету для скачивания файлов
go mod downloadgo run cmd/server/main.goСервер запустится на http://localhost:8080
Настройки находятся в файле configs/config.yaml:
server:
host: "0.0.0.0"
port: 8080
workerpool:
num_workers: 4 # количество параллельных воркеров
task_queue_size: 100 # размер канала задач
storage:
downloads_dir: "downloads" # папка для сохранения файлов
tasks:
file: "tasks.json" # файл для сохранения состояния задачcurl -X POST http://localhost:8080/tasks \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com/file1.pdf",
"https://example.com/file2.jpg"
]
}'Ответ:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"urls": ["https://example.com/file1.pdf", "https://example.com/file2.jpg"],
"status": "pending",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
}curl http://localhost:8080/taskscurl http://localhost:8080/tasks/123e4567-e89b-12d3-a456-426614174000При получении сигнала прерывания (Ctrl+C) сервис:
- Прекращает принимать новые HTTP-запросы
- Ожидает завершения текущих задач
- Сохраняет состояние всех задач в файл
tasks.json - Корректно завершает работу
При запуске сервис:
- Загружает задачи из файла состояния
- Переводит
runningзадачи в состояниеpending - Добавляет незавершенные задачи в очередь обработки
- Таймауты: Каждый файл скачивается с таймаутом 3 минуты
- Сетевые ошибки: При ошибке скачивания любого файла вся задача помечается как
failed - Восстановление: Панические ситуации обрабатываются middleware
- Имена файлов: Используется базовое имя из URL (функция
filepath.Base()) - Дублирование: Файлы с одинаковыми именами перезаписываются
- Размер файлов: Нет ограничений на размер (может потребовать доработки для production)
- Concurrency: Один файл = одна загрузка (можно добавить поддержку chunk-загрузки)
go test ./...go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out- Создание и получение задач
- Сохранение/загрузка состояния
- Успешное скачивание файлов
- Обработка ошибок сети
- Локальное сохранение файлов
- База данных: Замена файлового хранилища на PostgreSQL/SQLite
- Retry mechanism: Повторные попытки при временных сбоях
- Прогресс загрузки: Отслеживание процента выполнения
- Webhooks: Уведомления о завершении задач
- Rate limiting: Ограничение нагрузки на внешние ресурсы
- Chunk downloading: Загрузка больших файлов частями
- Валидация URL: Проверка корректности ссылок
- Метрики: Интеграция с Prometheus/Grafana
- S3: Подключение объектного хранилища для загрузки файлов в облако