ic-proxy: Quit proxy bgworker when postmaster is dead
Proxy bgworker will become orphan process after postmaster is dead
due to the lack of checking pipe postmaster_alive_fds[POSTMASTER_FD_WATCH].
Epoll this pipe inside proxy bgworker main loop as well.
#include "postgres.h"
#include "postmaster/bgworker.h"
+#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/memutils.h"
@@ -41,6 +42,9 @@ static bool ic_proxy_client_listening;
static int ic_proxy_server_exit_code = 1;
+/* pipe to check whether postmaster is alive */
+static uv_pipe_t ic_proxy_postmaster_pipe;
+
/*
* The peer listener is closed.
*/
@@ -379,6 +383,25 @@ ic_proxy_server_on_signal(uv_signal_t *handle, int signum)
}
}
+/*
+ * callback when received data from ic_proxy_postmaster_pipe
+ */
+static void
+ic_proxy_server_on_read_postmaster_pipe(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
+{
+ /* return the pkt to cache freelist, we don't care about the buffer content */
+ if (buf->base)
+ ic_proxy_pkt_cache_free(buf->base);
+
+ /* nread = 0 means EAGAIN and EWOULDBLOCK, while nread = EOF means postmaster is dead */
+ if (nread == UV_EOF)
+ proc_exit(1);
+ else if (nread < 0)
+ ic_proxy_log(FATAL, "read on postmaster death monitoring pipe failed: %s", uv_strerror(nread));
+ else if (nread > 0)
+ ic_proxy_log(FATAL, "unexpected data in postmaster death monitoring pipe with length: %d", nread);
+}
+
/*
* The main loop of the ic-proxy.
*/
@@ -420,6 +443,12 @@ ic_proxy_server_main(void)
uv_timer_init(&ic_proxy_server_loop, &ic_proxy_server_timer);
uv_timer_start(&ic_proxy_server_timer, ic_proxy_server_on_timer, 100, 1000);
+ /* monitor the postmaster pipe to check whether postmaster is still alive */
+ uv_pipe_init(&ic_proxy_server_loop, &ic_proxy_postmaster_pipe, false);
+ uv_pipe_open(&ic_proxy_postmaster_pipe, postmaster_alive_fds[POSTMASTER_FD_WATCH]);
+ uv_read_start((uv_stream_t *)&ic_proxy_postmaster_pipe, ic_proxy_pkt_cache_alloc_buffer,
+ ic_proxy_server_on_read_postmaster_pipe);
+
ic_proxy_log(LOG, "ic-proxy-server: running");
/* We're now ready to receive signals */
