untriggered-notification.patch.nocfbot
application/octet-stream
Filename: untriggered-notification.patch.nocfbot
Type: application/octet-stream
Part: 0
From e7c6913c1e392e6a41e4f1886897cdbb479f7254 Mon Sep 17 00:00:00 2001
From: Arseniy Mukhin <arseniy.mukhin.dev@gmail.com>
Date: Wed, 20 May 2026 12:45:54 +0300
Subject: [PATCH] LISTEN/NOTIFY test - untriggered notification
---
src/backend/commands/async.c | 2 +
src/test/modules/injection_points/Makefile | 3 +-
...notify-listen-untriggered-notification.out | 45 ++++++++++++++
src/test/modules/injection_points/meson.build | 1 +
...otify-listen-untriggered-notification.spec | 60 +++++++++++++++++++
5 files changed, 110 insertions(+), 1 deletion(-)
create mode 100644 src/test/modules/injection_points/expected/async-notify-listen-untriggered-notification.out
create mode 100644 src/test/modules/injection_points/specs/async-notify-listen-untriggered-notification.spec
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index f1bd278bd19..fdb43321e04 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -2287,6 +2287,8 @@ SignalBackends(void)
*/
count = 0;
+ INJECTION_POINT("async-notify-signal-backends-start", NULL);
+
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
/* Scan each channel name that we notified in this transaction */
diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile
index 665e7852d52..f53e331c56e 100644
--- a/src/test/modules/injection_points/Makefile
+++ b/src/test/modules/injection_points/Makefile
@@ -22,7 +22,8 @@ ISOLATION = basic \
repack_temporal_multirange \
repack_toast \
syscache-update-pruned \
- heap_lock_update
+ heap_lock_update \
+ async-notify-listen-untriggered-notification
# some isolation tests require wal_level=replica
ISOLATION_OPTS = --temp-config $(top_srcdir)/src/test/modules/injection_points/extra.conf
diff --git a/src/test/modules/injection_points/expected/async-notify-listen-untriggered-notification.out b/src/test/modules/injection_points/expected/async-notify-listen-untriggered-notification.out
new file mode 100644
index 00000000000..dd77a8182b4
--- /dev/null
+++ b/src/test/modules/injection_points/expected/async-notify-listen-untriggered-notification.out
@@ -0,0 +1,45 @@
+Parsed test spec with 4 sessions
+
+starting permutation: listen notify2 notify wake wake_up_signal_backends_start check check check notify check
+step listen: LISTEN race; <waiting ...>
+step notify2: NOTIFY ch2, 'ch2_payload'; <waiting ...>
+step notify: NOTIFY race, 'payload';
+step wake:
+ SELECT FROM injection_points_detach('async-notify-before-listen-commit');
+ SELECT FROM injection_points_wakeup('async-notify-before-listen-commit');
+ <waiting ...>
+step listen: <... completed>
+listener: NOTIFY "race" with payload "payload" from n1
+step wake: <... completed>
+step wake_up_signal_backends_start:
+ SELECT FROM injection_points_detach('async-notify-signal-backends-start');
+ SELECT FROM injection_points_wakeup('async-notify-signal-backends-start');
+ <waiting ...>
+step notify2: <... completed>
+step check: SELECT 1 AS x;
+x
+-
+1
+(1 row)
+
+step wake_up_signal_backends_start: <... completed>
+step check: SELECT 1 AS x;
+x
+-
+1
+(1 row)
+
+step check: SELECT 1 AS x;
+x
+-
+1
+(1 row)
+
+step notify: NOTIFY race, 'payload';
+step check: SELECT 1 AS x;
+x
+-
+1
+(1 row)
+
+listener: NOTIFY "race" with payload "payload" from n1
diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build
index 7fb8de3d0f8..cf65c4a4817 100644
--- a/src/test/modules/injection_points/meson.build
+++ b/src/test/modules/injection_points/meson.build
@@ -54,6 +54,7 @@ tests += {
'repack_toast',
'syscache-update-pruned',
'heap_lock_update',
+ 'async-notify-listen-untriggered-notification',
],
'runningcheck': false, # see syscache-update-pruned
# Some tests wait for all snapshots, so avoid parallel execution
diff --git a/src/test/modules/injection_points/specs/async-notify-listen-untriggered-notification.spec b/src/test/modules/injection_points/specs/async-notify-listen-untriggered-notification.spec
new file mode 100644
index 00000000000..d57d46957c4
--- /dev/null
+++ b/src/test/modules/injection_points/specs/async-notify-listen-untriggered-notification.spec
@@ -0,0 +1,60 @@
+# Test LISTEN/NOTIFY untriggered notification
+#
+# -----------------------------------------------------------------------------------------------------
+# l | start listening | wakeup, set listen=true and
+# | sleep before set listen=true | start waiting for new messages
+# -----------------------------------------------------------------------------------------------------
+# n2 | add unrelated message, | advance listener over our unrelated message
+# | advance to signal_backends start | listener pos now is right before related message
+# | but listener doesn't know that
+# | there is something to read
+# -----------------------------------------------------------------------------------------------------
+# n1 | send related message
+# | don't signal as listen=false,
+# | don't direct advance as n2 message is in between our message and listener position
+# -----------------------------------------------------------------------------------------------------
+
+setup
+{
+ CREATE EXTENSION injection_points;
+}
+
+teardown
+{
+ DROP EXTENSION injection_points;
+}
+
+session listener
+setup
+{
+ SELECT FROM injection_points_set_local();
+ SELECT FROM injection_points_attach('async-notify-before-listen-commit', 'wait');
+}
+step listen { LISTEN race; }
+step check { SELECT 1 AS x; }
+teardown { UNLISTEN *; }
+
+session n1
+step notify { NOTIFY race, 'payload'; }
+
+session n2
+setup
+{
+ SELECT FROM injection_points_set_local();
+ SELECT FROM injection_points_attach('async-notify-signal-backends-start', 'wait');
+}
+step notify2 { NOTIFY ch2, 'ch2_payload'; }
+
+session ctrl
+step wake
+{
+ SELECT FROM injection_points_detach('async-notify-before-listen-commit');
+ SELECT FROM injection_points_wakeup('async-notify-before-listen-commit');
+}
+step wake_up_signal_backends_start
+{
+ SELECT FROM injection_points_detach('async-notify-signal-backends-start');
+ SELECT FROM injection_points_wakeup('async-notify-signal-backends-start');
+}
+
+permutation listen notify2 notify wake(listen) wake_up_signal_backends_start(notify2) check check check notify check
--
2.43.0