1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
# Tests for LISTEN/NOTIFY
# Most of these tests use only the "notifier" session and hence exercise only
# self-notifies, which are convenient because they minimize timing concerns.
# Note we assume that each step is delivered to the backend as a single Query
# message so it will run as one transaction.
session notifier
step listenc { LISTEN c1; LISTEN c2; }
step notify1 { NOTIFY c1; }
step notify2 { NOTIFY c2, 'payload'; }
step notify3 { NOTIFY c3, 'payload3'; } # not listening to c3
step notifyf { SELECT pg_notify('c2', NULL); }
step notifyd1 { NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; }
step notifyd2 { NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; }
step notifys1 {
BEGIN;
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
SAVEPOINT s1;
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads';
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads';
RELEASE SAVEPOINT s1;
SAVEPOINT s2;
NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload';
NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads';
NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload';
NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads';
ROLLBACK TO SAVEPOINT s2;
COMMIT;
}
step usage { SELECT pg_notification_queue_usage() > 0 AS nonzero; }
step bignotify { SELECT count(pg_notify('c1', s::text)) FROM generate_series(1, 1000) s; }
teardown { UNLISTEN *; }
# The listener session is used for cross-backend notify checks.
session listener
step llisten { LISTEN c1; LISTEN c2; }
step lcheck { SELECT 1 AS x; }
step lbegin { BEGIN; }
step lbegins { BEGIN ISOLATION LEVEL SERIALIZABLE; }
step lcommit { COMMIT; }
teardown { UNLISTEN *; }
# In some tests we need a second listener, just to block the queue.
session listener2
step l2listen { LISTEN c1; }
step l2begin { BEGIN; }
step l2commit { COMMIT; }
step l2stop { UNLISTEN *; }
# Trivial cases.
permutation listenc notify1 notify2 notify3 notifyf
# Check simple and less-simple deduplication.
permutation listenc notifyd1 notifyd2 notifys1
# Cross-backend notification delivery. We use a "select 1" to force the
# listener session to check for notifies. In principle we could just wait
# for delivery, but that would require extra support in isolationtester
# and might have portability-of-timing issues.
permutation llisten notify1 notify2 notify3 notifyf lcheck
# Again, with local delivery too.
permutation listenc llisten notify1 notify2 notify3 notifyf lcheck
# Check for bug when initial listen is only action in a serializable xact,
# and notify queue is not empty
permutation l2listen l2begin notify1 lbegins llisten lcommit l2commit l2stop
# Verify that pg_notification_queue_usage correctly reports a non-zero result,
# after submitting notifications while another connection is listening for
# those notifications and waiting inside an active transaction. We have to
# fill a page of the notify SLRU to make this happen, which is a good deal
# of traffic. To not bloat the expected output, we intentionally don't
# commit the listener's transaction, so that it never reports these events.
# Hence, this should be the last test in this script.
permutation llisten lbegin usage bignotify usage
|