]> granicus.if.org Git - postgresql/commitdiff
LISTEN/NOTIFY doc improvements.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 8 Oct 1998 00:18:31 +0000 (00:18 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 8 Oct 1998 00:18:31 +0000 (00:18 +0000)
doc/src/sgml/ref/listen.sgml
doc/src/sgml/ref/notify.sgml

index 10a4ef38b1e20f19e46811a32400740e38989fb1..97cb349a89072ea16b75a88d8563e8953f6e1486 100644 (file)
@@ -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;
index f88ac45c28f77386b2e4b4818431289c6b5a5f85..92310c0d8ce82e727639c56f27dfb1ecf74c797b 100644 (file)
@@ -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>