@sempasha/gzippo

Сканирует исходную директорию, каждый файл в этой директории будет сжат с помощью GZip и сохранён в другую директорию

Usage no npm install needed!

<script type="module">
  import sempashaGzippo from 'https://cdn.skypack.dev/@sempasha/gzippo';
</script>

README

gzippo

Сканирует исходную директорию, каждый файл в этой директории будет сжат с помощью GZip и сохранён в другую директорию.

Как работает

В работе утилиты можно выделить две стадии:

  1. Сканирование директории;
  2. Сжатие файлов.

Во время сканирования директории составляется список задач на сжатие файлов, задачи записываются в БД PostgreSQL. После завершения сканирования выполнение задач на сжатие файлов. Один процесс единовременно может выполнять лишь одну задачу на сжатие файлов. Результат выполнения каждой задачи регистриурется в БД.

Чтобы сжимать одновременно несколько файлов можно запустить несколько процессов в одинаковым набором параметров. Стоит отметить, что сканирование директории при запуске нескольких процессов будет выполняться только одним из них, остальные будут ждать результатов сканирования и начнут обрабатывать задачи на сжатие файлов сразу после завершения сканирования.

Саканирование директории

  1. Выполняется проверка - было ли выполнено сканирование директории ранее (проверяется существование списка задач в БД). Если список задач уже существует и не требуется повторное сканирование директории (см. параметр --rebuild), то сканирование считается выполненным;
  2. В БД регистрируется список задач и эта запись блокируется от чтения и записи;
  3. Выполняется сканирование директории, для каждого найденного файла в БД добавляется задача на сжатие файла. В задаче указывается, какой файл надо прочитать и куда положить результат;
  4. После того, как сканирование завершено и все задачи на сжатие файлов зарегистрированы блокировка со списка задач снимается. Сканирование считается выполненным.

Важно! В директории с исходными файлами могут встречаться ссылки на другие директории. Чтобы избежать рекурсивного сканирования мы пропускаем:

  1. Ссылки на директории, которые содержат внутри себя директорию с исходными файлами;
  2. Ссылки на директории, которые сами содержатся внутри директории с исходными файлами.

Сжатие файла

  1. Получение задачи на сжатие файла - будет выбрана любая из невыплненных задач. Задачи, которые выполняются в другом процессе (записи этих задач заблокированы), не участвуют в выборе. Если не найдено ни одной задачи, то процесс завершает работу;
  2. Запись в базе данных соответствующая задаче блокируется от чтения и записи;
  3. Проверяется наличие директории, куда надо сохранить конечный файл. Если директории нет, то предпринимается попытка создать её;
  4. Исходный файл открывается на чтение, выполняется его сжатие с записью в конечный файл, расположенный в другой директории;
  5. Результат выполнения задачи регистрируется в БД, блокировка с записи снимается;
  6. Если по ходу выполнения задачи происходит ошибка (нет исходного файла, нет прав на его чтение, возникли проблемы с созданием целевой директории или с записью в конечный файл), ошибка выполнения задачи так же регистрируется в БД и блокировка снимается с записи.

Установка

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

  1. Добавить тесты для СLI интерфейса (параметры, запуск нескольких процессов и т.д.);
  2. Добавить опцию определяющую владельца созданных директорий и файлов, а так же права на доступ к ним. Так же можно сохранять исходного владельца и права (при возможности). При запуске в контейнере эта проблема так же актуальна (если dockerd запускает контейнеры от root);
  3. Можно добавить параметр для определения уровня сжатия;
  4. Запуск нескольких процессов с флагом --rebuild приводит к тому, что все эти процессы будут перестраивать список задач. Можно придумать какой-то критерий, который позволит производить обновление списка задач при его выполнении, Например, время, прошедшее с последнего обновления;
  5. Обновление списка задач можно производить таким образом, чтобы не выполнять уже выполненные задачи повторно. Но в этом случае скорее всего придется считать контрольные суммы или хэши у файлов;
  6. Для контроля над потоками сжатия проще использовать очереди (RabbitMQ), нежели блокировки в БД.