gracefully shut down fastcgi backends

we need to delete the events associated with the backends, otherwise
the server process won't ever quit.

Here, we add a pending counter to every backend and shut down
immediately if they aren't handling any client; otherwise we try to
close them as soon as possible (i.e. when they close the connection to
the last connected client.)
This commit is contained in:
Omar Polo 2021-07-06 10:54:27 +00:00
parent ea976e8743
commit 090b8a89fa
4 changed files with 38 additions and 0 deletions

15
fcgi.c
View File

@ -381,9 +381,16 @@ close_all(struct fcgi *f)
start_reply(c, CGI_ERROR, "CGI error");
}
fcgi_close_backend(f);
}
void
fcgi_close_backend(struct fcgi *f)
{
event_del(&f->e);
close(f->fd);
f->fd = -1;
f->pending = 0;
f->s = FCGI_OFF;
}
@ -413,6 +420,8 @@ handle_fcgi(int sock, short event, void *d)
if (must_read(sock, (char*)&end, sizeof(end)) == -1)
goto err;
/* TODO: do something with the status? */
f->pending--;
c->fcgi = -1;
c->next = close_conn;
event_once(c->fd, EV_WRITE, &copy_mbuf, c, NULL);
@ -447,6 +456,10 @@ handle_fcgi(int sock, short event, void *d)
if (!consume(sock, h.padding))
goto err;
if (f->pending == 0 && shutting_down)
fcgi_close_backend(f);
return;
err:
@ -462,6 +475,8 @@ send_fcgi_req(struct fcgi *f, struct client *c)
struct tm tminfo;
struct envlist *p;
f->pending++;
e = getnameinfo((struct sockaddr*)&c->addr, sizeof(c->addr),
addr, sizeof(addr),
NULL, 0,

1
gmid.c
View File

@ -333,6 +333,7 @@ free_config(void)
fcgi[i].port = NULL;
fcgi[i].prog = NULL;
fcgi[i].pending = 0;
fcgi[i].s = FCGI_OFF;
}

5
gmid.h
View File

@ -70,6 +70,9 @@ struct fcgi {
int fd;
struct event e;
/* number of pending clients */
int pending;
#define FCGI_OFF 0
#define FCGI_INFLIGHT 1
#define FCGI_READY 2
@ -337,6 +340,7 @@ void load_default_mime(struct mime*);
const char *mime(struct vhost*, const char*);
/* server.c */
extern int shutting_down;
const char *vhost_lang(struct vhost*, const char*);
const char *vhost_default_mime(struct vhost*, const char*);
const char *vhost_index(struct vhost*, const char*);
@ -375,6 +379,7 @@ int recv_fd(int);
int executor_main(struct imsgbuf*);
/* fcgi.c */
void fcgi_close_backend(struct fcgi *);
void handle_fcgi(int, short, void*);
void send_fcgi_req(struct fcgi*, struct client*);

View File

@ -26,6 +26,8 @@
#include <limits.h>
#include <string.h>
int shutting_down;
struct client clients[MAX_USERS];
static struct tls *ctx;
@ -1246,12 +1248,16 @@ handle_imsg_fcgi_fd(struct imsgbuf *ibuf, struct imsg *imsg, size_t len)
static void
handle_imsg_quit(struct imsgbuf *ibuf, struct imsg *imsg, size_t len)
{
size_t i;
(void)imsg;
(void)len;
/* don't call event_loopbreak since we want to finish to
* handle the ongoing connections. */
shutting_down = 1;
event_del(&e4);
if (has_ipv6)
event_del(&e6);
@ -1259,6 +1265,17 @@ handle_imsg_quit(struct imsgbuf *ibuf, struct imsg *imsg, size_t len)
signal_del(&siginfo);
event_del(&imsgev);
signal_del(&sigusr2);
for (i = 0; i < FCGI_MAX; ++i) {
if (fcgi[i].path == NULL && fcgi[i].prog == NULL)
break;
if (!event_pending(&fcgi[i].e, EV_READ, NULL) ||
fcgi[i].pending != 0)
continue;
fcgi_close_backend(&fcgi[i]);
}
}
static void