summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2022-10-04 19:02:39 +0000
committerLaurent Bercot <ska@appnovation.com>2022-10-04 19:02:39 +0000
commit04876fbe6bb09832a78b013898d64b3abc921604 (patch)
treefd4c65d46e21e24796963bdeb7a940bd8a3383cc
parent7a991b6adb985ca13a28350a10e0324239bb39a2 (diff)
downloads6-04876fbe6bb09832a78b013898d64b3abc921604.tar.xz
s6-supervise QoL: only skip 1-second restart delay when service was ready
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--doc/s6-supervise.html4
-rw-r--r--src/supervision/s6-supervise.c36
2 files changed, 26 insertions, 14 deletions
diff --git a/doc/s6-supervise.html b/doc/s6-supervise.html
index 86d97a6..943a347 100644
--- a/doc/s6-supervise.html
+++ b/doc/s6-supervise.html
@@ -171,7 +171,9 @@ to <tt>./event</tt> <em>before</em> the <tt>'D'</tt>, and it
<strong>does not restart the service</strong>, as if <tt>s6-svc -O</tt> had
been called. This can be used to signify permanent failure to start the service. </li>
<li> There is a minimum 1-second delay between two <tt>./run</tt> spawns, to avoid busylooping
-if <tt>./run</tt> exits too quickly. </li>
+if <tt>./run</tt> exits too quickly. If the service has been <em>ready</em> for more
+than one second, it will restart immediately, but if it not <em>ready</em> when
+it dies, s6-supervise will always pause for 1 second before spawning it again. </li>
<li> When killed or asked to exit, it waits for the service to go down one last time, then
sends a <tt>'x'</tt> event to <tt>./event</tt> before exiting 0. </li>
</ul>
diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c
index c377e32..42372cd 100644
--- a/src/supervision/s6-supervise.c
+++ b/src/supervision/s6-supervise.c
@@ -3,6 +3,7 @@
/* For SIGWINCH */
#include <skalibs/nonposix.h>
+#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
@@ -52,15 +53,23 @@ enum state_e
LASTFINISH
} ;
+struct gflags_s
+{
+ uint8_t cont : 1 ;
+ uint8_t dying : 1 ;
+} gflags =
+{
+ .cont = 1,
+ .dying = 0
+} ;
+
typedef void action_t (void) ;
typedef action_t *action_t_ref ;
static tain deadline ;
-static tain dontrespawnbefore = TAIN_EPOCH ;
+static tain nextstart = TAIN_ZERO ;
static s6_svstatus_t status = S6_SVSTATUS_ZERO ;
static state_t state = DOWN ;
-static int flagdying = 0 ;
-static int cont = 1 ;
static int notifyfd = -1 ;
static char const *servicename = 0 ;
@@ -118,10 +127,10 @@ static void set_down_and_ready (char const *s, unsigned int n)
status.pid = 0 ;
status.flagfinishing = 0 ;
status.flagready = 1 ;
- tain_wallclock_read(&status.readystamp) ;
state = DOWN ;
- if (tain_future(&dontrespawnbefore)) deadline = dontrespawnbefore ;
- else tain_copynow(&deadline) ;
+ if (tai_sec(tain_secp(&nextstart))) deadline = nextstart ;
+ else tain_addsec_g(&deadline, 1) ;
+ tain_wallclock_read(&status.readystamp) ;
announce() ;
ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, s, n) ;
}
@@ -135,7 +144,7 @@ static void nop (void)
static void bail (void)
{
- cont = 0 ;
+ gflags.cont = 0 ;
}
static void sigint (void)
@@ -359,11 +368,11 @@ static void trystart (void)
fd_close(p[0]) ;
notifyfd = notifyp[0] ;
settimeout_infinite() ;
+ nextstart = tain_zero ;
state = UP ;
status.pid = pid ;
status.flagready = 0 ;
tain_wallclock_read(&status.stamp) ;
- tain_addsec_g(&dontrespawnbefore, 1) ;
announce() ;
ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "u", 1) ;
return ;
@@ -417,7 +426,7 @@ static int uplastup_z (void)
status.wstat = (int)status.pid ;
status.flagpaused = 0 ;
status.flagready = 0 ;
- flagdying = 0 ;
+ gflags.dying = 0 ;
tain_wallclock_read(&status.stamp) ;
if (notifyfd >= 0)
{
@@ -491,7 +500,7 @@ static void lastup_z (void)
static void uptimeout (void)
{
- if (flagdying)
+ if (gflags.dying)
{
killk() ;
settimeout(5) ;
@@ -520,7 +529,7 @@ static void up_d (void)
if (timeout && tain_from_millisecs(&tto, timeout))
{
tain_add_g(&deadline, &tto) ;
- flagdying = 1 ;
+ gflags.dying = 1 ;
}
else settimeout_infinite() ;
}
@@ -613,6 +622,7 @@ static inline void handle_notifyfd (void)
r = sanitize_read(fd_read(notifyfd, buf, 512)) ;
if (r > 0 && memchr(buf, '\n', r))
{
+ tain_addsec_g(&nextstart, 1) ;
tain_wallclock_read(&status.readystamp) ;
status.flagready = 1 ;
announce() ;
@@ -806,12 +816,12 @@ int main (int argc, char const *const *argv)
tain_now_set_stopwatch_g() ;
settimeout(0) ;
- tain_wallclock_read(&status.stamp) ;
+ tain_copynow(&status.stamp) ;
status.readystamp = status.stamp ;
announce() ;
ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "s", 1) ;
- while (cont)
+ while (gflags.cont)
{
int r ;
x[2].fd = notifyfd ;