This patch adds an advanced option to the Squid helper controls which
overrides Squid dying when helpers crash.
It has been found necessary in certain corner cases with PHP helpers
(which have system imposed limited lifetimes) where a proxy has
previously been under some load and helpers started then are timed out
later under low load as a bunch. Squid may die and restart.
If the proxy has been started under existing high load conditions (such
as a backup coming online) this case may also occur shortly after
startup. Leading to a chain reaction of restarts until load drops below
number of helpers needed to trigger a death.
These cases depend on external forces or helper design closing the
helpers outside Squid control.
There is one known issue with this option:
If the helpers are really dying due to some fatal issue during their
startup the use of this option would result in Squid hanging while
infinitely re-starting helpers and doing no request processing.
Amos
=== modified file 'src/HelperChildConfig.cc'
--- src/HelperChildConfig.cc 2010-02-13 09:16:30 +0000
+++ src/HelperChildConfig.cc 2010-02-20 01:33:07 +0000
@@ -4,11 +4,12 @@
#include <string.h>
-HelperChildConfig::HelperChildConfig(const unsigned int m, const unsigned int s, const unsigned int i, const unsigned int cc) :
+HelperChildConfig::HelperChildConfig(const unsigned int m, const unsigned int s, const unsigned int i, const unsigned int cc, const unsigned int im) :
n_max(m),
n_startup(s),
n_idle(i),
concurrency(cc),
+ immortal(im),
n_running(0),
n_active(0)
{}
@@ -62,6 +63,8 @@
}
} else if (strncmp(token, "concurrency=", 12) == 0) {
concurrency = atoi(token + 12);
+ } else if (strcmp(token, "immortal") == 0) {
+ immortal = 1;
} else {
self_destruct();
}
=== modified file 'src/HelperChildConfig.h'
--- src/HelperChildConfig.h 2010-02-13 09:16:30 +0000
+++ src/HelperChildConfig.h 2010-02-20 01:42:43 +0000
@@ -10,7 +10,7 @@
class HelperChildConfig
{
public:
- HelperChildConfig(const unsigned int m=0, const unsigned int s=0, const unsigned int i=1, const unsigned int cc=0);
+ HelperChildConfig(const unsigned int m=0, const unsigned int s=0, const unsigned int i=1, const unsigned int cc=0, const unsigned int im=0);
~HelperChildConfig();
HelperChildConfig &operator =(const HelperChildConfig &rhs);
@@ -54,6 +54,16 @@
*/
unsigned int concurrency;
+ /**
+ * Whether Squid should die if these helpers are closing too fast.
+ * This permits use of some script languages which have a maximum script run lifetime (ie PHP)
+ *
+ * The danger is that when used on truely broken helpers it will cause Squid to enter an
+ * infinite loop of restarting helpers.
+ * Default: 0 - Squid will shutdown if helpers close at too fast a rate.
+ */
+ unsigned int immortal;
+
/* derived from active operations */
public:
@@ -72,7 +82,7 @@
/* Legacy parser interface */
#define parse_HelperChildConfig(c) (c)->parseConfig()
-#define dump_HelperChildConfig(e,n,c) storeAppendPrintf((e), "\n%s %d startup=%d idle=%d concurrency=%d\n", (n), (c).n_max, (c).n_startup, (c).n_idle, (c).concurrency)
+#define dump_HelperChildConfig(e,n,c) storeAppendPrintf((e), "\n%s %d startup=%d idle=%d concurrency=%d%s\n", (n), (c).n_max, (c).n_startup, (c).n_idle, (c).concurrency, ((c).immortal?" immortal":""))
#define free_HelperChildConfig(dummy) // NO.
#endif /* _SQUID_SRC_HELPERCHILDCONFIG_H */
=== modified file 'src/helper.cc'
--- src/helper.cc 2009-12-16 03:46:59 +0000
+++ src/helper.cc 2010-02-20 01:38:33 +0000
@@ -715,8 +715,14 @@
if (hlp->childs.needNew() > 0) {
debugs(80, 1, "Too few " << hlp->id_name << " processes are running (need " << hlp->childs.needNew() << "/" << hlp->childs.n_max << ")");
- if (hlp->childs.n_active < hlp->childs.n_startup && hlp->last_restart > squid_curtime - 30)
- fatalf("The %s helpers are crashing too rapidly, need help!\n", hlp->id_name);
+ if (hlp->childs.n_active < hlp->childs.n_startup && hlp->last_restart > squid_curtime - 30) {
+ if (!hlp->childs.immortal) {
+ fatalf("The %s helpers are crashing too rapidly, need help!\n", hlp->id_name);
+ } else {
+ debugs(80,0, "WARNING: The " << hlp->id_name << " helpers are crashing too rapidly. They may be broken!");
+ debugs(80,0, "WARNING: Immortality override applied.");
+ }
+ }
debugs(80, 1, "Starting new helpers");
helperOpenServers(hlp);
@@ -775,7 +781,13 @@
debugs(80, 1, "Too few " << hlp->id_name << " processes are running (need " << hlp->childs.needNew() << "/" << hlp->childs.n_max << ")");
if (hlp->childs.n_active < hlp->childs.n_startup && hlp->last_restart > squid_curtime - 30)
- fatalf("The %s helpers are crashing too rapidly, need help!\n", hlp->id_name);
+ if (!hlp->childs.immortal) {
+ fatalf("The %s helpers are crashing too rapidly, need help!\n", hlp->id_name);
+ } else {
+ debugs(80,0, "WARNING: The " << hlp->id_name << " helpers are crashing too rapidly. They may be broken!");
+ debugs(80,0, "WARNING: Immortality override applied.");
+ }
+ }
debugs(80, 1, "Starting new helpers");
helperStatefulOpenServers(hlp);