PostgreSQL propose des notifications asynchrones via
les commandes LISTEN et NOTIFY. Une
session cliente enregistre son intérêt dans un canal particulier avec
la commande LISTEN (et peut arrêter son écoute avec la
commande UNLISTEN). Toutes les sessions écoutant un
canal particulier seront notifiées de façon asynchrone lorsqu'une commande
NOTIFY avec ce nom de canal sera exécutée par une
session. Une chaîne de « charge » peut être renseignée pour fournir
des données supplémentaires aux processus en écoute.
Les applications libpq soumettent les commandes
LISTEN, UNLISTEN et NOTIFY
comme des commandes
SQL ordinaires. L'arrivée des messages NOTIFY peut être
détectée ensuite en appelant
PQnotifies.
La fonction PQnotifies renvoie la prochaine notification à
partir d'une liste de messages de notification non gérés reçus à partir du
serveur. Il renvoie un pointeur NULL s'il n'existe pas de notification en
attente. Une fois qu'une notification est renvoyée à partir de
PQnotifies, elle est considérée comme étant gérée et sera supprimée
de la liste des notifications.
PGnotify* PQnotifies(PGconn *conn);
typedef struct pgNotify
{
char *relname; /* nom du canal de la notification */
int be_pid; /* ID du processus serveur notifiant */
char *extra; /* chaîne de charge pour la notification */
} PGnotify;
Après avoir traité un objet PGnotify renvoyé par
PQnotifies, assurez-vous de libérer le pointeur
PQfreemem. Il est suffisant de libérer le pointeur
PGnotify ; les champs
relname et extra ne
représentent pas des allocations séparées
(le nom de ces champs est historique ; en particulier, les noms des
canaux n'ont pas besoin d'être liés aux noms des relations.)
Exemple 34.2 donne un programme d'exemple illustrant l'utilisation d'une notification asynchrone.
PQnotifies ne lit pas réellement les données à partir du
serveur ; il renvoie simplement les messages précédemment absorbés par une
autre fonction de libpq. Dans les anciennes
versions de libpq, la seule façon de s'assurer une
réception à temps des messages NOTIFY consistait à soumettre
constamment des commandes de soumission, même vides, puis de vérifier
PQnotifies après chaque PQexec. Bien
que ceci fonctionnait, cela a été abandonné car un gaspillage de ressources.
Une meilleure façon de vérifier les messages NOTIFY lorsque vous
n'avez pas de commandes utiles à exécuter est d'appeler
PQconsumeInput puis de vérifier
PQnotifies. Vous pouvez utiliser
select() pour attendre l'arrivée des données à partir du
serveur, donc sans utiliser de CPU sauf
lorsqu'il y a quelque chose à faire (voir PQsocket pour
obtenir le numéro du descripteur de fichiers à utiliser avec
select()). Notez que ceci fonctionnera que vous
soumettiez les commandes avec
PQsendQuery/PQgetResult ou que vous
utilisiez simplement PQexec. Néanmoins, vous devriez vous
rappeler de vérifier PQnotifies après chaque
PQgetResult ou PQexec pour savoir si
des notifications sont arrivées pendant le traitement de la commande.