27.7. Notificação assíncrona

O PostgreSQL disponibiliza notificação assíncrona através dos comandos LISTEN e NOTIFY. A sessão cliente registra seu interesse por uma determinada notificação através do comando LISTEN (e pára de ouvir através do comando UNLISTEN). Todas as sessões ouvindo uma determinada condição são notificadas assincronamente quando o comando NOTIFY, com este nome de condição, é executado por qualquer sessão. Não é passada nenhuma informação adicional para quem ouve. Portanto, qualquer dado que precise ser comunicado é transferido, usualmente, através de uma tabela do banco de dados. Normalmente, o nome da condição é o mesmo da tabela associada, mas não é necessário que haja nenhuma tabela associada.

Os aplicativos da libpq submetem os comandos LISTEN e UNLISTEN como comandos SQL comuns. A chegada das mensagens NOTIFY podem ser detectadas em seguida chamando a função PQnotifies.

A função PQnotifies retorna a próxima notificação de uma lista de mensagens de notificação não tratadas recebidas do servidor. Retorna um ponteiro nulo caso não haja mais notificações pendentes. Uma vez que a notificação seja retornada pela função PQnotifies, esta é considerada tratada e removida da lista de notificações.

PGnotify *PQnotifies(PGconn *conn);

typedef struct pgNotify {
    char *relname;              /* nome da condição de notificação */
    int  be_pid;                /* ID de processo do processo servidor */
    char *extra;                /* parâmetro de notificação */
} PGnotify;

Após processar um objeto PGnotify retornado por PQnotifies, deve-se ter certeza que este é liberado através de PQfreemem. É suficiente liberar o ponteiro para PGnotify; os campos relname e extra não representam alocações separadas (No momento, o campo extra não é utilizado e sempre aponta para uma cadeia de caracteres vazia).

Nota: No PostgreSQL 6.4 e posteriores, o campo be_pid é relativo ao processo servidor fazendo a notificação, enquanto nas versões anteriores era sempre o PID do próprio processo servidor.

O Exemplo 27-2 mostra um programa exemplo que demonstra a utilização da notificação assíncrona.

Na verdade, a função PQnotifies não lê os dados do servidor; apenas retorna as mensagens previamente absorvidas por outra função da libpq. Nas versões anteriores da libpq, a única maneira de garantir a recepção a tempo das mensagens de NOTIFY era submetendo comandos constantemente, mesmo vazios, e depois verificando PQnotifies após cada PQexec. Embora isto ainda funcione, está em obsolescência e é um desperdício de poder de processamento.

Uma maneira melhor de verificar as mensagens de NOTIFY, quando não há comando útil a ser executado, é chamar PQconsumeInput e depois verificar PQnotifies. Pode ser utilizada a função select() para aguardar os dados chegarem do servidor, portanto usando ciclos da CPU a menos que haja algo a ser feito (Deve ser vista a função PQsocket para obter o número do descritor do arquivo a ser utilizado com a função select()). Deve ser observado que funciona bem se forem submetidos comandos através de PQsendQuery/PQgetResult, ou simplesmente utilizada a função PQexec. Entretanto, não se deve esquecer de verificar PQnotifies após cada PQgetResult ou PQexec, para ver se chegou alguma notificação durante o processamento do comando.

SourceForge.net Logo CSS válido!