From ecc59e31a81e34f4e6c0d9e73d8992d13f12b051 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 19 Oct 2018 22:22:57 -0400 Subject: Client-side fixes for delayed NOTIFY receipt. PQnotifies() is defined to just process already-read data, not try to read any more from the socket. (This is a debatable decision, perhaps, but I'm hesitant to change longstanding library behavior.) The documentation has long recommended calling PQconsumeInput() before PQnotifies() to ensure that any already-arrived message would get absorbed and processed. However, psql did not get that memo, which explains why it's not very reliable about reporting notifications promptly. Also, most (not quite all) callers called PQconsumeInput() just once before a PQnotifies() loop. Taking this recommendation seriously implies that we should do PQconsumeInput() before each call. This is more important now that we have "payload" strings in notification messages than it was before; that increases the probability of having more than one packet's worth of notify messages. Hence, adjust code as well as documentation examples to do it like that. Back-patch to 9.5 to match related server fixes. In principle we could probably go back further with these changes, but given lack of field complaints I doubt it's worthwhile. Discussion: https://postgr.es/m/CAOYf6ec-TmRYjKBXLLaGaB-jrd=mjG1Hzn1a1wufUAR39PQYhw@mail.gmail.com --- src/interfaces/ecpg/ecpglib/execute.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/interfaces/ecpg/ecpglib/execute.c') diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 9a6dde44de9..6f20cc412a2 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -1729,12 +1729,13 @@ ecpg_process_output(struct statement *stmt, bool clear_result) } /* check for asynchronous returns */ - notify = PQnotifies(stmt->connection->connection); - if (notify) + PQconsumeInput(stmt->connection->connection); + while ((notify = PQnotifies(stmt->connection->connection)) != NULL) { ecpg_log("ecpg_process_output on line %d: asynchronous notification of \"%s\" from backend PID %d received\n", stmt->lineno, notify->relname, notify->be_pid); PQfreemem(notify); + PQconsumeInput(stmt->connection->connection); } return status; -- cgit v1.2.3