Как из одного процесса сообщить в другой о том что закончена обработка группы таблиц
Есть исходная таблица, назовем ее table_source
. Эта таблица каким-то образом (для нашей задачи неважно каким) периодически обновляется, периоды обновления условно случайны. У каждой записи в таблице есть уникальное поле - идентификатор (пусть будет id
) и несколько полей с данными (data_1
, data_2
,..). Каждое обновление может добавить новые данные (т.е., после обновления будут как старые идентификаторы, так и новые), а может их полностью заменить (после обновления будут только новые идентификаторы).
А также есть два процесса (скрипты на Python), которые обрабатывают эти данные.
Первый процесс
У него есть несколько функций, каждая из которых обрабатывает данные из таблицы-источника и каждая из функций возвращает несколько результатов. Все результаты работы каждой функции записываются в отдельную таблицу. Работа первого процесса выглядит приблизительно так:
- Ждем когда обновятся данные в источнике
- Вычисляем функцию_1
- Результаты функции_1 записываем в таблица_результаты_1 вместе с идентификаторами
- Вычисляем функцию_2
- Результаты функции_2 записываем в таблица_результаты_2 вместе с идентификаторами
- Повторяем по количеству функций
- Переходим к п. 1
Каждая функция работает от нескольких секунд до нескольких минут.
Второй процесс
Должен выполнять следующее - как только данные во всех таблицах обновятся собрать все данные с помощью JOIN
в единую таблицу. И потом ее всю обрабатывает.
Вопрос
Как передать информацию от первого процесса ко второму об окончании вычислений и полному обновлению всех таблиц правильно/оптимально/быстро/просто - любые варианты подходят.
Я предполагаю общаться через файловую систему. После окончания обработки новых данных первый процесс выкладывает файл-флаг, второй его ждет и как дождется - собирает таблицы.
Можно, конечно, периодически получать идентификаторы из всех таблиц и сравнивать, но это как-то громоздко.
Но может есть какие-то более оптимальные способы в SQL? Или еще как? Мне этот вопрос интересен и с практической и с исследовательской точек зрения, для самообразования.
Не знаю какие тэги поставить, если что - поправьте
Ответы (1 шт):
Особая благодарность 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