Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7900269

Browse files
committed
Stabilize NOTIFY behavior by transmitting notifies before ReadyForQuery.
This patch ensures that, if any notify messages were received during a just-finished transaction, they get sent to the frontend just before not just after the ReadyForQuery message. With libpq and other client libraries that act similarly, this guarantees that the client will see the notify messages as available as soon as it thinks the transaction is done. This probably makes no difference in practice, since in realistic use-cases the application would have to cope with asynchronous arrival of notify events anyhow. However, it makes it a lot easier to build cross-session-notify test cases with stable behavior. I'm a bit surprised now that we've not seen any buildfarm instability with the test cases added by commit b10f40b. Tests that I intend to add in an upcoming bug fix are definitely unstable without this. Back-patch to 9.6, which is as far back as we can do NOTIFY testing with the isolationtester infrastructure. Discussion: https://postgr.es/m/13881.1574557302@sss.pgh.pa.us
1 parent 8b7ae5a commit 7900269

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

src/backend/commands/async.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -1885,11 +1885,13 @@ HandleNotifyInterrupt(void)
18851885
/*
18861886
* ProcessNotifyInterrupt
18871887
*
1888-
* This is called just after waiting for a frontend command. If a
1889-
* interrupt arrives (via HandleNotifyInterrupt()) while reading, the
1890-
* read will be interrupted via the process's latch, and this routine
1891-
* will get called. If we are truly idle (ie, *not* inside a transaction
1892-
* block), process the incoming notifies.
1888+
* This is called if we see notifyInterruptPending set, just before
1889+
* transmitting ReadyForQuery at the end of a frontend command, and
1890+
* also if a notify signal occurs while reading from the frontend.
1891+
* HandleNotifyInterrupt() will cause the read to be interrupted
1892+
* via the process's latch, and this routine will get called.
1893+
* If we are truly idle (ie, *not* inside a transaction block),
1894+
* process the incoming notifies.
18931895
*/
18941896
void
18951897
ProcessNotifyInterrupt(void)

src/backend/tcop/postgres.c

+11
Original file line numberDiff line numberDiff line change
@@ -4194,7 +4194,18 @@ PostgresMain(int argc, char *argv[],
41944194
}
41954195
else
41964196
{
4197+
/* Send out notify signals and transmit self-notifies */
41974198
ProcessCompletedNotifies();
4199+
4200+
/*
4201+
* Also process incoming notifies, if any. This is mostly to
4202+
* ensure stable behavior in tests: if any notifies were
4203+
* received during the just-finished transaction, they'll be
4204+
* seen by the client before ReadyForQuery is.
4205+
*/
4206+
if (notifyInterruptPending)
4207+
ProcessNotifyInterrupt();
4208+
41984209
pgstat_report_stat(false);
41994210

42004211
set_ps_display("idle", false);

0 commit comments

Comments
 (0)