You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by vm...@apache.org on 2018/03/01 23:07:01 UTC

[trafficserver] branch master updated: Add a HostStatus container used to mark down parents externall with an API call.

This is an automated email from the ASF dual-hosted git repository.

vmamidi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 37a7e53  Add a HostStatus container used to mark down parents externall with an API call.
37a7e53 is described below

commit 37a7e53ec9f88994fe4c7ba40933e35499076505
Author: John Rushford <jr...@apache.org>
AuthorDate: Thu Feb 22 15:35:45 2018 +0000

    Add a HostStatus container used to mark down parents
    externall with an API call.
---
 proxy/HostStatus.cc           | 59 +++++++++++++++++++++++++++++++
 proxy/HostStatus.h            | 68 +++++++++++++++++++++++++++++++++++
 proxy/Makefile.am             |  4 ++-
 proxy/ParentConsistentHash.cc |  7 ++--
 proxy/ParentRoundRobin.cc     | 12 ++++---
 proxy/ParentSelection.cc      | 82 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 224 insertions(+), 8 deletions(-)

diff --git a/proxy/HostStatus.cc b/proxy/HostStatus.cc
new file mode 100644
index 0000000..33bee19
--- /dev/null
+++ b/proxy/HostStatus.cc
@@ -0,0 +1,59 @@
+/** @file
+
+  Implementation of Host Proxy routing
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+#include "HostStatus.h"
+
+HostStatus::HostStatus() : hosts_statuses(ink_hash_table_create(InkHashTableKeyType_String))
+{
+  ink_mutex_init(&hosts_statuses_mutex);
+}
+
+HostStatus::~HostStatus()
+{
+  ink_hash_table_destroy(hosts_statuses);
+
+  ink_mutex_destroy(&hosts_statuses_mutex);
+}
+
+void
+HostStatus::setHostStatus(const char *key, HostStatus_t status)
+{
+  Debug("host_statuses", "HostStatus::setHostStatus():  key: %s, status: %d", key, status);
+  ink_mutex_acquire(&hosts_statuses_mutex);
+  // update / insert status.
+  // using the hash table pointer to store the HostStatus_t value.
+  ink_hash_table_insert(hosts_statuses, key, reinterpret_cast<void *>(status));
+
+  ink_mutex_release(&hosts_statuses_mutex);
+}
+
+HostStatus_t
+HostStatus::getHostStatus(const char *key)
+{
+  intptr_t _status = HostStatus_t::HOST_STATUS_INIT;
+
+  // the hash table value pointer has the HostStatus_t value.
+  ink_hash_table_lookup(hosts_statuses, key, reinterpret_cast<void **>(&_status));
+  Debug("host_statuses", "HostStatus::getHostStatus():  key: %s, status: %d", key, static_cast<int>(_status));
+
+  return static_cast<HostStatus_t>(_status);
+}
diff --git a/proxy/HostStatus.h b/proxy/HostStatus.h
new file mode 100644
index 0000000..87ebba6
--- /dev/null
+++ b/proxy/HostStatus.h
@@ -0,0 +1,68 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+/*****************************************************************************
+ *
+ *  HostSelection.h - Interface to Host Selection System
+ *
+ *
+ ****************************************************************************/
+
+#ifndef _HOST_SELECTION_H_
+#define _HOST_SELECTION_H_
+
+#include "ControlBase.h"
+#include "ControlMatcher.h"
+#include "P_RecProcess.h"
+
+enum HostStatus_t {
+  HOST_STATUS_INIT,
+  HOST_STATUS_UP,
+  HOST_STATUS_DOWN,
+};
+
+/**
+ * Singleton placeholder for next hop status.
+ */
+struct HostStatus {
+  ~HostStatus();
+
+  static HostStatus &
+  instance()
+  {
+    static HostStatus instance;
+    return instance;
+  } // return the signleton pointer.
+  void setHostStatus(const char *key, const HostStatus_t status);
+  HostStatus_t getHostStatus(const char *key);
+
+private:
+  HostStatus();
+  HostStatus(const HostStatus &obj) = delete;
+  HostStatus &operator=(HostStatus const &) = delete;
+
+  InkHashTable *hosts_statuses; // next hop status, key is hostname or ip string, data is bool (available).
+  ink_mutex hosts_statuses_mutex;
+};
+
+#endif
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index da5cf67..5e4892e 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -136,6 +136,8 @@ traffic_server_SOURCES = \
   Crash.cc \
   EventName.cc \
   FetchSM.cc \
+  HostStatus.cc \
+  HostStatus.h \
   IPAllow.cc \
   IPAllow.h \
   InkAPI.cc \
@@ -148,7 +150,7 @@ traffic_server_SOURCES = \
   ParentConsistentHash.h \
   ParentRoundRobin.cc \
   ParentRoundRobin.h \
-	ParentSelectionStrategy.cc \
+  ParentSelectionStrategy.cc \
   ParentSelection.cc \
   ParentSelection.h \
   Plugin.cc \
diff --git a/proxy/ParentConsistentHash.cc b/proxy/ParentConsistentHash.cc
index d2d988d..5c95da0 100644
--- a/proxy/ParentConsistentHash.cc
+++ b/proxy/ParentConsistentHash.cc
@@ -20,6 +20,7 @@
   See the License for the specific language governing permissions and
   limitations under the License.
  */
+#include "HostStatus.h"
 #include "ParentConsistentHash.h"
 
 ParentConsistentHash::ParentConsistentHash(ParentRecord *parent_record)
@@ -115,6 +116,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques
   uint64_t path_hash            = 0;
   uint32_t last_lookup;
   pRecord *prtmp = nullptr, *pRec = nullptr;
+  HostStatus &pStatus = HostStatus::instance();
 
   Debug("parent_select", "ParentConsistentHash::%s(): Using a consistent hash parent selection strategy.", __func__);
   ink_assert(numParents(result) > 0 || result->rec->go_direct == true);
@@ -165,9 +167,8 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques
       } while (prtmp && strcmp(prtmp->hostname, result->hostname) == 0);
     }
   }
-
   // didn't find a parent or the parent is marked unavailable.
-  if (!pRec || (pRec && !pRec->available)) {
+  if ((pRec && !pRec->available) || pStatus.getHostStatus(pRec->hostname) == HOST_STATUS_DOWN) {
     do {
       if (pRec && !pRec->available) {
         Debug("parent_select", "Parent.failedAt = %u, retry = %u, xact_start = %u", (unsigned int)pRec->failedAt,
@@ -215,7 +216,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques
         Debug("parent_select", "No available parents.");
         break;
       }
-    } while (!prtmp || !pRec->available);
+    } while (!prtmp || !pRec->available || pStatus.getHostStatus(pRec->hostname) == HOST_STATUS_DOWN);
   }
 
   // use the available or marked for retry parent.
diff --git a/proxy/ParentRoundRobin.cc b/proxy/ParentRoundRobin.cc
index 7b2ba6e..52eecb7 100644
--- a/proxy/ParentRoundRobin.cc
+++ b/proxy/ParentRoundRobin.cc
@@ -20,6 +20,7 @@
   See the License for the specific language governing permissions and
   limitations under the License.
  */
+#include "HostStatus.h"
 #include "ParentRoundRobin.h"
 
 ParentRoundRobin::ParentRoundRobin(ParentRecord *parent_record, ParentRR_t _round_robin_type)
@@ -60,9 +61,10 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat
                                unsigned int retry_time)
 {
   Debug("parent_select", "In ParentRoundRobin::selectParent(): Using a round robin parent selection strategy.");
-  int cur_index    = 0;
-  bool parentUp    = false;
-  bool parentRetry = false;
+  int cur_index       = 0;
+  bool parentUp       = false;
+  bool parentRetry    = false;
+  HostStatus &pStatus = HostStatus::instance();
 
   HttpRequestData *request_info = static_cast<HttpRequestData *>(rdata);
 
@@ -131,6 +133,7 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat
       }
     }
   }
+
   // Loop through the array of parent seeing if any are up or
   //   should be retried
   do {
@@ -154,7 +157,8 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat
       }
     }
 
-    if (parentUp == true) {
+    if (parentUp == true && pStatus.getHostStatus(parents[cur_index].hostname) != HOST_STATUS_DOWN) {
+      Debug("parent_select", "status for %s: %d", parents[cur_index].hostname, pStatus.getHostStatus(parents[cur_index].hostname));
       result->result      = PARENT_SPECIFIED;
       result->hostname    = parents[cur_index].hostname;
       result->port        = parents[cur_index].port;
diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc
index 2d64d24..79d541b 100644
--- a/proxy/ParentSelection.cc
+++ b/proxy/ParentSelection.cc
@@ -27,6 +27,7 @@
 #include "ControlMatcher.h"
 #include "Main.h"
 #include "ProxyConfig.h"
+#include "HostStatus.h"
 #include "HTTP.h"
 #include "HttpTransact.h"
 #include "I_Machine.h"
@@ -1386,6 +1387,87 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */,
   sleep(1);
   RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 183);
 
+  // Test 184
+  // mark fuzzy down with HostStatus API.
+  HostStatus &_st = HostStatus::instance();
+  _st.setHostStatus("fuzzy", HOST_STATUS_DOWN);
+
+  ST(184);
+  REINIT;
+  br(request, "i.am.rabbit.net");
+  FP;
+  sleep(1);
+  RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 184);
+
+  // Test 185
+  // mark fluffy down and expect furry to be chosen
+  _st.setHostStatus("fluffy", HOST_STATUS_DOWN);
+
+  ST(185);
+  REINIT;
+  br(request, "i.am.rabbit.net");
+  FP;
+  sleep(1);
+  RE(verify(result, PARENT_SPECIFIED, "furry", 80), 185);
+
+  // Test 186
+  // mark furry and frisky down, fuzzy up and expect fuzzy to be chosen
+  _st.setHostStatus("furry", HOST_STATUS_DOWN);
+  _st.setHostStatus("frisky", HOST_STATUS_DOWN);
+  _st.setHostStatus("fuzzy", HOST_STATUS_UP);
+
+  ST(186);
+  REINIT;
+  br(request, "i.am.rabbit.net");
+  FP;
+  sleep(1);
+  RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 186);
+
+  // test
+  // test the HostStatus API with ParentConsistent Hash.
+  tbl[0] = '\0';
+  ST(178);
+  T("dest_domain=rabbit.net parent=fuzzy:80|1.0;fluffy:80|1.0;furry:80|1.0;frisky:80|1.0 "
+    "round_robin=consistent_hash go_direct=false\n");
+  REBUILD;
+  REINIT;
+
+  // mark all up.
+  _st.setHostStatus("furry", HOST_STATUS_UP);
+  _st.setHostStatus("fluffy", HOST_STATUS_UP);
+  _st.setHostStatus("frisky", HOST_STATUS_UP);
+  _st.setHostStatus("fuzzy", HOST_STATUS_UP);
+
+  // Test 187
+  ST(187);
+  REINIT;
+  br(request, "i.am.rabbit.net");
+  FP;
+  sleep(1);
+  RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 187);
+
+  // Test 188
+  // mark fuzzy down and expect fluffy.
+  _st.setHostStatus("fuzzy", HOST_STATUS_DOWN);
+
+  ST(188);
+  REINIT;
+  br(request, "i.am.rabbit.net");
+  FP;
+  sleep(1);
+  RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 188);
+
+  // Test 189
+  // mark fuzzy back up and expect fuzzy.
+  _st.setHostStatus("fuzzy", HOST_STATUS_UP);
+
+  ST(189);
+  REINIT;
+  br(request, "i.am.rabbit.net");
+  FP;
+  sleep(1);
+  RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 189);
+
   delete request;
   delete result;
   delete params;

-- 
To stop receiving notification emails like this one, please contact
vmamidi@apache.org.