README
gzippo
Сканирует исходную директорию, каждый файл в этой директории будет сжат с помощью GZip и сохранён в другую директорию.
Как работает
В работе утилиты можно выделить две стадии:
- Сканирование директории;
- Сжатие файлов.
Во время сканирования директории составляется список задач на сжатие файлов, задачи записываются в БД PostgreSQL. После завершения сканирования выполнение задач на сжатие файлов. Один процесс единовременно может выполнять лишь одну задачу на сжатие файлов. Результат выполнения каждой задачи регистриурется в БД.
Чтобы сжимать одновременно несколько файлов можно запустить несколько процессов в одинаковым набором параметров. Стоит отметить, что сканирование директории при запуске нескольких процессов будет выполняться только одним из них, остальные будут ждать результатов сканирования и начнут обрабатывать задачи на сжатие файлов сразу после завершения сканирования.
Саканирование директории
- Выполняется проверка - было ли выполнено сканирование директории ранее (проверяется существование списка задач
в БД). Если список задач уже существует и не требуется повторное сканирование директории (см. параметр
--rebuild
), то сканирование считается выполненным; - В БД регистрируется список задач и эта запись блокируется от чтения и записи;
- Выполняется сканирование директории, для каждого найденного файла в БД добавляется задача на сжатие файла. В задаче указывается, какой файл надо прочитать и куда положить результат;
- После того, как сканирование завершено и все задачи на сжатие файлов зарегистрированы блокировка со списка задач снимается. Сканирование считается выполненным.
Важно! В директории с исходными файлами могут встречаться ссылки на другие директории. Чтобы избежать рекурсивного сканирования мы пропускаем:
- Ссылки на директории, которые содержат внутри себя директорию с исходными файлами;
- Ссылки на директории, которые сами содержатся внутри директории с исходными файлами.
Сжатие файла
- Получение задачи на сжатие файла - будет выбрана любая из невыплненных задач. Задачи, которые выполняются в другом процессе (записи этих задач заблокированы), не участвуют в выборе. Если не найдено ни одной задачи, то процесс завершает работу;
- Запись в базе данных соответствующая задаче блокируется от чтения и записи;
- Проверяется наличие директории, куда надо сохранить конечный файл. Если директории нет, то предпринимается попытка создать её;
- Исходный файл открывается на чтение, выполняется его сжатие с записью в конечный файл, расположенный в другой директории;
- Результат выполнения задачи регистрируется в БД, блокировка с записи снимается;
- Если по ходу выполнения задачи происходит ошибка (нет исходного файла, нет прав на его чтение, возникли проблемы с созданием целевой директории или с записью в конечный файл), ошибка выполнения задачи так же регистрируется в БД и блокировка снимается с записи.
Установка
Docker Compose
curl -o docker-compose.yml https://raw.githubusercontent.com/sempasha/gzippo/master/docker-compose.yml
docker-compose pull
NPM
Глоабальная установка
npm install -g @sempasha/gzippo
На Linux, при глобальноу установке от root могут позникнуть проблемы при установке модуля
dtrace-provider, возникает ошибка
Error: EACCES: permission denied, mkdir '/usr/lib/node_modules/@sempasha/gzippo/node_modules/dtrace-provider/build'
.
В этом случае можно применить грязный костыль.
sudo npm install -g --unsafe-perm=true @sempasha/gzippo
Использование
Docker Compose
Содайте .env файл в котором укажите из какой директории нужно взять файлы для сжатия и в какую директорию их надо положить:
echo 'GZIPPO_SOURCE=/source' > .env
echo 'GZIPPO_DESTINATION=/destination' >> .env
Можно запускать сервис
docker-compose up -d
Чтобы запустить несколько инстансов сервиса gzippo (например, 3):
docker-compose up -d --scale gzippo=3
CLI
gzippo [options] [source] <destination>
Например, сжать все файлы в текущей директории и поместить сжатые файлы в директорию /destination/path
:
gzippo /destination/dir
Или
gzippo . /destination/dir
Можно сжать файлы в любой директории на хосте:
gzippo /source/dir /destination/dir
Важно! Директория, в которую необходимо сохранить файлы не должна располагаться внутри директории с исходными файлами.
Параметры запуска
Все параметры могут быть заданы, как с помощью параметров команды ([OPTIONS]
), так и с помощью переменных окружения.
Переменные окружения имеют приоритет ниже, чем параметры команды.
Использование параметра --param-name
:
gzippo --param-name value /destination/dir
Использование переменной окружения GZIPPO_PARAM_NAME
вместо параметра --param-name
:
env GZIPPO_PARAM_NAME=value gzippo /destination/dir
Если одновременно указать и параметр и переменную окружения, то переменная окружения будет иметь более низкий приоритет:
env GZIPPO_PARAM_NAME=value1 gzippo --param-name value2 /destination/dir
В этом примере параметр будет иметь значение value2
Хост
Параметр: --hostname
Переменная оркужения: GZIPPO_HOSTNAME
Значение по умолчанию: Название хоста
Имя хоста. Наряду с именами директорий, откуда нужно взять исходные файлы и куда надо записть сжатые файлы, определяет уникальность списка зазадч. Если одна база данных используется для регистрации задач на сжатие файлов с разных хостов, имя хоста позволит разделить списки задач задачи.
PostgreSQL URL
Параметр: --pg-url
Переменная оркужения: GZIPPO_PG_URL
Значение по умолчанию: postgresql://postgres:postgres@localhost:5432/postgres
Адрес для подключения к PostgreSQL.
Повторное сканирование
Параметр: --rebuild
Переменная оркужения: GZIPPO_REBUILD
Значение по умолчанию: (нет)
Произвести повторое сканирование директории. По умолчанию сканирование директории производится только один раз. Но если использовать данный параметр, то директория будет просканирована повторно.
Запуск тестов
git clone git@github.com:sempasha/gzippo.git
cd gzippo
docker-compose -f docker-test.yml pull
docker-compose -f docker-test.yml run gzippo
Разработка
git clone git@github.com:sempasha/gzippo.git
cd gzippo
docker-compose -f docker-dev.yml pull
docker-compose -f docker-dev.yml run gzippo bash
TODO
- Добавить тесты для СLI интерфейса (параметры, запуск нескольких процессов и т.д.);
- Добавить опцию определяющую владельца созданных директорий и файлов, а так же права на доступ к ним. Так же можно сохранять исходного владельца и права (при возможности). При запуске в контейнере эта проблема так же актуальна (если dockerd запускает контейнеры от root);
- Можно добавить параметр для определения уровня сжатия;
- Запуск нескольких процессов с флагом
--rebuild
приводит к тому, что все эти процессы будут перестраивать список задач. Можно придумать какой-то критерий, который позволит производить обновление списка задач при его выполнении, Например, время, прошедшее с последнего обновления; - Обновление списка задач можно производить таким образом, чтобы не выполнять уже выполненные задачи повторно. Но в этом случае скорее всего придется считать контрольные суммы или хэши у файлов;
- Для контроля над потоками сжатия проще использовать очереди (RabbitMQ), нежели блокировки в БД.