PostgreSQL soporta notificación asíncrona a través de los comandos LISTEN y NOTIFY. Un servidor registra su interés en una condición de notificación particular con el comando LISTEN (y puede dejar de escuchar con el comando UNLISTEN). Todos los servidores que están escuchando una condición de notificación particular recibirán la notificación asíncronamente cuando cualquier servidor ejecute un NOTIFY de ese nombre de condición. El servidor que realiza la notificación no pasará ninguna otra información particular a los servidores que están escuchando. Por ello, cualquier dato que deba ser comunicado se transfiere habitualmente a través de una relación de base de datos. También habitualmente el nombre de la condición es el mismo de la relación asociada, pero no sólo no es necesario, sino que tampoco lo es que exista ninguna relación asociada.
Las aplicaciones libpq emiten los comandos LISTEN y UNLISTEN como consultas SQL ordinarias. Subsiguientemenet, la llegada de mensajes NOTIFY se puede detectar llamando a PQnotifies().
PQnotifies Devuelve la siguiente noficación de una lista de mensajes de notificación aún no manipulados recibidos desde el servidor. Devuelve NULL si no hay notificaciones pendientes. Una vez se devuelve una notificación con PQnotifies, esta se considera manipulada y se borrará de la lista de notificaciones.
PGnotify* PQnotifies(PGconn *conn); typedef struct PGnotify { char relname[NAMEDATALEN]; /* nombre de la relación */ /* que contiene los datos */ int be_pid; /* identificador del proceso servidor */ } PGnotify; |
En PostgreSQL 6.4 y posteriores, el be_pid corresponde al servidor que realiza la notificación, mientras que en versiones anteriores era siempre el PID del propio servidor. |
La segunda muestra de programa da un ejemplo del uso de la notificación asíncrona.
PQnotifies() actualmente no lee datos del servidor; únicamente devuelve mensajes previamente absorvidos por otra función libpq. En versiones previas de libpq, la única forma de asegurar la recepción a tiempo de mensajes NOTIFY era emitir constantemente consultas, incluso vacías, y comprobar entonces PQnotifies() tras cada PQexec(). Aunque esto funcionaba, se menospreciaba como una forma de malgastar poder de proceso.
Una forma mejor de comprobar los mensajes NOTIFY cuando no se dispone de consultas utilizables es hacer una llamada PQconsumeInput(), y comprobar entonces PQnotifies(). Se puede usar select(2) para esperar la llegada de datos del servidor, no utilizando en este caso potencia de CPU a menos que se tenga algo que hacer. Nótese que esta forma funcionará correctamente mientras utilice usted PQsendQuery/PQgetResult o símplemente PQexec para las consultas. Debería usted, sin embargo, recordar comprobar PQnotifies() tras cada PQgetResult o PQexec para comprobar si ha llegado alguna notificación durante el procesado de la consulta.