Логирование данных о загрузке скрипта (обновление данных в базе clickhouse)
Техническое описание
Логирование процесса импорта данных выполняется в микросервисе Nest.js - "loader".
Данные по процессу импорта записываются в базу данных postgress и в дальнейшем используются в пределах приложения, например для формирования ответа на запрос о получении информации статуса импорта (загрузка скрипта)
Запуск скрипта вызывается запросом PUT https://fastbord-back-dev.fb-dev.winsolutions.ru/api/v1/script/{projectId}/run, где projectId - идентификатор проекта
После запуска скрипта загрузки клиентская часть с определённой периодичностью вызывает запрос для получения статуса импорта:
Результат запроса:
{
"id": "3dd62e51-f77e-45a7-9902-d4f03225e43d",
"projectId": "5c11b334-98b7-43db-a82a-e86a7e8a2a79",
"sourceId": null,
"status": "pending",
"started": "2025-06-20T17:32:51.908Z",
"loaded": 0,
"progress": 0
}
- id - идентификатор процесса загрузки скрипта
- projectId - идентификатор проекта
- sourceId - идентификатор источника данных
- status - статус импорта данных в таблицу clickhouse
- loaded - количество успешно импортированных записей из источника
- progress - процент выполнения импорта
Для объяснения механизма записи логов по процессу импорта данных рассмотрим подробнее структуру выполнения запроса загрузки скрипта, представленного ранее. ( PUT https://fastbord-back-dev.fb-dev.winsolutions.ru/api/v1/script/{projectId}/run)
Последовательность выполнения запроса:
- Регистрация запроса в контроллере (PUT 'script/:projectId'), проверка авторизации, соответствия роли пользователя (админ или разработчик) – подтверждение доступа к внутренним сервисам приложения
- Отправка в микросервис загрузок (loader) запроса о запуске процесса импорта данных в базу clickhouse (посредством брокера rabbitMQ) - результат, регистрация запроса о запуске
- Выполняется проверка о состоянии обновления проекта. Если в данный момент обновление уже выполняется (запущено другим пользователем) - будет возвращена ошибка с сообщением "Проект/источник с id {идентификатор проекта/источника} уже обновляется". Проверка выполняется благодаря отдельному микросервису "blocker", сообщение происходит через брокер rabbitM
- Создаётся сущность процесса загрузки ("loading"), которая записывается в базу данных postgres. На основе этой сущности процесс импорта добавляется в специальную очередь по загрузке данных. Механизм очереди реализован на основе библиотеки bull, которая является "обёрткой" для redis клиента.
- Когда очередь bull доходит до текущей задачи загрузки, в дочернем процессе сервера Nest.js запускается соответствующая задача (loader-process-ctl.service.ts -> startProcess)
- В зависимости от типа задачи (файловый источник, подключение к бд или rest-соединение) запускается соответствующий дочерний процесс из п.5.
- Файловый источник - дочерний процесс Nest.js отправляет запрос на микросервис GO ("loader_dev") для импорта данных из источника и ожидает сообщений о статусе импорта. Сообщение с сервисом GO внутри дочернего процесса Nest.js осуществляется с помощью брокера. (File.process.ts)
При получении результата импорта, дочерний процесс сообщает результат главному процессу Nest.js через канал IPC - Работа дочерних процессов по импорту данных из подключений к бд и rest-соединений выполняется аналогично, за исключением того, что весь процесс осуществляется на стороне Nest.js, без привлечения микросервиса на GO (loader-pgsql.process.ts, loader-rest-api.process.ts)
- В процессе импорта данных дочерние процессы могут уведомлять главный процесс Nest.js о наступлении ключевых событий, таких как начала запуска импорта, изменение прогресса, успешное выполнение импорта или ошибка (onTaskStart, onTaskProgress, onTaskSuccess, onTaskFail). Благодаря этому, обновляются записи о загрузке данных в базе postgress, а также клиенты получают уведомления о процессе импорта данных в базу clickhouse
Все стадии и этапы импорта данных записываются (логируются) в отдельную таблицу postgres. На каждом этапе импорта, заинтересованные пользователи получают уведомления о статусе процесса через отдельный REST запрос или с помощью сокет соединения