pg_listen

pg_listen — Set a callback for asynchronous notification messages

Synopsis

pg_listen ?-pid? conn notifyName ?callbackCommand?

Description

pg_listen creates, changes, or cancels a request to listen for asynchronous notification messages from the PostgreSQL server. With a callbackCommand parameter, the request is established, or the command string of an already existing request is replaced. With no callbackCommand parameter, a prior request is canceled.

After a pg_listen request is established, the specified command string is executed whenever a notification message bearing the given name arrives from the server. This occurs when any PostgreSQL client application issues a NOTIFY command referencing that name. The command string is executed from the Tcl idle loop. That is the normal idle state of an application written with Tk. In non-Tk Tcl shells, you can execute update or vwait to cause the idle loop to be entered.

You should not invoke the SQL statements LISTEN or UNLISTEN directly when using pg_listen. pgtcl takes care of issuing those statements for you. But if you want to send a notification message yourself, invoke the SQL NOTIFY statement using pg_exec or a related command.

Arguments

-pid

If present, indicates that the callbackCommand should be given an additional parameter which is the backend process ID (PID) of the client which sent the notification.

conn

The handle of the connection on which to listen for notifications or cancel listening.

notifyName

The name of the notification condition to start or stop listening to. Starting with PostgreSQL-9.0, this is referred to as a channel by the PostgreSQL documentation. This is treated like an SQL name: downcased, unless enclosed in double quotes. (See notes below)

callbackCommand

If present, provides the command string to execute when a matching notification arrives. If absent, an existing command string for matching notification is canceled. The command string should be the name of a Tcl procedure (possibly with leading arguments specified), which accepts an argument for the notifying PID if the -pid option was used, and also accepts an optional additional argument for the notification payload. See the notes below for details.

Return Value

Nothing. Throws a Tcl error if an error occurs.

Notes

The notifyName (or channel) is considered case insensitive unless quoted, for compatibility with way SQL treats the channel name in the SQL NOTIFY command. That is, pg_listen converts the name to lower case, unless it is enclosed in double quotes. If it is in double quotes (which must be protected to get past the Tcl parser, for example as {"MyChannel"}) then the quote marks are stripped and the name is not case folded.

Note: pgtcl-ng always did case folding or quote stripping on notifyName. pgintcl, however, did not do any case folding or quote stripping on the notifyName parameter until after version 3.3.0. For maximum compatibility, use only unquoted lower case values for notifyName and in SQL NOTIFY.

Starting with PostgreSQL-9.0, a notification message can include a payload string. An example of SQL to send a notification with payload is:

NOTIFY my_channel, 'the payload'

The Tcl commands to set up a listener for that condition might look like this:

proc my_listener {{payload ""}} {
    ....
}
pg_listen $db_conn my_channel my_listener

The procedure can be defined to accept additional arguments before the payload, with the fixed arguments supplied in the pg_listen command as a single script argument.

proc my_listener2 {command_arg {payload ""}} {
    ....
}
pg_listen $db_conn my_channel [list my_listener2 Command1]

If the NOTIFY message includes a payload string, Pgtcl will include this as an additional argument to the listener command. If the NOTIFY message does not include a payload string, or includes an empty string as a payload, or you are connected to a pre-9.0.0 PostgreSQL database, then no additional argument will be supplied to the listener command. This is why you need to have an optional argument to your listener command, not a required argument.

Passing a payload string to the notification command was added in pgtclng-1.8.0 and pgintcl-3.2.0, and only works when connected to a PostgreSQL-9.0.0 or higher database server.

Caution

Code written for previous versions of the Pgtcl interfaces should be updated to include an optional argument to all listener callback commands. If you do not update your listener callback command to have an optional argument, and you never include a payload in the notification SQL, your script will not have any problems. However, note that anyone who can connect to the database can send a notification (if they know the channel name used in the pg_listen command), and they can include a payload. If your listener callback does not expect a payload argument, it will throw a background error (which may or may not terminate the script) if it receives such a payload argument.

The -pid option was added in pgtclng-2.0.0 and pgintcl-3.4.0. It may be useful, for example, to compare with the connection's own backend process id (see pg_backend_pid to ignore notifications coming from the client itself. See the example below.

Example

In this partial example, a notification handler accepts a PID argument and compares it with the client's own backend PID to ignore notifications from the client itself.

proc my_handler {backend_pid notifier_pid {payload ""}} {
    # Ignore notifications from ourself:
    if {$backend_pid == $notifier_pid} return
    ... continue processing ...
} 
# Establish a listener, with notifying PID argument.
# Include our backend PID as a command argument.
pg_listen -pid $db_conn my_channel [list my_handler [pg_backend_pid $db_conn]]

SourceForge.net Logo

This version of the manual was produced for the Pgtcl-ng Sourceforge project web service site, which requires the logo on each page.

To download a logo-free copy of the manual, see the Pgtcl-ng project downloads area.