Hi,

Recently, the API to define custom wait events for extension is supported.
* Change custom wait events to use dynamic shared hash tables(af720b4c5)

So, I'd like to rethink the wait event names for modules which use
"WAIT_EVENT_EXTENSION" wait events.
* postgres_fdw
* dblink
* pg_prewarm
* test_shm_mq
* worker_spi

I expect that no one will object to changing the names to appropriate
ones. But, we need to discuss that naming convention, the names themselves,
document descriptions and so on.

I made the v1 patch
* CamelCase naming convention
* Add document descriptions for each module

I haven't added document descriptions for pg_prewarm and test modules.
The reason is that the wait event of autoprewarm is not shown on
pg_stat_activity. It's not an auxiliary-process and doesn't connect to
a database, so pgstat_bestart() isn't be called.

Feedback is always welcome and appreciated.

Regards,
--
Masahiro Ikeda
NTT DATA CORPORATION
From 73c4c6562509465bea75a9bbd273298bdf0ee85e Mon Sep 17 00:00:00 2001
From: Masahiro Ikeda <mshr.ik...@ntt.com>
Date: Fri, 18 Aug 2023 11:38:05 +0900
Subject: [PATCH] Make to use custom wait events for modules

---
 contrib/dblink/dblink.c                       | 15 +++++-
 contrib/pg_prewarm/autoprewarm.c              | 13 ++++-
 contrib/postgres_fdw/connection.c             | 23 ++++++--
 doc/src/sgml/dblink.sgml                      | 26 +++++++++
 doc/src/sgml/postgres-fdw.sgml                | 53 +++++++++++++++++++
 doc/src/sgml/xfunc.sgml                       |  6 +--
 src/test/modules/test_shm_mq/setup.c          |  9 +++-
 src/test/modules/test_shm_mq/test.c           |  9 +++-
 .../modules/worker_spi/t/001_worker_spi.pl    |  8 +--
 src/test/modules/worker_spi/worker_spi.c      |  2 +-
 10 files changed, 147 insertions(+), 17 deletions(-)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 41e1f6c91d..26fcd093c7 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -130,6 +130,9 @@ static void restoreLocalGucs(int nestlevel);
 static remoteConn *pconn = NULL;
 static HTAB *remoteConnHash = NULL;
 
+/* value cached, fetched from shared memory */
+static uint32 wait_event_info = 0;
+
 /*
  *	Following is list that holds multiple remote connections.
  *	Calling convention of each dblink function changes to accept
@@ -202,8 +205,12 @@ dblink_get_conn(char *conname_or_str,
 			connstr = conname_or_str;
 		dblink_connstr_check(connstr);
 
+		/* first time, allocate or get the custom wait event */
+		if (wait_event_info == 0)
+			wait_event_info = WaitEventExtensionNew("DblinkConnect");
+
 		/* OK to make connection */
-		conn = libpqsrv_connect(connstr, WAIT_EVENT_EXTENSION);
+		conn = libpqsrv_connect(connstr, wait_event_info);
 
 		if (PQstatus(conn) == CONNECTION_BAD)
 		{
@@ -292,8 +299,12 @@ dblink_connect(PG_FUNCTION_ARGS)
 	/* check password in connection string if not superuser */
 	dblink_connstr_check(connstr);
 
+	/* first time, allocate or get the custom wait event */
+	if (wait_event_info == 0)
+		wait_event_info = WaitEventExtensionNew("DblinkConnect");
+
 	/* OK to make connection */
-	conn = libpqsrv_connect(connstr, WAIT_EVENT_EXTENSION);
+	conn = libpqsrv_connect(connstr, wait_event_info);
 
 	if (PQstatus(conn) == CONNECTION_BAD)
 	{
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index d0efc9e524..8c2581f457 100644
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -104,6 +104,7 @@ static AutoPrewarmSharedState *apw_state = NULL;
 /* GUC variables. */
 static bool autoprewarm = true; /* start worker? */
 static int	autoprewarm_interval = 300; /* dump interval */
+static uint32 wait_event_info = 0; /* value cached, fetched from shared memory */
 
 /*
  * Module load callback.
@@ -231,13 +232,21 @@ autoprewarm_main(Datum main_arg)
 			ProcessConfigFile(PGC_SIGHUP);
 		}
 
+		/*
+		 * allocate or get the custom wait event though it will not be shown
+		 * on pg_stat_activity because the autoprewarm worker doesn't connect
+		 * a database.
+		 */
+		if (wait_event_info == 0)
+			wait_event_info = WaitEventExtensionNew("PgPrewarmDumpDelay");
+
 		if (autoprewarm_interval <= 0)
 		{
 			/* We're only dumping at shutdown, so just wait forever. */
 			(void) WaitLatch(MyLatch,
 							 WL_LATCH_SET | WL_EXIT_ON_PM_DEATH,
 							 -1L,
-							 WAIT_EVENT_EXTENSION);
+							wait_event_info);
 		}
 		else
 		{
@@ -264,7 +273,7 @@ autoprewarm_main(Datum main_arg)
 			(void) WaitLatch(MyLatch,
 							 WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
 							 delay_in_ms,
-							 WAIT_EVENT_EXTENSION);
+							 wait_event_info);
 		}
 
 		/* Reset the latch, loop. */
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 7e12b722ec..c88624763d 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -83,6 +83,11 @@ static unsigned int prep_stmt_number = 0;
 /* tracks whether any work is needed in callback functions */
 static bool xact_got_connection = false;
 
+/* value cached, fetched from shared memory */
+static uint32 wait_event_info_connect = 0;
+static uint32 wait_event_info_receive = 0;
+static uint32 wait_event_info_cleanup_receive = 0;
+
 /*
  * Milliseconds to wait to cancel an in-progress query or execute a cleanup
  * query; if it takes longer than 30 seconds to do these, we assume the
@@ -527,10 +532,14 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		/* verify the set of connection parameters */
 		check_conn_params(keywords, values, user);
 
+		/* first time, allocate or get the custom wait event */
+		if (wait_event_info_connect == 0)
+			wait_event_info_connect = WaitEventExtensionNew("PostgresFdwConnect");
+
 		/* OK to make connection */
 		conn = libpqsrv_connect_params(keywords, values,
 									   false,	/* expand_dbname */
-									   WAIT_EVENT_EXTENSION);
+									   wait_event_info_connect);
 
 		if (!conn || PQstatus(conn) != CONNECTION_OK)
 			ereport(ERROR,
@@ -858,12 +867,16 @@ pgfdw_get_result(PGconn *conn, const char *query)
 			{
 				int			wc;
 
+				/* first time, allocate or get the custom wait event */
+				if (wait_event_info_receive == 0)
+					wait_event_info_receive = WaitEventExtensionNew("PostgresFdwReceive");
+
 				/* Sleep until there's something to do */
 				wc = WaitLatchOrSocket(MyLatch,
 									   WL_LATCH_SET | WL_SOCKET_READABLE |
 									   WL_EXIT_ON_PM_DEATH,
 									   PQsocket(conn),
-									   -1L, WAIT_EVENT_EXTENSION);
+									   -1L, wait_event_info_receive);
 				ResetLatch(MyLatch);
 
 				CHECK_FOR_INTERRUPTS();
@@ -1562,12 +1575,16 @@ pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result,
 					goto exit;
 				}
 
+				/* first time, allocate or get the custom wait event */
+				if (wait_event_info_cleanup_receive == 0)
+					wait_event_info_cleanup_receive = WaitEventExtensionNew("PostgresFdwCleanupReceive");
+
 				/* Sleep until there's something to do */
 				wc = WaitLatchOrSocket(MyLatch,
 									   WL_LATCH_SET | WL_SOCKET_READABLE |
 									   WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
 									   PQsocket(conn),
-									   cur_timeout, WAIT_EVENT_EXTENSION);
+									   cur_timeout, wait_event_info_cleanup_receive);
 				ResetLatch(MyLatch);
 
 				CHECK_FOR_INTERRUPTS();
diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml
index 7d25f24f49..da6c4b7a92 100644
--- a/doc/src/sgml/dblink.sgml
+++ b/doc/src/sgml/dblink.sgml
@@ -101,6 +101,32 @@ dblink_connect(text connname, text connstr) returns text
    </para>
   </refsect1>
 
+  <refsect1>
+   <title>Wait Event</title>
+
+  <para>
+   <filename>dblink</filename> could show the following wait event under the wait
+   event type <literal>Extension</literal>.
+  </para>
+
+  <variablelist>
+   <varlistentry>
+    <term>
+     <literal>DblinkConnect</literal>
+     <indexterm>
+      <primary><literal>DblinkConnect</literal> wait event</primary>
+     </indexterm>
+    </term>
+    <listitem>
+     <para>
+      Waiting to establish connection to a remote server.
+     </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+
+  </refsect1>
+
   <refsect1>
    <title>Notes</title>
 
diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml
index 5062d712e7..c631e1384a 100644
--- a/doc/src/sgml/postgres-fdw.sgml
+++ b/doc/src/sgml/postgres-fdw.sgml
@@ -1042,6 +1042,59 @@ postgres=# SELECT postgres_fdw_disconnect_all();
   </para>
  </sect2>
 
+ <sect2 id="postgres-fdw-wait-events">
+  <title>Wait Events</title>
+
+  <para>
+   <filename>postgres_fdw</filename> could show the following wait events under the wait
+   event type <literal>Extension</literal>.
+  </para>
+
+  <variablelist>
+   <varlistentry>
+    <term>
+     <literal>PostgresFdwConnect</literal>
+     <indexterm>
+      <primary><literal>PostgresFdwConnect</literal> wait event</primary>
+     </indexterm>
+    </term>
+    <listitem>
+     <para>
+      Waiting to establish connection to a remote server.
+     </para>
+    </listitem>
+   </varlistentry>
+   <varlistentry>
+    <term>
+     <literal>PostgresFdwReceive</literal>
+     <indexterm>
+      <primary><literal>PostgresFdwReceive</literal> wait event</primary>
+     </indexterm>
+    </term>
+    <listitem>
+     <para>
+      Waiting to receive the results of a query from a remote server.
+     </para>
+    </listitem>
+   </varlistentry>
+   <varlistentry>
+    <term>
+     <literal>PostgresFdwCleanupReceive</literal>
+     <indexterm>
+      <primary><literal>PostgresFdwCleanupReceive</literal> wait event</primary>
+     </indexterm>
+    </term>
+    <listitem>
+     <para>
+      Waiting for same reason as <literal>PostgresFdwReceive</literal>, except that it's only for
+      abort.
+     </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+
+ </sect2>
+
  <sect2 id="postgres-fdw-configuration-parameters">
   <title>Configuration Parameters</title>
 
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 281c178b0e..96ba95818c 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -3472,9 +3472,9 @@ uint32 WaitEventExtensionNew(const char *wait_event_name)
 <screen>
 =# SELECT wait_event_type, wait_event FROM pg_stat_activity
      WHERE backend_type ~ 'worker_spi';
- wait_event_type |   wait_event
------------------+-----------------
- Extension       | worker_spi_main
+ wait_event_type |  wait_event
+-----------------+---------------
+ Extension       | WorkerSpiMain
 (1 row)
 </screen>
     </para>
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 192e5cc2ab..ef68689d0b 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -40,6 +40,9 @@ static void wait_for_workers_to_become_ready(worker_state *wstate,
 											 volatile test_shm_mq_header *hdr);
 static bool check_worker_status(worker_state *wstate);
 
+/* value cached, fetched from shared memory */
+static uint32 wait_event_info_bgworker_startup = 0;
+
 /*
  * Set up a dynamic shared memory segment and zero or more background workers
  * for a test run.
@@ -278,9 +281,13 @@ wait_for_workers_to_become_ready(worker_state *wstate,
 			break;
 		}
 
+		/* first time, allocate or get the custom wait event */
+		if (wait_event_info_bgworker_startup == 0)
+			wait_event_info_bgworker_startup = WaitEventExtensionNew("TestShmMqBgWorkerStartup");
+
 		/* Wait to be signaled. */
 		(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-						 WAIT_EVENT_EXTENSION);
+						 wait_event_info_bgworker_startup);
 
 		/* Reset the latch so we don't spin. */
 		ResetLatch(MyLatch);
diff --git a/src/test/modules/test_shm_mq/test.c b/src/test/modules/test_shm_mq/test.c
index d9be703350..d7e8d3d868 100644
--- a/src/test/modules/test_shm_mq/test.c
+++ b/src/test/modules/test_shm_mq/test.c
@@ -28,6 +28,9 @@ PG_FUNCTION_INFO_V1(test_shm_mq_pipelined);
 static void verify_message(Size origlen, char *origdata, Size newlen,
 						   char *newdata);
 
+/* value cached, fetched from shared memory */
+static uint32 wait_event_info_message_queue = 0;
+
 /*
  * Simple test of the shared memory message queue infrastructure.
  *
@@ -225,6 +228,10 @@ test_shm_mq_pipelined(PG_FUNCTION_ARGS)
 
 		if (wait)
 		{
+			/* first time, allocate or get the custom wait event */
+			if (wait_event_info_message_queue == 0)
+				wait_event_info_message_queue = WaitEventExtensionNew("TestShmMqMessageQueue");
+
 			/*
 			 * If we made no progress, wait for one of the other processes to
 			 * which we are connected to set our latch, indicating that they
@@ -232,7 +239,7 @@ test_shm_mq_pipelined(PG_FUNCTION_ARGS)
 			 * for us to do.
 			 */
 			(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
-							 WAIT_EVENT_EXTENSION);
+							 wait_event_info_message_queue);
 			ResetLatch(MyLatch);
 			CHECK_FOR_INTERRUPTS();
 		}
diff --git a/src/test/modules/worker_spi/t/001_worker_spi.pl b/src/test/modules/worker_spi/t/001_worker_spi.pl
index 26b8a49bec..dac97be75f 100644
--- a/src/test/modules/worker_spi/t/001_worker_spi.pl
+++ b/src/test/modules/worker_spi/t/001_worker_spi.pl
@@ -43,9 +43,9 @@ is($result, qq(total|1), 'dynamic bgworker correctly consumed tuple data');
 $result = $node->poll_query_until(
 	'postgres',
 	qq[SELECT wait_event FROM pg_stat_activity WHERE backend_type ~ 'worker_spi';],
-	qq[worker_spi_main]);
+	qq[WorkerSpiMain]);
 is($result, 1,
-	'dynamic bgworker has reported "worker_spi_main" as wait event');
+	'dynamic bgworker has reported "WorkerSpiMain" as wait event');
 
 note "testing bgworkers loaded with shared_preload_libraries";
 
@@ -68,7 +68,7 @@ ok( $node->poll_query_until(
 		'mydb',
 		qq[SELECT datname, count(datname), wait_event FROM pg_stat_activity
             WHERE backend_type = 'worker_spi' GROUP BY datname, wait_event;],
-		'mydb|3|worker_spi_main'),
+		'mydb|3|WorkerSpiMain'),
 	'bgworkers all launched'
 ) or die "Timed out while waiting for bgworkers to be launched";
 
@@ -83,7 +83,7 @@ ok( $node->poll_query_until(
 		qq[SELECT datname, count(datname), wait_event FROM pg_stat_activity
             WHERE backend_type = 'worker_spi dynamic' AND
             pid IN ($worker1_pid, $worker2_pid) GROUP BY datname, wait_event;],
-		'mydb|2|worker_spi_main'),
+		'mydb|2|WorkerSpiMain'),
 	'dynamic bgworkers all launched'
 ) or die "Timed out while waiting for dynamic bgworkers to be launched";
 
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index 98f8d4194b..2e3114990e 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -194,7 +194,7 @@ worker_spi_main(Datum main_arg)
 
 		/* First time, allocate or get the custom wait event */
 		if (worker_spi_wait_event_main == 0)
-			worker_spi_wait_event_main = WaitEventExtensionNew("worker_spi_main");
+			worker_spi_wait_event_main = WaitEventExtensionNew("WorkerSpiMain");
 
 		/*
 		 * Background workers mustn't call usleep() or any direct equivalent:
-- 
2.25.1

Reply via email to