29.7. Notification asynchrone
PostgreSQL™ propose des
notifications asynchrone via les commandes
LISTEN
et
NOTIFY
. Une session cliente
enregistre son intérêt dans une notification particulière avec la
commande
LISTEN
(et
peut arrêter son écoute avec la commande
UNLISTEN
). Toutes les sessions
écoutant une condition particulière seront notifiées de façon
asynchrone lorsqu'une commande
NOTIFY
avec ce nom de condition
sera exécutée par une session. Aucune autre information n'est passée
du notifieur au notifié. Du coup, typiquement, toute donnée qui a
besoin d'être communiquée est transférée via une table de la base.
D'habitude, le nom de la condition est identique à la table associée
mais il n'est pas nécessaire d'avoir une table associée.
Les applications libpq soumettent
les commandes
LISTEN
et
UNLISTEN
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 nul s'il
n'existe pas de notifications 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 de la condition de la notification */
int be_pid; /* ID du processus serveur notifiant */
char *extra; /* paramètre de 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 (actuellement, le champ
extra
est inutilisé et pointera en
permanence vers une chaîne vide).
Exemple 29.2,
« Deuxième exemple de programme pour libpq » 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 précédentes 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é à cause de la perte de puissance.
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 en utilisant aucune puissance du 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 bien que vous
soumettez les commandes avec PQsendQuery/PQgetResult ou
que vous utilisez 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 lors du traitement de la
commande.