From 95e31929e8fe3cf06eb8ee2b36082ad0b1656129 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Tue, 6 Oct 2015 21:04:14 -0700 Subject: [PATCH] taskd.pl: eliminate main loop sleep 1 delay Implement a penalty box system where by accept is skipped whenever the current number of penalty points exceeds a spawning threshold. The current number of penalty points is increased by one whenever a new process is spawned and decreased by one as each second passes. This preserves the previous of accepting no more than one new connection per second but changes it to no more than one new connection per second on average while allowing bursts of up to eight new connections at once. This improves responsiveness and allows the pipe messages to be serviced more frequently while avoiding excessive spawning. Signed-off-by: Kyle J. McKay --- taskd/taskd.pl | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/taskd/taskd.pl b/taskd/taskd.pl index 796bcd8..39b0b1c 100755 --- a/taskd/taskd.pl +++ b/taskd/taskd.pl @@ -81,6 +81,7 @@ my $idle_timeout; my $abbrev = 8; my $statusintv = 60; my $idleintv = 3600; +my $maxspawn = 8; $| = 1; @@ -1017,10 +1018,13 @@ pipe($piperead, $pipewrite) or die "pipe failed: $!"; setnonblock($piperead); select((select($pipewrite), $|=1)[0]); my $pipebuff = ''; -my $fdset = ''; -vec($fdset, fileno(Server), 1) = 1; -vec($fdset, fileno($piperead), 1) = 1; +my $fdset_both = ''; +vec($fdset_both, fileno($piperead), 1) = 1; +my $fdset_pipe = $fdset_both; +vec($fdset_both, fileno(Server), 1) = 1; +my $penalty = 0; my $t = time; +my $penaltytime = $t; my $nextwakeup = $t + 60; my $nextstatus = undef; $nextstatus = $t + $statusintv if $statusintv; @@ -1030,6 +1034,13 @@ while (1) { do { my $wait; my $now = time; + my $adjustpenalty = sub { + if ($penaltytime < $now) { + my $credit = $now - $penaltytime; + $penalty = $penalty > $credit ? $penalty - $credit : 0; + $penaltytime = $now; + } + }; if (defined($nextstatus) && $now >= $nextstatus) { unless ($idlestatus && !$children && (!$idleintv || $now - $idlestatus < $idleintv)) { my $statmsg = "STATUS: $children active"; @@ -1065,11 +1076,20 @@ while (1) { } $nextwakeup += 60, $now = time while ($wait = $nextwakeup - $now) <= 0; $wait = _min($wait, (Throttle::ServiceQueue()||60)); + &$adjustpenalty; # this prevents ignoring accept when we shouldn't + my $fdset; + if ($penalty <= $maxspawn) { + $fdset = $fdset_both; + } else { + $fdset = $fdset_pipe; + $wait = $penalty - $maxspawn if $wait > $penalty - $maxspawn; + } $nfound = select($rout=$fdset, undef, $eout=$fdset, $wait); logmsg("select failed: $!"), exit(1) unless $nfound >= 0 || $!{EINTR} || $!{EAGAIN}; my $reaped; Throttle::RemoveSupplicant($reaped) while ($reaped = shift(@reapedpids)); $now = time; + &$adjustpenalty; # this prevents banking credits for elapsed time if ($idle_timeout && !$children && !$nfound && $now - $idlestart >= $idle_timeout) { statmsg "idle timeout (@{[duration($idle_timeout)]}) exceeded now exiting"; exit 0; @@ -1108,6 +1128,7 @@ while (1) { next; } logmsg "connection on $NAME"; + ++$penalty; spawn sub { my $inp = ; $inp = if defined($inp) && $inp eq "\n"; @@ -1128,7 +1149,6 @@ while (1) { } }; close Client; - sleep 1; } # -- 2.11.4.GIT