You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by so...@apache.org on 2015/12/14 20:45:40 UTC

trafficserver git commit: TS-4030: Allow parent selection to ignore query string

Repository: trafficserver
Updated Branches:
  refs/heads/master 596512ecf -> 5f251bdf2


TS-4030: Allow parent selection to ignore query string

This closes #369.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/5f251bdf
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/5f251bdf
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/5f251bdf

Branch: refs/heads/master
Commit: 5f251bdf293dc6b59e362d5ea81fe2fc7dc4d489
Parents: 596512e
Author: Phil Sorber <so...@apache.org>
Authored: Thu Nov 19 10:32:55 2015 -0700
Committer: Phil Sorber <so...@apache.org>
Committed: Mon Dec 14 12:37:05 2015 -0700

----------------------------------------------------------------------
 lib/ts/ConsistentHash.cc |  29 +++++++++++-
 lib/ts/ConsistentHash.h  |   1 +
 proxy/ParentSelection.cc | 106 +++++++++++++++++++++++++++---------------
 proxy/ParentSelection.h  |   7 ++-
 4 files changed, 104 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/5f251bdf/lib/ts/ConsistentHash.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ConsistentHash.cc b/lib/ts/ConsistentHash.cc
index 461c39f..9acbab6 100644
--- a/lib/ts/ConsistentHash.cc
+++ b/lib/ts/ConsistentHash.cc
@@ -106,7 +106,6 @@ ATSConsistentHash::lookup(const char *url, ATSConsistentHashIter *i, bool *w, AT
       *wptr = true;
       *iter = NodeMap.begin();
     }
-
   } else {
     (*iter)++;
   }
@@ -179,6 +178,34 @@ ATSConsistentHash::lookup_available(const char *url, ATSConsistentHashIter *i, b
   return (*iter)->second;
 }
 
+ATSConsistentHashNode *
+ATSConsistentHash::lookup_by_hashval(uint64_t hashval, ATSConsistentHashIter *i, bool *w)
+{
+  ATSConsistentHashIter NodeMapIterUp, *iter;
+  bool *wptr, wrapped = false;
+
+  if (w) {
+    wptr = w;
+  } else {
+    wptr = &wrapped;
+  }
+
+  if (i) {
+    iter = i;
+  } else {
+    iter = &NodeMapIterUp;
+  }
+
+  *iter = NodeMap.lower_bound(hashval);
+
+  if (*iter == NodeMap.end()) {
+    *wptr = true;
+    *iter = NodeMap.begin();
+  }
+
+  return (*iter)->second;
+}
+
 ATSConsistentHash::~ATSConsistentHash()
 {
   if (hash) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/5f251bdf/lib/ts/ConsistentHash.h
----------------------------------------------------------------------
diff --git a/lib/ts/ConsistentHash.h b/lib/ts/ConsistentHash.h
index 1440b23..d1a34ba 100644
--- a/lib/ts/ConsistentHash.h
+++ b/lib/ts/ConsistentHash.h
@@ -52,6 +52,7 @@ struct ATSConsistentHash {
   ATSConsistentHashNode *lookup(const char *url = NULL, ATSConsistentHashIter *i = NULL, bool *w = NULL, ATSHash64 *h = NULL);
   ATSConsistentHashNode *lookup_available(const char *url = NULL, ATSConsistentHashIter *i = NULL, bool *w = NULL,
                                           ATSHash64 *h = NULL);
+  ATSConsistentHashNode *lookup_by_hashval(uint64_t hashval, ATSConsistentHashIter *i = NULL, bool *w = NULL);
   ~ATSConsistentHash();
 
 private:

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/5f251bdf/proxy/ParentSelection.cc
----------------------------------------------------------------------
diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc
index 9000982..69ce74c 100644
--- a/proxy/ParentSelection.cc
+++ b/proxy/ParentSelection.cc
@@ -472,6 +472,34 @@ ParentConfigParams::nextParent(HttpRequestData *rdata, ParentResult *result)
 //   End API functions
 //
 
+uint64_t
+ParentRecord::getPathHash(HttpRequestData *hrdata, ATSHash64 *h)
+{
+  const char *tmp = NULL;
+  int len;
+  URL *url = hrdata->hdr->url_get();
+
+  // Always hash on '/' because paths returned by ATS are always stripped of it
+  h->update("/", 1);
+
+  tmp = url->path_get(&len);
+  if (tmp) {
+    h->update(tmp, len);
+  }
+
+  if (!ignore_query) {
+    tmp = url->query_get(&len);
+    if (tmp) {
+      h->update("?", 1);
+      h->update(tmp, len);
+    }
+  }
+
+  h->final();
+
+  return h->get();
+}
+
 void
 ParentRecord::FindParent(bool first_call, ParentResult *result, RequestData *rdata, ParentConfigParams *config)
 {
@@ -480,29 +508,23 @@ ParentRecord::FindParent(bool first_call, ParentResult *result, RequestData *rda
   bool parentUp = false;
   bool parentRetry = false;
   bool bypass_ok = (go_direct == true && config->DNS_ParentOnly == 0);
-  char *url, *path = NULL;
+  uint64_t path_hash;
+
   ATSHash64Sip24 hash;
   pRecord *prtmp = NULL;
 
-  HttpRequestData *request_info = (HttpRequestData *)rdata;
+  HttpRequestData *request_info = static_cast<HttpRequestData *>(rdata);
 
   ink_assert(num_parents > 0 || go_direct == true);
 
-  if (first_call == true) {
+  if (first_call) {
     if (parents == NULL) {
       // We should only get into this state if
-      //   if we are supposed to go dirrect
+      //   if we are supposed to go direct
       ink_assert(go_direct == true);
       goto NO_PARENTS;
-    } else if (round_robin == true) {
-      cur_index = ink_atomic_increment((int32_t *)&rr_next, 1);
-      cur_index = result->start_parent = cur_index % num_parents;
     } else {
       switch (round_robin) {
-      case P_STRICT_ROUND_ROBIN:
-        cur_index = ink_atomic_increment((int32_t *)&rr_next, 1);
-        cur_index = cur_index % num_parents;
-        break;
       case P_HASH_ROUND_ROBIN:
         // INKqa12817 - make sure to convert to host byte order
         // Why was it important to do host order here?  And does this have any
@@ -516,24 +538,24 @@ ParentRecord::FindParent(bool first_call, ParentResult *result, RequestData *rda
         }
         break;
       case P_CONSISTENT_HASH:
-        url = rdata->get_string();
-        path = strstr(url + 7, "/");
-        if (path) {
-          prtmp = (pRecord *)chash->lookup(path, &(result->chashIter), NULL, (ATSHash64 *)&hash);
+        path_hash = getPathHash(request_info, (ATSHash64 *)&hash);
+        if (path_hash) {
+          prtmp = (pRecord *)chash->lookup_by_hashval(path_hash, &result->chashIter, &result->wrap_around);
           if (prtmp) {
             cur_index = prtmp->idx;
             result->foundParents[cur_index] = true;
             result->start_parent++;
+            break;
           } else {
             Error("Consistent Hash loopup returned NULL");
-            cur_index = ink_atomic_increment((int32_t *)&rr_next, 1);
-            cur_index = cur_index % num_parents;
           }
         } else {
-          Error("Could not find path in URL: %s", url);
-          cur_index = ink_atomic_increment((int32_t *)&rr_next, 1);
-          cur_index = cur_index % num_parents;
+          Error("Could not find path");
         }
+      // Fall through to round robin
+      case P_STRICT_ROUND_ROBIN:
+        cur_index = ink_atomic_increment((int32_t *)&rr_next, 1);
+        cur_index = cur_index % num_parents;
         break;
       case P_NO_ROUND_ROBIN:
         cur_index = result->start_parent = 0;
@@ -544,22 +566,26 @@ ParentRecord::FindParent(bool first_call, ParentResult *result, RequestData *rda
     }
   } else {
     if (round_robin == P_CONSISTENT_HASH) {
+      Debug("parent_select", "result->start_parent=%d, num_parents=%d", result->start_parent, num_parents);
       if (result->start_parent == (unsigned int)num_parents) {
         result->wrap_around = true;
         result->start_parent = 0;
         memset(result->foundParents, 0, sizeof(result->foundParents));
-        url = rdata->get_string();
-        path = strstr(url + 7, "/");
       }
 
       do {
-        prtmp = (pRecord *)chash->lookup(path, &(result->chashIter), NULL, (ATSHash64 *)&hash);
-        path = NULL;
-      } while (result->foundParents[prtmp->idx]);
+        prtmp = (pRecord *)chash->lookup(NULL, &result->chashIter, &result->wrap_around, &hash);
+      } while (prtmp && result->foundParents[prtmp->idx]);
 
-      cur_index = prtmp->idx;
-      result->foundParents[cur_index] = true;
-      result->start_parent++;
+      if (prtmp) {
+        cur_index = prtmp->idx;
+        result->foundParents[cur_index] = true;
+        result->start_parent++;
+      } else {
+        Error("Consistent Hash loopup returned NULL");
+        cur_index = ink_atomic_increment((int32_t *)&rr_next, 1);
+        cur_index = cur_index % num_parents;
+      }
     } else {
       // Move to next parent due to failure
       cur_index = (result->last_parent + 1) % num_parents;
@@ -598,7 +624,6 @@ ParentRecord::FindParent(bool first_call, ParentResult *result, RequestData *rda
         parentUp = true;
         parentRetry = true;
         Debug("parent_select", "Parent marked for retry %s:%d", parents[cur_index].hostname, parents[cur_index].port);
-
       } else {
         parentUp = false;
       }
@@ -621,18 +646,17 @@ ParentRecord::FindParent(bool first_call, ParentResult *result, RequestData *rda
         result->wrap_around = false;
         result->start_parent = 0;
         memset(result->foundParents, 0, sizeof(result->foundParents));
-        url = rdata->get_string();
-        path = strstr(url + 7, "/");
       }
 
       do {
-        prtmp = (pRecord *)chash->lookup(path, &(result->chashIter), NULL, (ATSHash64 *)&hash);
-        path = NULL;
-      } while (result->foundParents[prtmp->idx]);
+        prtmp = (pRecord *)chash->lookup(NULL, &(result->chashIter), &result->wrap_around, &hash);
+      } while (prtmp && result->foundParents[prtmp->idx]);
 
-      cur_index = prtmp->idx;
-      result->foundParents[cur_index] = true;
-      result->start_parent++;
+      if (prtmp) {
+        cur_index = prtmp->idx;
+        result->foundParents[cur_index] = true;
+        result->start_parent++;
+      }
     } else {
       cur_index = (cur_index + 1) % num_parents;
     }
@@ -784,6 +808,7 @@ ParentRecord::DefaultInit(char *val)
 
   this->go_direct = true;
   this->round_robin = P_NO_ROUND_ROBIN;
+  this->ignore_query = false;
   this->scheme = NULL;
   errPtr = ProcessParents(val);
 
@@ -877,6 +902,13 @@ ParentRecord::Init(matcher_line *line_info)
         go_direct = true;
       }
       used = true;
+    } else if (strcasecmp(label, "qstring") == 0) {
+      // qstring=ignore | consider
+      if (strcasecmp(val, "ignore") == 0) {
+        this->ignore_query = true;
+      } else {
+        this->ignore_query = false;
+      }
     }
     // Report errors generated by ProcessParents();
     if (errPtr != NULL) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/5f251bdf/proxy/ParentSelection.h
----------------------------------------------------------------------
diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h
index a74b659..8dc428c 100644
--- a/proxy/ParentSelection.h
+++ b/proxy/ParentSelection.h
@@ -195,7 +195,10 @@ enum ParentRR_t {
 class ParentRecord : public ControlBase
 {
 public:
-  ParentRecord() : parents(NULL), num_parents(0), round_robin(P_NO_ROUND_ROBIN), rr_next(0), go_direct(true), chash(NULL) {}
+  ParentRecord()
+    : parents(NULL), num_parents(0), round_robin(P_NO_ROUND_ROBIN), ignore_query(false), rr_next(0), go_direct(true), chash(NULL)
+  {
+  }
 
   ~ParentRecord();
 
@@ -203,6 +206,7 @@ public:
   bool DefaultInit(char *val);
   void UpdateMatch(ParentResult *result, RequestData *rdata);
   void FindParent(bool firstCall, ParentResult *result, RequestData *rdata, ParentConfigParams *config);
+  uint64_t getPathHash(HttpRequestData *hrdata, ATSHash64 *h);
   void Print();
   pRecord *parents;
   int num_parents;
@@ -218,6 +222,7 @@ public:
   const char *ProcessParents(char *val);
   void buildConsistentHash(void);
   ParentRR_t round_robin;
+  bool ignore_query;
   volatile uint32_t rr_next;
   bool go_direct;
   ATSConsistentHash *chash;