Как из одного процесса сообщить в другой о том что закончена обработка группы таблиц

Есть исходная таблица, назовем ее table_source. Эта таблица каким-то образом (для нашей задачи неважно каким) периодически обновляется, периоды обновления условно случайны. У каждой записи в таблице есть уникальное поле - идентификатор (пусть будет id) и несколько полей с данными (data_1, data_2,..). Каждое обновление может добавить новые данные (т.е., после обновления будут как старые идентификаторы, так и новые), а может их полностью заменить (после обновления будут только новые идентификаторы).

А также есть два процесса (скрипты на Python), которые обрабатывают эти данные.

Первый процесс

У него есть несколько функций, каждая из которых обрабатывает данные из таблицы-источника и каждая из функций возвращает несколько результатов. Все результаты работы каждой функции записываются в отдельную таблицу. Работа первого процесса выглядит приблизительно так:

  1. Ждем когда обновятся данные в источнике
  2. Вычисляем функцию_1
  3. Результаты функции_1 записываем в таблица_результаты_1 вместе с идентификаторами
  4. Вычисляем функцию_2
  5. Результаты функции_2 записываем в таблица_результаты_2 вместе с идентификаторами
  6. Повторяем по количеству функций
  7. Переходим к п. 1

Каждая функция работает от нескольких секунд до нескольких минут.

Второй процесс

Должен выполнять следующее - как только данные во всех таблицах обновятся собрать все данные с помощью JOIN в единую таблицу. И потом ее всю обрабатывает.

Вопрос

Как передать информацию от первого процесса ко второму об окончании вычислений и полному обновлению всех таблиц правильно/оптимально/быстро/просто - любые варианты подходят.

Я предполагаю общаться через файловую систему. После окончания обработки новых данных первый процесс выкладывает файл-флаг, второй его ждет и как дождется - собирает таблицы.

Можно, конечно, периодически получать идентификаторы из всех таблиц и сравнивать, но это как-то громоздко.

Но может есть какие-то более оптимальные способы в SQL? Или еще как? Мне этот вопрос интересен и с практической и с исследовательской точек зрения, для самообразования.

Не знаю какие тэги поставить, если что - поправьте


Ответы (1 шт):

Автор решения: Alexey Trukhanov

Особая благодарность Akina за наводку.

Для общения Python с postgresql я использую модуль psycopg версии 3, поэтому ответ актуален для этого модуля именно этой версии.

В postgresql существует механизм похожий на брокер сообщений, а именно NOTIFY / LISTEN. Данный механизм не является стандартом SQL и актуален для postgresql, начиная с версии 9.0.

Для подробного ознакомления с этим механизмом рекомендую официальную документацию postgresql

С помощью команды LISTEN <название канала> процесс-приёмник организует прослушивание канала. Название канала произвольно.

С помощью команды NOTIFY <название канала>, <сообщение> процесс-передатчик отправляет в канал сообщение.

Для psycopg версии 3 актуален следующий код для процесса-приёмника, создающий генератор получаемых сообщений (код взят из официальной документации psycopg3):

import psycopg
conn = psycopg.connect("", autocommit=True)
conn.execute("LISTEN mychan")
gen = conn.notifies()
for notify in gen:
    print(notify)
    if notify.payload == "stop":
        gen.close()
print("there, I stopped")

Процесс передатчик:

=# NOTIFY mychan, 'hello';
NOTIFY
=# NOTIFY mychan, 'hey';
NOTIFY
=# NOTIFY mychan, 'stop';
NOTIFY

На выходе процесса приемника:

Notify(channel='mychan', payload='hello', pid=961823)
Notify(channel='mychan', payload='hey', pid=961823)
Notify(channel='mychan', payload='stop', pid=961823)
there, I stopped
→ Ссылка