diff --git a/doc/src/sgml/ref/listen.sgml b/doc/src/sgml/ref/listen.sgml index 10a4ef38b1e20f19e46811a32400740e38989fb1..97cb349a89072ea16b75a88d8563e8953f6e1486 100644 --- a/doc/src/sgml/ref/listen.sgml +++ b/doc/src/sgml/ref/listen.sgml @@ -10,20 +10,20 @@ LISTEN LISTEN </REFNAME> <REFPURPOSE> -Listen for notification on a relation +Listen for notification on a notify condition </REFPURPOSE> <REFSYNOPSISDIV> <REFSYNOPSISDIVINFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSYNOPSISDIVINFO> <SYNOPSIS> -LISTEN <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE> +LISTEN <REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> </SYNOPSIS> <REFSECT2 ID="R2-SQL-LISTEN-1"> <REFSECT2INFO> -<DATE>1998-09-01</DATE> +<DATE>1998-10-07</DATE> </REFSECT2INFO> <TITLE> Inputs @@ -33,11 +33,11 @@ Inputs <VARIABLELIST> <VARLISTENTRY> <TERM> -<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE> +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> </TERM> <LISTITEM> <PARA> -Table object used for notification. +Name of notify condition. </VARIABLELIST> @@ -62,63 +62,95 @@ Outputs <VARIABLELIST> <VARLISTENTRY> <TERM> -LISTEN +<returnvalue>LISTEN</returnvalue> </TERM> <LISTITEM> <PARA> Message returned upon successful completion of registration. - -</VARIABLELIST> +</PARA> +</LISTITEM> +</VARLISTENTRY> +<VARLISTENTRY> +<TERM> +<returnvalue>NOTICE Async_Listen: We are already listening on notifyname</returnvalue> +</TERM> +<LISTITEM> +<PARA> +If this backend is already registered for that notify condition. +</PARA> +</LISTITEM> +</VARLISTENTRY> +</variablelist> +</LISTITEM> +</VARLISTENTRY> </VARIABLELIST> - </REFSECT2> </REFSYNOPSISDIV> <REFSECT1 ID="R1-SQL-LISTEN-1"> <REFSECT1INFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSECT1INFO> <TITLE> Description </TITLE> <PARA> -LISTEN is used to register the current backend as a listener on the relation -<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>. -When the command -<command>NOTIFY <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE></command> -is called either from within a rule or at the query level, the -frontend applications corresponding to the listening backends -are notified. When the backend process exits, this registration -is cleared. +LISTEN registers the current <productname>Postgres</productname> backend as a +listener on the notify condition +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>. + +<para> +Whenever the command +<command>NOTIFY <REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE></command> +is invoked, either by this backend or another one connected to +the same database, all the backends currently listening on that notify +condition are notified, and each will in turn notify its connected +frontend application. See the discussion of <command>NOTIFY</command> +for more information. <para> -This event notification is performed through the libpq protocol -and frontend application interface. The application program -must call the routine -<function>PQnotifies</function> -in order to find out the name of the class to which a given -notification corresponds. If this code is not included in -the application, the event notification will be queued and -never be processed. +A backend can be deregistered for a given notify condition with the +<command>UNLISTEN</command> command. Also, a backend's listen registrations +are automatically cleared when the backend process exits. + +<para> +The method a frontend application must use to detect notify events depends on +which <productname>Postgres</productname> application programming interface it +uses. With the basic libpq library, the application issues +<command>LISTEN</command> as an ordinary SQL command, and then must +periodically call the routine <function>PQnotifies</function> to find out +whether any notify events have been received. Other interfaces such as +libpgtcl provide higher-level methods for handling notify events; indeed, +with libpgtcl the application programmer should not even issue +<command>LISTEN</command> or <command>UNLISTEN</command> directly. See the +documentation for the library you are using for more details. + +<para> +The reference page for <command>NOTIFY</command> contains a more extensive +discussion of the use of <command>LISTEN</command> and +<command>NOTIFY</command>. <REFSECT2 ID="R2-SQL-LISTEN-3"> <REFSECT2INFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSECT2INFO> <TITLE> Notes </TITLE> <para> -Note that <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE> -needs not to be a valid class name but can be any string valid - as a name up to 32 characters long. +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> +can be any string valid as a name; +it need not correspond to the name of any actual table. If +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> +is enclosed in double-quotes, it need not even be a syntactically +valid name, but can be any string up to 31 characters long. <para> -A restriction in some previous releases of - <productname>Postgres</productname> that a -<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE> -which does not correspond to an actual table must be enclosed in double-quotes -is no longer present. +In some previous releases of +<productname>Postgres</productname>, +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> +had to be enclosed in double-quotes when it did not correspond to any existing +table name, even if syntactically valid as a name. That is no longer required. </REFSECT2> @@ -128,6 +160,7 @@ Usage </TITLE> <PARA> <ProgramListing> +-- Configure and execute a listen/notify sequence from psql postgres=> listen virtual; LISTEN postgres=> notify virtual; diff --git a/doc/src/sgml/ref/notify.sgml b/doc/src/sgml/ref/notify.sgml index f88ac45c28f77386b2e4b4818431289c6b5a5f85..92310c0d8ce82e727639c56f27dfb1ecf74c797b 100644 --- a/doc/src/sgml/ref/notify.sgml +++ b/doc/src/sgml/ref/notify.sgml @@ -10,22 +10,22 @@ NOTIFY NOTIFY </REFNAME> <REFPURPOSE> -Signals all frontends and backends listening on a class +Signals all frontends and backends listening on a notify condition </REFPURPOSE> <REFSYNOPSISDIV> <REFSYNOPSISDIVINFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSYNOPSISDIVINFO> <SYNOPSIS> <REPLACEABLE CLASS="PARAMETER"> </REPLACEABLE> -NOTIFY <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE> +NOTIFY <REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> </SYNOPSIS> <REFSECT2 ID="R2-SQL-NOTIFY-1"> <REFSECT2INFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSECT2INFO> <TITLE> Inputs @@ -35,11 +35,11 @@ Inputs <VARIABLELIST> <VARLISTENTRY> <TERM> -<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE> +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> </TERM> <LISTITEM> <PARA> -Table or arbitrary relation class used for notification. +Notify condition to be signaled. </VARIABLELIST> @@ -47,7 +47,7 @@ Table or arbitrary relation class used for notification. <REFSECT2 ID="R2-SQL-NOTIFY-2"> <REFSECT2INFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSECT2INFO> <TITLE> Outputs @@ -69,66 +69,141 @@ NOTIFY </TERM> <LISTITEM> <PARA> -Notification message from backend. - -</VARIABLELIST> +Acknowledgement that notify command has executed. +</PARA> +</LISTITEM> +</VARLISTENTRY> +<VARLISTENTRY> +<TERM> +Notify events +</TERM> +<LISTITEM> +<PARA> +Events are delivered to listening frontends; whether and how each frontend +application reacts depends on its programming. +</PARA> +</LISTITEM> +</VARLISTENTRY> +</variablelist> +</LISTITEM> +</VARLISTENTRY> </VARIABLELIST> - </REFSECT2> </REFSYNOPSISDIV> <REFSECT1 ID="R1-SQL-NOTIFY-1"> <REFSECT1INFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSECT1INFO> <TITLE> Description </TITLE> <PARA> - <command>NOTIFY</command> is used to awaken all sessions which have -previously executed - <command>LISTEN <replaceable class="parameter">classname</replaceable></command>. - This can be used either within an instance-level rule -as part of the action body or from a normal query. +The <command>NOTIFY</command> command sends a notify event to each +frontend application that has previously executed +<command>LISTEN <replaceable class="parameter">notifyname</replaceable></command> +for the specified notify condition in the current database. <para> - When used from within a normal query, -this can be thought of as interprocess communication (IPC). When -used from within a rule, this can be thought of as an alert mechanism. +The information passed to the frontend for a notify event includes the notify +condition name and the notifying backend process's PID. It is up to the +database designer to define the condition names that will be used in a given +database and what each one means. + <para> - Note that the mere fact that a <command>NOTIFY</command> has been - executed does not imply anything in particular about the state - of the class (e.g., that it has been updated), - nor does the notification protocol transmit any useful information - other than the class name. -Therefore, all <command>NOTIFY</command> does is indicate that some backend - wishes its peers to - examine <replaceable class="parameter">classname</replaceable> - in some application-specific way. +Commonly, the notify condition name is the same as the name of some table in +the database, and the notify event essentially means "I changed this table, +take a look at it to see what's new". But no such association is enforced by +the <command>NOTIFY</command> and <command>LISTEN</command> commands. For +example, a database designer could use several different condition names +to signal different sorts of changes to a single table. + <para> - In fact, <replaceable class="parameter">classname</replaceable> - need not be the name of an SQL class at all. - It is best thought of as a condition name - that the application programmer selects. +<command>NOTIFY</command> provides a simple form of signal or +IPC (interprocess communication) mechanism for a collection of processes +accessing the same <productname>Postgres</productname> database. +Higher-level mechanisms can be built by using tables in the database to +pass additional data (beyond a mere condition name) from notifier to +listener(s). + <para> - This event notification is performed through the libpq protocol - and frontend application interface. The application program - must call the routine <function>PQnotifies</function> - in order to find out the name of the class to which a given - notification corresponds. -If this code is not included in the application, -the event notification will be - queued and never be processed. - +When <command>NOTIFY</command> is used to signal the occurrence of changes +to a particular table, a useful programming technique is to put the +<command>NOTIFY</command> in a rule that is triggered by table updates. +In this way, notification happens automatically when the table is changed, +and the application programmer can't accidentally forget to do it. + +<para> +<command>NOTIFY</command> interacts with SQL transactions in some important +ways. Firstly, if a <command>NOTIFY</command> is executed inside a +transaction, the notify events are not delivered until and unless the +transaction is committed. This is appropriate, since if the transaction +is aborted we would like all the commands within it to have had no effect +--- including <command>NOTIFY</command>. But it can be disconcerting if one +is expecting the notify events to be delivered immediately. Secondly, if +a listening backend receives a notify signal while it is within a transaction, +the notify event will not be delivered to its connected frontend until just +after the transaction is completed (either committed or aborted). Again, the +reasoning is that if a notify were delivered within a transaction that was +later aborted, one would want the notification to be undone somehow --- but +the backend cannot "take back" a notify once it has sent it to the frontend. +So notify events are delivered only between transactions. The upshot of this +is that applications using <command>NOTIFY</command> for real-time signaling +should try to keep their transactions short. + +<para> +<command>NOTIFY</command> behaves rather like Unix signals in one important +respect: if the same notify name is signaled multiple times in quick +succession, recipients may get only one notify event for several executions +of <command>NOTIFY</command>. So it is a bad idea to depend on the number +of notifies received; instead use <command>NOTIFY</command> to wake up +applications that need to pay attention to something, and use a database +object (such as a sequence) to keep track of what happened or how many times +it happened. + +<para> +It is common for a frontend that sends <command>NOTIFY</command> to be +listening on the same notify name itself. In that case it will get back a +notify event, just like all the other listening frontends. Depending on the +application logic, this could result in useless work --- for example, +re-reading a database table to find the same updates that that frontend just +wrote out. In <productname>Postgres</productname> 6.4 and later, it is +possible to avoid such extra work by noticing whether the notifying backend +process's PID (supplied in the notify event message) is the same as one's own +backend's PID (available from libpq). When they are the same, the notify +event is one's own work bouncing back, and can be ignored. (Despite what was +said in the preceding paragraph, this is a safe technique. +<productname>Postgres</productname> keeps self-notifies separate from notifies +arriving from other backends, so you cannot miss an outside notify by ignoring +your own notifies.) + <REFSECT2 ID="R2-SQL-NOTIFY-3"> <REFSECT2INFO> -<DATE>1998-09-24</DATE> +<DATE>1998-10-07</DATE> </REFSECT2INFO> <TITLE> Notes </TITLE> -<PARA> -</PARA> +<para> +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> +can be any string valid as a name; +it need not correspond to the name of any actual table. If +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> +is enclosed in double-quotes, it need not even be a syntactically +valid name, but can be any string up to 31 characters long. + +<para> +In some previous releases of +<productname>Postgres</productname>, +<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE> +had to be enclosed in double-quotes when it did not correspond to any existing +table name, even if syntactically valid as a name. That is no longer required. + +<para> +In <productname>Postgres</productname> releases prior to 6.4, the backend +PID delivered in a notify message is always the PID of the frontend's own +backend. So it is not possible to distinguish one's own notifies from other +clients' notifies in those earlier releases. </REFSECT2> @@ -137,19 +212,13 @@ Notes Usage </TITLE> <PARA> -</PARA> <ProgramListing> --- Configure and execute a listen/notify sequence --- from psql -CREATE TABLE t (i int4); -<computeroutput> -LISTEN t; -</computeroutput> -NOTIFY t; -<computeroutput> +-- Configure and execute a listen/notify sequence from psql +postgres=> listen virtual; +LISTEN +postgres=> notify virtual; NOTIFY -ASYNC NOTIFY of 't' from backend pid '10949' received -</computeroutput> +ASYNC NOTIFY of 'virtual' from backend pid '11239' received </ProgramListing> </REFSECT1>