| « Compensa aprender python? | Rails Rally: Apertem os cintos, o piloto sumiu » |
Armadilha no LISTEN e NOTIFY (PostgreSQL)
Tradução do texto de Greg Sabino Mullane em seu blog.
O tÃtulo original é LISTEN AND NOTIFY gotcha. Resolvi traduzir gotcha como armadilha. Primeiro, a definição de gotcha da wikipedia:
Em programação, um gotcha é uma caracterÃstica de um sistema, um programa, ou uma linguagem de programação que funciona da forma como está documentado mas é contra-intuitivo e quase sempre propÃcia à erro porque é fácil de usar e impredizÃvel em seu resultado.
Existe um problema sutil com os comandos LISTEN e NOTIFY. Enquanto o nome que você atribui no comando LISTEN parece um texto comum, ele é na verdade aquilo que é chamado de "nome" no PostgreSQL, que significa que está sujeito às mesmas estranhas regras e comportamento. Eu pessoalmente adoraria ver isso mudado de uma nome de relação para uma string normal, mas até que isso ocorra, seja cuidadoso com a forma que você usa essa dupla. Aqui está um exemplo de uso comum:
$ LISTEN employee; LISTEN $ NOTIFY employee; NOTIFY Asynchronous notification "employee" received from server process with PID 8875.
No exemplo acima, nós começamos a ouvir por evemtos com o nome "employee", então disparamos um NOTIFY com o mesmo nome e obtemos uma notificação imediata sobre isso. Porém, como o nome está sujeito a todas as regras de nomes de relações, existem outros problemas:
$ LISTEN host;
LISTEN
$ LISTEN user;
ERROR: syntax error at or near "user"
LINE 1: listen user;
^
$ LISTEN "user";
LISTEN
$ SELECT * FROM pg_listener;
relname | listenerpid | notification
----------+-------------+--------------
employee | 8875 | 0
user | 8875 | 0
host | 8875 | 0
(3 rows)
$ NOTIFY user;
ERROR: syntax error at or near "user"
LINE 1: listen user;
^
$ NOTIFY "user";
NOTIFY
Asynchronous notification "employee" received from server process with PID 8875.
Observe que precisamos colocar a palavra "user" entre aspas, pois a palavra user não é válida como um nome de relação sem aspas. Agora note que a tabela pg_listener não nos dá nenhuma dica que isso precisa estar entre aspas. O problema real acontece quando adicionamos pontos ao nosso "nome". O Postgres trata isso como uma sequência de esquema, tabela, e coluna e remove tudo, exceto a parte final do nome:
$ LISTEN newyork.employee; LISTEN $ NOTIFY newyork.emplyee; NOTIFY Asynchronous notification "employee" received from server process with PID 8875. $ NOTIFY losangeles.employee; NOTIFY Asynchronous notification "employee" received from server process with PID 8875. $ NOTIFY elephants.makeagood.employee; NOTIFY Asynchronous notification "employee" received from server process with PID 8875. $ LISTEN thisworks.forunquoted.user; LISTEN $ LISTEN cannot.handle.three.dots; ERROR: improper qualified name (too many dotted names): cannot.handle.three.dots
Eu enviei uma correção para a documentação, mas tome cuidado, principalmente se você escreve código que gera nomes automáticos para os seus argumentos LISTEN.
Endereço de trackback para este post
Trackback URL (clique direito e copie atalho/localização do link)
2 comentários

Eu não sei o que são esses comandos e gostaria de lê-la para saber.

Até mais.
