31.9. Асинхронное уведомление#
31.9. Асинхронное уведомление #
Tantor BE предлагает асинхронное уведомление
с помощью команд LISTEN
и NOTIFY
.
Клиентская сессия регистрирует свой интерес к определенному
каналу уведомлений с помощью команды LISTEN
(и
может прекратить прослушивание с помощью команды UNLISTEN
).
Все сессии, прослушивающие определенный канал, будут уведомлены
асинхронно, когда команда NOTIFY
с указанным
именем канала будет выполнена любой сессией. Строка “payload” может
быть передана для передачи дополнительных данных слушателям.
libpq приложения отправляют
команды LISTEN
, UNLISTEN
и NOTIFY
как
обычные SQL команды. Поступление сообщений NOTIFY
может быть обнаружено впоследствии вызовом
PQnotifies
.
Функция PQnotifies
возвращает следующее уведомление из списка необработанных уведомлений, полученных от сервера. Если нет ожидающих уведомлений, функция возвращает нулевой указатель. После возврата уведомления из PQnotifies
оно считается обработанным и будет удалено из списка уведомлений.
PGnotify *PQnotifies(PGconn *conn); typedef struct pgNotify { char *relname; /* notification channel name */ int be_pid; /* process ID of notifying server process */ char *extra; /* notification payload string */ } PGnotify;
После обработки объекта PGnotify
, возвращаемого функцией PQnotifies
, обязательно освободите его с помощью PQfreemem
. Достаточно освободить указатель PGnotify
; поля relname
и extra
не представляют отдельных выделений памяти. (Названия этих полей исторические; в частности, имена каналов не обязательно должны иметь отношение к именам отношений).
Пример 31.2 предоставляет пример программы, иллюстрирующей использование асинхронного уведомления.
PQnotifies
на самом деле не считывает данные с сервера; он просто возвращает сообщения, ранее полученные другой функцией libpq. В древних версиях libpq единственным способом гарантировать своевременное получение сообщений NOTIFY
было постоянно отправлять команды, даже пустые, а затем проверять PQnotifies
после каждого PQexec
. Хотя это все еще работает, это устарело как пустая трата вычислительной мощности.
Лучший способ проверить сообщения NOTIFY
, когда у вас нет полезных команд для выполнения, - вызвать PQconsumeInput
, а затем проверить PQnotifies
. Вы можете использовать select()
, чтобы ожидать поступления данных от сервера, тем самым не используя CPU до тех пор, пока не будет что-то делать. (См. PQsocket
, чтобы получить номер файлового дескриптора для использования с select()
). Обратите внимание, что это будет работать нормально, независимо от того, отправляете ли вы команды с помощью PQsendQuery
/PQgetResult
или просто используете PQexec
. Однако, после каждого PQgetResult
или PQexec
, вы должны проверить PQnotifies
, чтобы увидеть, поступили ли какие-либо уведомления во время обработки команды.