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;