Hello,

This patch removes "use dead idle peer" heuristic since
nobody has spoken in defense of this feature on Squid mailing lists:
http://lists.squid-cache.org/pipermail/squid-users/2017-March/014785.html
http://lists.squid-cache.org/pipermail/squid-dev/2017-March/008308.html

Note that the removed functionality was not used to detect revived
peers. All peer revival mechanisms (such as TCP probes) remain intact.


Regards,

Eduard.

Do not forward HTTP requests to dead idle peers.

Squid does not forward HTTP transactions to dead peers except when a
dead peer was idle for some time (ten peer connect timeouts or longer).
When the idle peer is still dead, this exception leads to transaction
delays (at best) or client disconnects/errors (at worst), depending on
Squid and client configurations/state. I am removing this exception.

The "use dead idle peer" heuristic was introduced as a small part of a
much bigger bug #14 fix (trunk r6631). AFAICT, the stated goal of the
feature was speeding up failure recovery: The heuristic may result in
HTTP transactions sent to a previously dead (but now alive) idle peer
earlier, before the peer is proven to be alive (using peer revival
mechanisms such as TCP probes). However, the negative side effects of
this heuristic outweigh its accidental benefits. If somebody needs Squid
to detect revived idle peers earlier, they need to add a different
probing mechanism that does not jeopardize HTTP transactions.

Nobody has spoken in defense of this feature on Squid mailing lists:
http://lists.squid-cache.org/pipermail/squid-users/2017-March/014785.html
http://lists.squid-cache.org/pipermail/squid-dev/2017-March/008308.html

The removed functionality was not used to detect revived peers. All peer
revival mechanisms (such as TCP probes) remain intact.

=== modified file 'src/neighbors.cc'
--- src/neighbors.cc	2017-04-12 23:34:50 +0000
+++ src/neighbors.cc	2017-04-18 10:07:37 +0000
@@ -32,61 +32,61 @@
 #include "multicast.h"
 #include "neighbors.h"
 #include "NeighborTypeDomainList.h"
 #include "pconn.h"
 #include "PeerDigest.h"
 #include "PeerPoolMgr.h"
 #include "PeerSelectState.h"
 #include "RequestFlags.h"
 #include "SquidConfig.h"
 #include "SquidMath.h"
 #include "SquidTime.h"
 #include "stat.h"
 #include "Store.h"
 #include "store_key_md5.h"
 #include "tools.h"
 #include "URL.h"
 
 /* count mcast group peers every 15 minutes */
 #define MCAST_COUNT_RATE 900
 
 bool peerAllowedToUse(const CachePeer *, HttpRequest *);
 static int peerWouldBePinged(const CachePeer *, HttpRequest *);
 static void neighborRemove(CachePeer *);
 static void neighborAlive(CachePeer *, const MemObject *, const icp_common_t *);
 #if USE_HTCP
 static void neighborAliveHtcp(CachePeer *, const MemObject *, const HtcpReplyData *);
 #endif
 static void neighborCountIgnored(CachePeer *);
 static void peerRefreshDNS(void *);
 static IPH peerDNSConfigure;
-static bool peerProbeConnect(CachePeer *);
+static void peerProbeConnect(CachePeer *);
 static CNCB peerProbeConnectDone;
 static void peerCountMcastPeersDone(void *data);
 static void peerCountMcastPeersStart(void *data);
 static void peerCountMcastPeersSchedule(CachePeer * p, time_t when);
 static IRCB peerCountHandleIcpReply;
 
 static void neighborIgnoreNonPeer(const Ip::Address &, icp_opcode);
 static OBJH neighborDumpPeers;
 static OBJH neighborDumpNonPeers;
 static void dump_peers(StoreEntry * sentry, CachePeer * peers);
 
 static unsigned short echo_port;
 
 static int NLateReplies = 0;
 static CachePeer *first_ping = NULL;
 
 const char *
 neighborTypeStr(const CachePeer * p)
 {
     if (p->type == PEER_NONE)
         return "Non-Peer";
 
     if (p->type == PEER_SIBLING)
         return "Sibling";
 
     if (p->type == PEER_MULTICAST)
         return "Multicast Group";
 
     return "Parent";
 }
@@ -1096,64 +1096,62 @@
     for (p = Config.peers; p; p = p->next) {
         if (!strcasecmp(name, p->name))
             break;
     }
 
     return p;
 }
 
 CachePeer *
 peerFindByNameAndPort(const char *name, unsigned short port)
 {
     CachePeer *p = NULL;
 
     for (p = Config.peers; p; p = p->next) {
         if (strcasecmp(name, p->name))
             continue;
 
         if (port != p->http_port)
             continue;
 
         break;
     }
 
     return p;
 }
 
 int
 neighborUp(const CachePeer * p)
 {
     if (!p->tcp_up) {
-        if (!peerProbeConnect((CachePeer *) p)) {
-            debugs(15, 8, "neighborUp: DOWN (probed): " << p->host << " (" << p->in_addr << ")");
-            return 0;
-        }
+        peerProbeConnect(const_cast<CachePeer*>(p));
+        return 0;
     }
 
     /*
      * The CachePeer can not be UP if we don't have any IP addresses
      * for it.
      */
     if (0 == p->n_addresses) {
         debugs(15, 8, "neighborUp: DOWN (no-ip): " << p->host << " (" << p->in_addr << ")");
         return 0;
     }
 
     if (p->options.no_query) {
         debugs(15, 8, "neighborUp: UP (no-query): " << p->host << " (" << p->in_addr << ")");
         return 1;
     }
 
     if (p->stats.probe_start != 0 &&
             squid_curtime - p->stats.probe_start > Config.Timeout.deadPeer) {
         debugs(15, 8, "neighborUp: DOWN (dead): " << p->host << " (" << p->in_addr << ")");
         return 0;
     }
 
     debugs(15, 8, "neighborUp: UP: " << p->host << " (" << p->in_addr << ")");
     return 1;
 }
 
 void
 peerNoteDigestGone(CachePeer * p)
 {
 #if USE_CACHE_DIGESTS
@@ -1265,91 +1263,91 @@
 
     if (!p->tcp_up) {
         debugs(15, DBG_IMPORTANT, "Detected DEAD " << neighborTypeStr(p) << ": " << p->name);
         p->stats.logged_state = PEER_DEAD;
     }
 }
 
 void
 peerConnectFailed(CachePeer *p)
 {
     debugs(15, DBG_IMPORTANT, "TCP connection to " << p->host << "/" << p->http_port << " failed");
     peerConnectFailedSilent(p);
 }
 
 void
 peerConnectSucceded(CachePeer * p)
 {
     if (!p->tcp_up) {
         debugs(15, 2, "TCP connection to " << p->host << "/" << p->http_port << " succeded");
         p->tcp_up = p->connect_fail_limit; // NP: so peerAlive(p) works properly.
         peerAlive(p);
         if (!p->n_addresses)
             ipcache_nbgethostbyname(p->host, peerDNSConfigure, p);
     } else
         p->tcp_up = p->connect_fail_limit;
 }
 
 /*
 * peerProbeConnect will be called on dead peers by neighborUp
 */
-static bool
+static void
 peerProbeConnect(CachePeer * p)
 {
+    if (p->testing_now > 0) {
+        debugs(15, 8, "already probing " << p);
+        return;
+    }
+
+    if (squid_curtime - p->stats.last_connect_probe == 0) {
+        debugs(15, 8, "just probed " << p);
+        return;
+    }
+
     const time_t ctimeout = peerConnectTimeout(p);
-    bool ret = (squid_curtime - p->stats.last_connect_failure) > (ctimeout * 10);
-
-    if (p->testing_now > 0)
-        return ret;/* probe already running */
-
-    if (squid_curtime - p->stats.last_connect_probe == 0)
-        return ret;/* don't probe to often */
-
     /* for each IP address of this CachePeer. find one that we can connect to and probe it. */
     for (int i = 0; i < p->n_addresses; ++i) {
         Comm::ConnectionPointer conn = new Comm::Connection;
         conn->remote = p->addresses[i];
         conn->remote.port(p->http_port);
         conn->setPeer(p);
         getOutgoingAddress(NULL, conn);
 
         ++ p->testing_now;
 
         AsyncCall::Pointer call = commCbCall(15,3, "peerProbeConnectDone", CommConnectCbPtrFun(peerProbeConnectDone, p));
         Comm::ConnOpener *cs = new Comm::ConnOpener(conn, call, ctimeout);
         cs->setHost(p->host);
         AsyncJob::Start(cs);
     }
 
     p->stats.last_connect_probe = squid_curtime;
-
-    return ret;
 }
 
 static void
 peerProbeConnectDone(const Comm::ConnectionPointer &conn, Comm::Flag status, int, void *data)
 {
     CachePeer *p = (CachePeer*)data;
 
     if (status == Comm::OK) {
         peerConnectSucceded(p);
     } else {
         peerConnectFailedSilent(p);
     }
 
     -- p->testing_now;
     conn->close();
     // TODO: log this traffic.
 }
 
 static void
 peerCountMcastPeersSchedule(CachePeer * p, time_t when)
 {
     if (p->mcast.flags.count_event_pending)
         return;
 
     eventAdd("peerCountMcastPeersStart",
              peerCountMcastPeersStart,
              p,
              (double) when, 1);
 
     p->mcast.flags.count_event_pending = true;

_______________________________________________
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev

Reply via email to