summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorRobert Haas2013-07-16 17:02:15 +0000
committerRobert Haas2013-07-16 17:02:15 +0000
commit7f7485a0cde92aa4ba235a1ffe4dda0ca0b6cc9a (patch)
treed9a8776628552b886451703f2a8a56e137f678c8 /contrib
parent233bfe06735411f08d231764dfd3a6fcf7aef9a3 (diff)
Allow background workers to be started dynamically.
There is a new API, RegisterDynamicBackgroundWorker, which allows an ordinary user backend to register a new background writer during normal running. This means that it's no longer necessary for all background workers to be registered during processing of shared_preload_libraries, although the option of registering workers at that time remains available. When a background worker exits and will not be restarted, the slot previously used by that background worker is automatically released and becomes available for reuse. Slots used by background workers that are configured for automatic restart can't (yet) be released without shutting down the system. This commit adds a new source file, bgworker.c, and moves some of the existing control logic for background workers there. Previously, there was little enough logic that it made sense to keep everything in postmaster.c, but not any more. This commit also makes the worker_spi contrib module into an extension and adds a new function, worker_spi_launch, which can be used to demonstrate the new facility.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/worker_spi/Makefile3
-rw-r--r--contrib/worker_spi/worker_spi--1.0.sql9
-rw-r--r--contrib/worker_spi/worker_spi.c66
-rw-r--r--contrib/worker_spi/worker_spi.control5
4 files changed, 67 insertions, 16 deletions
diff --git a/contrib/worker_spi/Makefile b/contrib/worker_spi/Makefile
index edf4105a11..fbb29b4f2f 100644
--- a/contrib/worker_spi/Makefile
+++ b/contrib/worker_spi/Makefile
@@ -2,6 +2,9 @@
MODULES = worker_spi
+EXTENSION = worker_spi
+DATA = worker_spi--1.0.sql
+
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/worker_spi/worker_spi--1.0.sql b/contrib/worker_spi/worker_spi--1.0.sql
new file mode 100644
index 0000000000..a56b42c10e
--- /dev/null
+++ b/contrib/worker_spi/worker_spi--1.0.sql
@@ -0,0 +1,9 @@
+/* contrib/worker_spi/worker_spi--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION worker_spi" to load this file. \quit
+
+CREATE FUNCTION worker_spi_launch(pg_catalog.int4)
+RETURNS pg_catalog.bool STRICT
+AS 'MODULE_PATHNAME'
+LANGUAGE C;
diff --git a/contrib/worker_spi/worker_spi.c b/contrib/worker_spi/worker_spi.c
index 414721a70f..ef19e4b39e 100644
--- a/contrib/worker_spi/worker_spi.c
+++ b/contrib/worker_spi/worker_spi.c
@@ -42,8 +42,11 @@
#include "tcop/utility.h"
PG_MODULE_MAGIC;
+PG_FUNCTION_INFO_V1(worker_spi_launch);
void _PG_init(void);
+void worker_spi_main(Datum);
+Datum worker_spi_launch(PG_FUNCTION_ARGS);
/* flags set by signal handlers */
static volatile sig_atomic_t got_sighup = false;
@@ -153,11 +156,22 @@ initialize_worker_spi(worktable *table)
pgstat_report_activity(STATE_IDLE, NULL);
}
-static void
-worker_spi_main(void *main_arg)
+void
+worker_spi_main(Datum main_arg)
{
- worktable *table = (worktable *) main_arg;
+ int index = DatumGetInt32(main_arg);
+ worktable *table;
StringInfoData buf;
+ char name[20];
+
+ table = palloc(sizeof(worktable));
+ sprintf(name, "schema%d", index);
+ table->schema = pstrdup(name);
+ table->name = pstrdup("counted");
+
+ /* Establish signal handlers before unblocking signals. */
+ pqsignal(SIGHUP, worker_spi_sighup);
+ pqsignal(SIGTERM, worker_spi_sigterm);
/* We're now ready to receive signals */
BackgroundWorkerUnblockSignals();
@@ -279,7 +293,7 @@ worker_spi_main(void *main_arg)
pgstat_report_activity(STATE_IDLE, NULL);
}
- proc_exit(0);
+ proc_exit(1);
}
/*
@@ -292,9 +306,7 @@ void
_PG_init(void)
{
BackgroundWorker worker;
- worktable *table;
unsigned int i;
- char name[20];
/* get the configuration */
DefineCustomIntVariable("worker_spi.naptime",
@@ -309,6 +321,10 @@ _PG_init(void)
NULL,
NULL,
NULL);
+
+ if (!process_shared_preload_libraries_in_progress)
+ return;
+
DefineCustomIntVariable("worker_spi.total_workers",
"Number of workers.",
NULL,
@@ -328,23 +344,41 @@ _PG_init(void)
worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
worker.bgw_restart_time = BGW_NEVER_RESTART;
worker.bgw_main = worker_spi_main;
- worker.bgw_sighup = worker_spi_sighup;
- worker.bgw_sigterm = worker_spi_sigterm;
+ worker.bgw_sighup = NULL;
+ worker.bgw_sigterm = NULL;
/*
* Now fill in worker-specific data, and do the actual registrations.
*/
for (i = 1; i <= worker_spi_total_workers; i++)
{
- sprintf(name, "worker %d", i);
- worker.bgw_name = pstrdup(name);
-
- table = palloc(sizeof(worktable));
- sprintf(name, "schema%d", i);
- table->schema = pstrdup(name);
- table->name = pstrdup("counted");
- worker.bgw_main_arg = (void *) table;
+ snprintf(worker.bgw_name, BGW_MAXLEN, "worker %d", i);
+ worker.bgw_main_arg = Int32GetDatum(i);
RegisterBackgroundWorker(&worker);
}
}
+
+/*
+ * Dynamically launch an SPI worker.
+ */
+Datum
+worker_spi_launch(PG_FUNCTION_ARGS)
+{
+ int32 i = PG_GETARG_INT32(0);
+ BackgroundWorker worker;
+
+ worker.bgw_flags = BGWORKER_SHMEM_ACCESS |
+ BGWORKER_BACKEND_DATABASE_CONNECTION;
+ worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
+ worker.bgw_restart_time = BGW_NEVER_RESTART;
+ worker.bgw_main = NULL; /* new worker might not have library loaded */
+ sprintf(worker.bgw_library_name, "worker_spi");
+ sprintf(worker.bgw_function_name, "worker_spi_main");
+ worker.bgw_sighup = NULL; /* new worker might not have library loaded */
+ worker.bgw_sigterm = NULL; /* new worker might not have library loaded */
+ snprintf(worker.bgw_name, BGW_MAXLEN, "worker %d", i);
+ worker.bgw_main_arg = Int32GetDatum(i);
+
+ PG_RETURN_BOOL(RegisterDynamicBackgroundWorker(&worker));
+}
diff --git a/contrib/worker_spi/worker_spi.control b/contrib/worker_spi/worker_spi.control
new file mode 100644
index 0000000000..84d6294628
--- /dev/null
+++ b/contrib/worker_spi/worker_spi.control
@@ -0,0 +1,5 @@
+# worker_spi extension
+comment = 'Sample background worker'
+default_version = '1.0'
+module_pathname = '$libdir/worker_spi'
+relocatable = true