From b46f8a97230d6d2e07cc87c5976037fe0216822e Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Fri, 29 May 2020 10:44:00 -0600 Subject: [PATCH 01/15] Add nexthop strategy plugins Adds a remap plugin hook to add a strategy object, and moves and adds other necessary API symbols necessary to implement strategies in plugins. Also adds an example strategy plugin. --- include/ts/apidefs.h.in | 36 ++ include/ts/nexthop.h | 24 +- include/ts/parentresult.h | 51 ++ include/ts/ts.h | 30 ++ iocore/cache/test/stub.cc | 2 +- iocore/net/Socks.cc | 14 +- plugins/Makefile.am | 1 + .../Makefile.inc | 29 ++ .../consistenthash.cc | 476 ++++++++++++++++++ .../consistenthash.h | 48 ++ .../consistenthash_config.cc | 204 ++++++++ .../consistenthash_config.h | 26 + .../healthstatus.cc | 146 ++++++ .../healthstatus.h | 39 ++ .../plugin_consistenthash.cc | 133 +++++ .../strategy.cc | 344 +++++++++++++ .../strategy.h | 233 +++++++++ .../nexthop_strategy_consistenthash/util.h | 55 ++ proxy/HostStatus.h | 13 +- proxy/ParentConsistentHash.cc | 102 ++-- proxy/ParentConsistentHash.h | 2 +- proxy/ParentRoundRobin.cc | 74 +-- proxy/ParentSelection.cc | 114 ++--- proxy/ParentSelection.h | 52 +- proxy/ParentSelectionStrategy.cc | 24 +- proxy/http/HttpSM.cc | 6 +- proxy/http/HttpTransact.cc | 62 ++- proxy/http/HttpTransact.h | 4 +- proxy/http/remap/NextHopConsistentHash.cc | 107 ++-- proxy/http/remap/NextHopConsistentHash.h | 13 +- proxy/http/remap/NextHopHealthStatus.cc | 36 +- proxy/http/remap/NextHopRoundRobin.cc | 94 ++-- proxy/http/remap/NextHopRoundRobin.h | 13 +- proxy/http/remap/NextHopSelectionStrategy.cc | 43 +- proxy/http/remap/NextHopSelectionStrategy.h | 40 +- proxy/http/remap/NextHopStrategyFactory.cc | 38 +- proxy/http/remap/NextHopStrategyFactory.h | 6 +- proxy/http/remap/PluginDso.cc | 6 + proxy/http/remap/PluginDso.h | 1 + proxy/http/remap/PluginFactory.cc | 10 + proxy/http/remap/PluginFactory.h | 4 + proxy/http/remap/RemapConfig.cc | 53 +- proxy/http/remap/RemapPluginInfo.cc | 27 + proxy/http/remap/RemapPluginInfo.h | 8 + proxy/http/remap/UrlMapping.h | 4 +- .../remap/unit-tests/nexthop_test_stubs.cc | 4 +- .../unit-tests/test_NextHopConsistentHash.cc | 216 ++++---- .../unit-tests/test_NextHopRoundRobin.cc | 99 ++-- .../unit-tests/test_NextHopStrategyFactory.cc | 437 ++++++++-------- src/traffic_server/HostStatus.cc | 38 +- src/traffic_server/InkAPI.cc | 37 ++ 51 files changed, 2825 insertions(+), 853 deletions(-) create mode 100644 include/ts/parentresult.h create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/Makefile.inc create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/strategy.cc create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/strategy.h create mode 100644 plugins/experimental/nexthop_strategy_consistenthash/util.h diff --git a/include/ts/apidefs.h.in b/include/ts/apidefs.h.in index 27e1522dd91..3b35b7edceb 100644 --- a/include/ts/apidefs.h.in +++ b/include/ts/apidefs.h.in @@ -1308,6 +1308,42 @@ extern tsapi const char *const TS_PROTO_TAG_IPV6; */ #define TS_NULL_MLOC ((TSMLoc)0) +/* -------------------------------------------------------------------------- + HostStatus types */ + +typedef enum { + TS_HOST_STATUS_INIT, + TS_HOST_STATUS_DOWN, + TS_HOST_STATUS_UP, +} TSHostStatus; + +/* MUST match proxy/HostStatus.h Reason. + * If a value is added here, it MUST be added there with the same value. + */ +typedef enum { + TS_HOST_STATUS_ACTIVE = 0x1, + TS_HOST_STATUS_LOCAL = 0x2, + TS_HOST_STATUS_MANUAL = 0x4, + TS_HOST_STATUS_SELF_DETECT = 0x8, + TS_HOST_STATUS_ALL = 0xf, +} TSHostStatusReason; + +/* -------------------------------------------------------------------------- + ParentResult API types */ + +// used in ParentSelection to to set the number of ATSConsistentHashIter's +// used in NextHopSelectionStrategy to limit the host group +// size as well, group size is one to one with the number of rings +#define TS_MAX_GROUP_RINGS 5 + +enum TSParentResultType { + PARENT_UNDEFINED, + PARENT_DIRECT, + PARENT_SPECIFIED, + PARENT_AGENT, + PARENT_FAIL, +}; + /* -------------------------------------------------------------------------- Interface for the UUID APIs. https://www.ietf.org/rfc/rfc4122.txt. */ typedef enum { diff --git a/include/ts/nexthop.h b/include/ts/nexthop.h index ed623805649..f1a2d6eb0a4 100644 --- a/include/ts/nexthop.h +++ b/include/ts/nexthop.h @@ -30,20 +30,20 @@ #include -// plugin callback commands. enum NHCmd { NH_MARK_UP, NH_MARK_DOWN }; -struct NHHealthStatus { - virtual bool isNextHopAvailable(TSHttpTxn txn, const char *hostname, const int port, void *ih = nullptr) = 0; - virtual void markNextHop(TSHttpTxn txn, const char *hostname, const int port, const NHCmd status, void *ih = nullptr, - const time_t now = 0) = 0; - virtual ~NHHealthStatus() {} -}; +class TSNextHopSelectionStrategy +{ +public: + TSNextHopSelectionStrategy() {}; + virtual ~TSNextHopSelectionStrategy() {}; -struct NHPluginStrategy { - virtual void findNextHop(TSHttpTxn txnp, void *ih = nullptr) = 0; - virtual bool nextHopExists(TSHttpTxn txnp, void *ih = nullptr) = 0; - virtual ~NHPluginStrategy() {} + virtual void findNextHop(TSHttpTxn txnp, time_t now = 0) = 0; + virtual void markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now = 0) = 0; + virtual bool nextHopExists(TSHttpTxn txnp) = 0; + virtual bool responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) = 0; + virtual bool onFailureMarkParentDown(TSHttpStatus response_code) = 0; - NHHealthStatus *healthStatus; + virtual bool goDirect() = 0; + virtual bool parentIsProxy() = 0; }; diff --git a/include/ts/parentresult.h b/include/ts/parentresult.h new file mode 100644 index 00000000000..149533b3675 --- /dev/null +++ b/include/ts/parentresult.h @@ -0,0 +1,51 @@ +/** @file + + @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. + */ + +#pragma once + +#include "ts/apidefs.h" +#include "tscore/ConsistentHash.h" + +// Needed by core. Disabling the warning for plugins +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +static const char *ParentResultStr[] = {"PARENT_UNDEFINED", "PARENT_DIRECT", "PARENT_SPECIFIED", "PARENT_AGENT", "PARENT_FAIL"}; +#pragma GCC diagnostic pop + +struct TSParentResult { + const char *hostname; + int port; + bool retry; + TSParentResultType result; + bool chash_init[TS_MAX_GROUP_RINGS] = {false}; + TSHostStatus first_choice_status = TSHostStatus::TS_HOST_STATUS_INIT; + // Internal use only + // Not to be modified by HTTP + int line_number; + uint32_t last_parent; + uint32_t start_parent; + uint32_t last_group; + bool wrap_around; + bool mapWrapped[2]; + // state for consistent hash. + int last_lookup; + ATSConsistentHashIter chashIter[TS_MAX_GROUP_RINGS]; +}; diff --git a/include/ts/ts.h b/include/ts/ts.h index 4c4565e683f..cecc482fe6d 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -29,6 +29,7 @@ #pragma once +#include #include #ifdef __cplusplus @@ -2609,6 +2610,35 @@ tsapi TSReturnCode TSHttpTxnClientStreamIdGet(TSHttpTxn txnp, uint64_t *stream_i */ tsapi TSReturnCode TSHttpTxnClientStreamPriorityGet(TSHttpTxn txnp, TSHttpPriority *priority); +/* + * Returns whether hostname is this machine, as used for parent and remap self-detection. + */ +bool TSHostnameIsSelf(const char* hostname); + +/* + * Gets the status of hostname in the outparam status, and the status reason in the outparam reason. + * The reason is a logical-and combination of the reasons in TSHostStatusReason. + * If either outparam is null, it will not be set and no error will be returned. + * Returns whether the hostname was a parent and existed in the HostStatus. + */ +bool TSHostStatusGet(const char *hostname, TSHostStatus* status, unsigned int *reason); + +/* + * Sets the status of hostname in status, down_time, and reason. + * The reason is a logical-and combination of the reasons in TSHostStatusReason. + */ +void TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int down_time, const unsigned int reason); + +struct TSParentResult; + +/* + * Gets the Transaction Parent Result pointer. + * Note this is the actual pointer inside the TSHttpTxn. + * It MUST NOT be freed. The data it points to may be modified. + */ +struct TSParentResult* +TSHttpTxnParentResultGet(TSHttpTxn txnp); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/iocore/cache/test/stub.cc b/iocore/cache/test/stub.cc index 65f81e79c05..dcc232c1a2c 100644 --- a/iocore/cache/test/stub.cc +++ b/iocore/cache/test/stub.cc @@ -157,7 +157,7 @@ ts::svtoi(TextView src, TextView *out, int base) } void -HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned int down_time, const unsigned int reason) +HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned int down_time, const unsigned int reason) { } diff --git a/iocore/net/Socks.cc b/iocore/net/Socks.cc index dbc2a02835a..251396092a4 100644 --- a/iocore/net/Socks.cc +++ b/iocore/net/Socks.cc @@ -90,7 +90,7 @@ SocksEntry::findServer() #ifdef SOCKS_WITH_TS if (nattempts == 1) { - ink_assert(server_result.result == PARENT_UNDEFINED); + ink_assert(server_result.ts_result.result == PARENT_UNDEFINED); server_params->findParent(&req_data, &server_result, fail_threshold, retry_time); } else { socks_conf_struct *conf = netProcessor.socks_conf_stuff; @@ -101,21 +101,21 @@ SocksEntry::findServer() server_params->markParentDown(&server_result, fail_threshold, retry_time); if (nattempts > conf->connection_attempts) { - server_result.result = PARENT_FAIL; + server_result.ts_result.result = PARENT_FAIL; } else { server_params->nextParent(&req_data, &server_result, fail_threshold, retry_time); } } - switch (server_result.result) { + switch (server_result.ts_result.result) { case PARENT_SPECIFIED: // Original was inet_addr, but should hostnames work? // ats_ip_pton only supports numeric (because other clients // explicitly want to avoid hostname lookups). - if (0 == ats_ip_pton(server_result.hostname, &server_addr)) { - ats_ip_port_cast(&server_addr) = htons(server_result.port); + if (0 == ats_ip_pton(server_result.ts_result.hostname, &server_addr)) { + ats_ip_port_cast(&server_addr) = htons(server_result.ts_result.port); } else { - Debug("SocksParent", "Invalid parent server specified %s", server_result.hostname); + Debug("SocksParent", "Invalid parent server specified %s", server_result.ts_result.hostname); } break; @@ -151,7 +151,7 @@ SocksEntry::free() } #ifdef SOCKS_WITH_TS - if (!lerrno && netVConnection && server_result.retry) { + if (!lerrno && netVConnection && server_result.ts_result.retry) { server_params->markParentUp(&server_result); } #endif diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 52ce5d8bfdc..d4512727d6f 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -63,6 +63,7 @@ include experimental/cert_reporting_tool/Makefile.inc include experimental/collapsed_forwarding/Makefile.inc include experimental/cookie_remap/Makefile.inc include experimental/custom_redirect/Makefile.inc +include experimental/nexthop_strategy_consistenthash/Makefile.inc include experimental/fq_pacing/Makefile.inc include experimental/geoip_acl/Makefile.inc include experimental/header_freq/Makefile.inc diff --git a/plugins/experimental/nexthop_strategy_consistenthash/Makefile.inc b/plugins/experimental/nexthop_strategy_consistenthash/Makefile.inc new file mode 100644 index 00000000000..c75eb8e7d76 --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/Makefile.inc @@ -0,0 +1,29 @@ +# 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. + +pkglib_LTLIBRARIES += experimental/nexthop_strategy_consistenthash/nexthop_strategy_consistenthash.la + +experimental_nexthop_strategy_consistenthash_nexthop_strategy_consistenthash_la_SOURCES = \ + experimental/nexthop_strategy_consistenthash/strategy.cc \ + experimental/nexthop_strategy_consistenthash/healthstatus.cc \ + experimental/nexthop_strategy_consistenthash/consistenthash.cc \ + experimental/nexthop_strategy_consistenthash/consistenthash_config.cc \ + experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc + +experimental_nexthop_strategy_consistenthash_nexthop_strategy_consistenthash_la_LDFLAGS = \ + $(AM_LDFLAGS) + +AM_CPPFLAGS += @YAMLCPP_INCLUDES@ $(TS_INCLUDES) diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc new file mode 100644 index 00000000000..662c685eddd --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -0,0 +1,476 @@ +/* + * 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 "strategy.h" +#include "consistenthash.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "tscore/HashSip.h" +#include "tscore/ConsistentHash.h" +#include "tscore/ink_assert.h" +#include "ts/ts.h" +#include "ts/remap.h" +#include "ts/nexthop.h" +#include "ts/parentresult.h" + +// hash_key strings. +constexpr std::string_view hash_key_url = "url"; +constexpr std::string_view hash_key_hostname = "hostname"; +constexpr std::string_view hash_key_path = "path"; +constexpr std::string_view hash_key_path_query = "path+query"; +constexpr std::string_view hash_key_path_fragment = "path+fragment"; +constexpr std::string_view hash_key_cache = "cache_key"; + +static HostRecord * +chash_lookup(std::shared_ptr ring, uint64_t hash_key, ATSConsistentHashIter *iter, bool *wrapped, + ATSHash64Sip24 *hash, bool *hash_init, bool *mapWrapped, uint64_t sm_id) +{ + HostRecord *host_rec = nullptr; + + if (*hash_init == false) { + host_rec = static_cast(ring->lookup_by_hashval(hash_key, iter, wrapped)); + *hash_init = true; + } else { + host_rec = static_cast(ring->lookup(nullptr, iter, wrapped, hash)); + } + bool wrap_around = *wrapped; + *wrapped = (*mapWrapped && *wrapped) ? true : false; + if (!*mapWrapped && wrap_around) { + *mapWrapped = true; + } + + return host_rec; +} + +NextHopConsistentHash::NextHopConsistentHash(const std::string_view name) + : NextHopSelectionStrategy(name) +{} + +NextHopConsistentHash::~NextHopConsistentHash() +{ + NH_Debug(NH_DEBUG_TAG, "destructor called for strategy named: %s", strategy_name.c_str()); +} + +bool +NextHopConsistentHash::Init(const YAML::Node &n) +{ + ATSHash64Sip24 hash; + + try { + if (n["hash_key"]) { + auto hash_key_val = n["hash_key"].Scalar(); + if (hash_key_val == hash_key_url) { + hash_key = NH_URL_HASH_KEY; + } else if (hash_key_val == hash_key_hostname) { + hash_key = NH_HOSTNAME_HASH_KEY; + } else if (hash_key_val == hash_key_path) { + hash_key = NH_PATH_HASH_KEY; + } else if (hash_key_val == hash_key_path_query) { + hash_key = NH_PATH_QUERY_HASH_KEY; + } else if (hash_key_val == hash_key_path_fragment) { + hash_key = NH_PATH_FRAGMENT_HASH_KEY; + } else if (hash_key_val == hash_key_cache) { + hash_key = NH_CACHE_HASH_KEY; + } else { + hash_key = NH_PATH_HASH_KEY; + NH_Note("Invalid 'hash_key' value, '%s', for the strategy named '%s', using default '%s'.", hash_key_val.c_str(), + strategy_name.c_str(), hash_key_path.data()); + } + } + } catch (std::exception &ex) { + NH_Note("Error parsing the strategy named '%s' due to '%s', this strategy will be ignored.", strategy_name.c_str(), ex.what()); + return false; + } + + bool result = NextHopSelectionStrategy::Init(n); + if (!result) { + return false; + } + + // load up the hash rings. + for (uint32_t i = 0; i < groups; i++) { + std::shared_ptr hash_ring = std::make_shared(); + for (uint32_t j = 0; j < host_groups[i].size(); j++) { + // ATSConsistentHash needs the raw pointer. + HostRecord *p = host_groups[i][j].get(); + // need to copy the 'hash_string' or 'hostname' cstring to 'name' for insertion into ATSConsistentHash. + if (!p->hash_string.empty()) { + p->name = const_cast(p->hash_string.c_str()); + } else { + p->name = const_cast(p->hostname.c_str()); + } + p->group_index = host_groups[i][j]->group_index; + p->host_index = host_groups[i][j]->host_index; + hash_ring->insert(p, p->weight, &hash); + NH_Debug(NH_DEBUG_TAG, "Loading hash rings - ring: %d, host record: %d, name: %s, hostname: %s, stategy: %s", i, j, p->name, + p->hostname.c_str(), strategy_name.c_str()); + } + hash.clear(); + rings.push_back(std::move(hash_ring)); + } + return true; +} + +// returns a hash key calculated from the request and 'hash_key' configuration +// parameter. +uint64_t +NextHopConsistentHash::getHashKey(uint64_t sm_id, TSMBuffer reqp, TSMLoc url, TSMLoc parent_selection_url, ATSHash64 *h) +{ + int len = 0; + const char *url_string_ref = nullptr; + + // calculate a hash using the selected config. + switch (hash_key) { + case NH_URL_HASH_KEY: + url_string_ref = TSUrlStringGet(reqp, url, &len); + if (url_string_ref && len > 0) { + h->update(url_string_ref, len); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] url hash string: %s", sm_id, url_string_ref); + } + break; + // hostname hash + case NH_HOSTNAME_HASH_KEY: + url_string_ref = TSUrlHostGet(reqp, url, &len); + if (url_string_ref && len > 0) { + h->update(url_string_ref, len); + } + break; + // path + query string + case NH_PATH_QUERY_HASH_KEY: + url_string_ref = TSUrlPathGet(reqp, url, &len); + h->update("/", 1); + if (url_string_ref && len > 0) { + h->update(url_string_ref, len); + } + url_string_ref = TSUrlHttpQueryGet(reqp, url, &len); + if (url_string_ref && len > 0) { + h->update("?", 1); + h->update(url_string_ref, len); + } + break; + // path + fragment hash + case NH_PATH_FRAGMENT_HASH_KEY: + url_string_ref = TSUrlPathGet(reqp, url, &len); + h->update("/", 1); + if (url_string_ref && len > 0) { + h->update(url_string_ref, len); + } + url_string_ref = TSUrlHttpFragmentGet(reqp, url, &len); + if (url_string_ref && len > 0) { + h->update("?", 1); + h->update(url_string_ref, len); + } + break; + // use the cache key created by the cache-key plugin. + case NH_CACHE_HASH_KEY: + if (parent_selection_url != TS_NULL_MLOC) { + url_string_ref = TSUrlStringGet(reqp, parent_selection_url, &len); + if (url_string_ref && len > 0) { + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] using parent selection over-ride string:'%.*s'.", sm_id, len, url_string_ref); + h->update(url_string_ref, len); + } + } else { + url_string_ref = TSUrlPathGet(reqp, url, &len); + h->update("/", 1); + if (url_string_ref && len > 0) { + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] the parent selection over-ride url is not set, using default path: %s.", sm_id, + url_string_ref); + h->update(url_string_ref, len); + } + } + break; + // use the path as the hash, default. + case NH_PATH_HASH_KEY: + default: + url_string_ref = TSUrlPathGet(reqp, url, &len); + h->update("/", 1); + if (url_string_ref && len > 0) { + h->update(url_string_ref, len); + } + break; + } + + h->final(); + return h->get(); +} + +static void setParentResultErr(TSParentResult *result) { + result->hostname = nullptr; + result->port = 0; + result->retry = false; +} + +void +NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) +{ + NH_Debug(NH_DEBUG_TAG, "NH plugin findNexthop calling"); + + TSParentResult* result = TSHttpTxnParentResultGet(txnp); + int64_t sm_id = TSHttpTxnIdGet(txnp); + + TSMBuffer reqp; // TODO verify doesn't need freed + + TSMLoc hdr; + ScopedFreeMLoc hdr_cleanup(&reqp, TS_NULL_MLOC, &hdr); + if (TSHttpTxnClientReqGet(txnp, &reqp, &hdr) == TS_ERROR) { + setParentResultErr(result); + return; + } + + TSMLoc parent_selection_url = TS_NULL_MLOC; + ScopedFreeMLoc parent_selection_url_cleanup(&reqp, TS_NULL_MLOC, &parent_selection_url); + if (TSUrlCreate(reqp, &parent_selection_url) != TS_SUCCESS) { + NH_Error("nexthop failed to create url for parent_selection_url"); + setParentResultErr(result); + return; + } + if (TSHttpTxnParentSelectionUrlGet(txnp, reqp, parent_selection_url) != TS_SUCCESS) { + parent_selection_url = TS_NULL_MLOC; + } + + TSMLoc url; + ScopedFreeMLoc url_cleanup(&reqp, hdr, &url); + if (TSHttpHdrUrlGet(reqp, hdr, &url) != TS_SUCCESS) { + NH_Error("failed to get header url, cannot find next hop"); + setParentResultErr(result); + return; + } + + // TODO is it really worth getting the string out to debug print here? + NH_Debug(NH_DEBUG_TAG, "NH plugin findNexthop got url 'x'"); + + int64_t retry_time = 0; // = sm->t_state.txn_conf->parent_retry_time; + if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_HTTP_PARENT_PROXY_RETRY_TIME, &retry_time) != TS_SUCCESS) { + // TODO get and cache on init, to prevent potential runtime failure? + NH_Error("failed to get parent retry time, cannot find next hop"); + setParentResultErr(result); + return; + } + + time_t _now = now; + bool firstcall = false; + bool nextHopRetry = false; + bool wrapped = false; + std::vector wrap_around(groups, false); + uint32_t cur_ring = 0; // there is a hash ring for each host group + uint64_t hash_key = 0; + uint32_t lookups = 0; + ATSHash64Sip24 hash; + HostRecord *hostRec = nullptr; + std::shared_ptr pRec = nullptr; + TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_INIT; + + if (result->line_number == -1 && result->result == PARENT_UNDEFINED) { + firstcall = true; + } + + if (firstcall) { + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] firstcall, line_number: %d, result: %s", sm_id, result->line_number, + ParentResultStr[result->result]); + result->line_number = NextHopConsistentHash::LineNumberPlaceholder; + cur_ring = 0; + for (uint32_t i = 0; i < groups; i++) { + result->chash_init[i] = false; + wrap_around[i] = false; + } + } else { + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] not firstcall, line_number: %d, result: %s", sm_id, result->line_number, + ParentResultStr[result->result]); + switch (ring_mode) { + case NH_ALTERNATE_RING: + if (groups > 1) { + cur_ring = (result->last_group + 1) % groups; + } else { + cur_ring = result->last_group; + } + break; + case NH_EXHAUST_RING: + default: + if (!wrapped) { + cur_ring = result->last_group; + } else if (groups > 1) { + cur_ring = (result->last_group + 1) % groups; + } + break; + } + } + + // Do the initial parent look-up. + hash_key = getHashKey(sm_id, reqp, url, parent_selection_url, &hash); + + do { // search until we've selected a different parent if !firstcall + std::shared_ptr r = rings[cur_ring]; + hostRec = chash_lookup(r, hash_key, &result->chashIter[cur_ring], &wrapped, &hash, &result->chash_init[cur_ring], + &result->mapWrapped[cur_ring], sm_id); + wrap_around[cur_ring] = wrapped; + lookups++; + // the 'available' flag is maintained in 'host_groups' and not the hash ring. + if (hostRec) { + pRec = host_groups[hostRec->group_index][hostRec->host_index]; + if (firstcall) { + TSHostStatus hostStatus; + const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, nullptr) : false; + result->first_choice_status = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; + break; + } + } else { + pRec = nullptr; + } + } while (pRec && result->hostname && strcmp(pRec->hostname.c_str(), result->hostname) == 0); + + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Initial parent lookups: %d", sm_id, lookups); + + // ---------------------------------------------------------------------------------------------------- + // Validate initial parent look-up and perform additional look-ups if required. + // ---------------------------------------------------------------------------------------------------- + + TSHostStatus hostStatus; + unsigned int hostReasons; + const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) : false; + host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; + // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason + // ignore the down status and mark it as avaialble + if ((pRec && ignore_self_detect) && (hostExists && hostStatus == TS_HOST_STATUS_DOWN)) { + if (hostReasons & TS_HOST_STATUS_SELF_DETECT) { + host_stat = TS_HOST_STATUS_UP; + } + } + if (!pRec || (pRec && !pRec->available) || host_stat == TS_HOST_STATUS_DOWN) { + do { + // check if an unavailable server is now retryable, use it if it is. + if (pRec && !pRec->available && host_stat == TS_HOST_STATUS_UP) { + _now == 0 ? _now = time(nullptr) : _now = now; + // check if the host is retryable. It's retryable if the retry window has elapsed + if ((pRec->failedAt + retry_time) < static_cast(_now)) { + nextHopRetry = true; + result->last_parent = pRec->host_index; + result->last_lookup = pRec->group_index; + result->retry = nextHopRetry; + result->result = PARENT_SPECIFIED; + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next hop %s is now retryable, marked it available.", sm_id, pRec->hostname.c_str()); + break; + } + } + switch (ring_mode) { + case NH_ALTERNATE_RING: + if (groups > 0) { + cur_ring = (pRec->group_index + 1) % groups; + } + break; + case NH_EXHAUST_RING: + default: + if (wrap_around[cur_ring] && groups > 1) { + cur_ring = (cur_ring + 1) % groups; + } + break; + } + std::shared_ptr r = rings[cur_ring]; + hostRec = chash_lookup(r, hash_key, &result->chashIter[cur_ring], &wrapped, &hash, &result->chash_init[cur_ring], + &result->mapWrapped[cur_ring], sm_id); + wrap_around[cur_ring] = wrapped; + lookups++; + if (hostRec) { + pRec = host_groups[hostRec->group_index][hostRec->host_index]; + + TSHostStatus hostStatus; + unsigned int hostReasons; + const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) : false; + host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; + + // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason + // ignore the down status and mark it as avaialble + if ((pRec && ignore_self_detect) && (hostExists && hostStatus == TS_HOST_STATUS_DOWN)) { + if (hostReasons & TS_HOST_STATUS_SELF_DETECT) { + host_stat = TS_HOST_STATUS_UP; + } + } + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Selected a new parent: %s, available: %s, wrapped: %s, lookups: %d.", sm_id, + pRec->hostname.c_str(), (pRec->available) ? "true" : "false", (wrapped) ? "true" : "false", lookups); + // use available host. + if (pRec->available && host_stat == TS_HOST_STATUS_UP) { + break; + } + } else { + pRec = nullptr; + } + bool all_wrapped = true; + for (uint32_t c = 0; c < groups; c++) { + if (wrap_around[c] == false) { + all_wrapped = false; + } + } + if (all_wrapped) { + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] No available parents.", sm_id); + if (pRec) { + pRec = nullptr; + } + break; + } + } while (!pRec || (pRec && !pRec->available) || host_stat == TS_HOST_STATUS_DOWN); + } + + // ---------------------------------------------------------------------------------------------------- + // Validate and return the final result. + // ---------------------------------------------------------------------------------------------------- + + if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->retry)) { + result->result = PARENT_SPECIFIED; + result->hostname = pRec->hostname.c_str(); + result->last_parent = pRec->host_index; + result->last_lookup = result->last_group = cur_ring; + switch (scheme) { + case NH_SCHEME_NONE: + case NH_SCHEME_HTTP: + result->port = pRec->getPort(scheme); + break; + case NH_SCHEME_HTTPS: + result->port = pRec->getPort(scheme); + break; + } + result->retry = nextHopRetry; + ink_assert(result->hostname != nullptr); + ink_assert(result->port != 0); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s Chosen parent: %s:%d", sm_id, ParentResultStr[result->result], + result->hostname, result->port); + } else { + if (go_direct == true) { + result->result = PARENT_DIRECT; + } else { + result->result = PARENT_FAIL; + } + result->hostname = nullptr; + result->port = 0; + result->retry = false; + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, ParentResultStr[result->result]); + } +} diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h new file mode 100644 index 00000000000..62c9389687e --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#pragma once + +#include "strategy.h" + +class NextHopSelectionStrategy; + +enum NHHashKeyType { + NH_URL_HASH_KEY = 0, + NH_HOSTNAME_HASH_KEY, + NH_PATH_HASH_KEY, // default, consistent hash uses the request url path + NH_PATH_QUERY_HASH_KEY, + NH_PATH_FRAGMENT_HASH_KEY, + NH_CACHE_HASH_KEY +}; + +class NextHopConsistentHash : public NextHopSelectionStrategy +{ + std::vector> rings; + uint64_t getHashKey(uint64_t sm_id, TSMBuffer reqp, TSMLoc url, TSMLoc parent_selection_url, ATSHash64 *h); +public: + const uint32_t LineNumberPlaceholder = 99999; + + NHHashKeyType hash_key = NH_PATH_HASH_KEY; + + NextHopConsistentHash() = delete; + NextHopConsistentHash(const std::string_view name); + ~NextHopConsistentHash(); + bool Init(const YAML::Node &n); + void findNextHop(TSHttpTxn txnp, time_t now = 0) override; +}; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc new file mode 100644 index 00000000000..8b09d8bb553 --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc @@ -0,0 +1,204 @@ +/* + * 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 "strategy.h" +#include "consistenthash.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "tscore/HashSip.h" +#include "tscore/ConsistentHash.h" +#include "tscore/ink_assert.h" +#include "ts/ts.h" +#include "ts/remap.h" +#include "ts/nexthop.h" +#include "ts/parentresult.h" + +void loadConfigFile(const std::string fileName, std::stringstream &doc, std::unordered_set &include_once); + +// createStrategy creates and initializes a Consistent Hash strategy from the given YAML node. +// Caller takes ownership of the returned pointer, and must call delete on it. +TSNextHopSelectionStrategy* createStrategy(const std::string &name, const YAML::Node &node) +{ + NextHopConsistentHash *st = new NextHopConsistentHash(name); + if (!st->Init(node)) { + return nullptr; + } + return st; +} + +// createStrategyFromFile creates a Consistent Hash strategy from the given config file. +// Caller takes ownership of the returned pointer, and must call delete on it. +TSNextHopSelectionStrategy* createStrategyFromFile(const char *file, const char *strategyName) +{ + NH_Debug(NH_DEBUG_TAG, "plugin createStrategyFromFile file '%s' strategy '%s'", file, strategyName); + + YAML::Node config; + YAML::Node strategies; + std::stringstream doc; + std::unordered_set include_once; + std::string_view fn = file; + + // strategy policy + constexpr std::string_view consistent_hash = "consistent_hash"; + + const char *basename = fn.substr(fn.find_last_of('/') + 1).data(); + + try { + NH_Note("%s loading ...", basename); + loadConfigFile(fn.data(), doc, include_once); + + config = YAML::Load(doc); + if (config.IsNull()) { + NH_Note("No NextHop strategy configs were loaded."); + return nullptr; + } + + strategies = config["strategies"]; + if (strategies.Type() != YAML::NodeType::Sequence) { + NH_Error("malformed %s file, expected a 'strategies' sequence", basename); + return nullptr; + } + + for (unsigned int i = 0; i < strategies.size(); ++i) { + YAML::Node strategy = strategies[i]; + auto name = strategy["strategy"].as(); + if (name != strategyName) { + continue; + } + auto policy = strategy["policy"]; + if (!policy) { + NH_Error("No policy is defined for the strategy named '%s', this strategy will be ignored.", name.c_str()); + continue; + } + auto policy_value = policy.Scalar(); + if (policy_value != consistent_hash) { + NH_Error("Strategy named '%s' has unsupported policy '%s', this strategy will be ignored.", strategyName, policy_value.c_str()); + return nullptr; + } + return createStrategy(name, strategy); + } + NH_Error("no strategy named '%s' found", strategyName); + } catch (std::exception &ex) { + NH_Note("%s", ex.what()); + } + return nullptr; +} + +/* + * loads the contents of a file into a std::stringstream document. If the file has a '#include file' + * directive, that 'file' is read into the document beginning at the the point where the + * '#include' was found. This allows the 'strategy' and 'hosts' yaml files to be separate. The + * 'strategy' yaml file would then normally have the '#include hosts.yml' in it's begining. + */ +void +loadConfigFile(const std::string fileName, std::stringstream &doc, std::unordered_set &include_once) +{ + const char *sep = " \t"; + char *tok, *last; + struct stat buf; + std::string line; + + if (stat(fileName.c_str(), &buf) == -1) { + std::string err_msg = strerror(errno); + throw std::invalid_argument("Unable to stat '" + fileName + "': " + err_msg); + } + + // if fileName is a directory, concatenate all '.yaml' files alphanumerically + // into a single document stream. No #include is supported. + if (S_ISDIR(buf.st_mode)) { + DIR *dir = nullptr; + struct dirent *dir_ent = nullptr; + std::vector files; + + NH_Note("loading strategy YAML files from the directory %s", fileName.c_str()); + if ((dir = opendir(fileName.c_str())) == nullptr) { + std::string err_msg = strerror(errno); + throw std::invalid_argument("Unable to open the directory '" + fileName + "': " + err_msg); + } else { + while ((dir_ent = readdir(dir)) != nullptr) { + // filename should be greater that 6 characters to have a '.yaml' suffix. + if (strlen(dir_ent->d_name) < 6) { + continue; + } + std::string_view sv = dir_ent->d_name; + if (sv.find(".yaml", sv.size() - 5) == sv.size() - 5) { + files.push_back(sv); + } + } + // sort the files alphanumerically + std::sort(files.begin(), files.end(), + [](const std::string_view lhs, const std::string_view rhs) { return lhs.compare(rhs) < 0; }); + + for (uint32_t i = 0; i < files.size(); i++) { + std::ifstream file(fileName + "/" + files[i].data()); + if (file.is_open()) { + while (std::getline(file, line)) { + if (line[0] == '#') { + // continue; + } + doc << line << "\n"; + } + file.close(); + } else { + throw std::invalid_argument("Unable to open and read '" + fileName + "/" + files[i].data() + "'"); + } + } + } + } else { + std::ifstream file(fileName); + if (file.is_open()) { + while (std::getline(file, line)) { + if (line[0] == '#') { + tok = strtok_r(const_cast(line.c_str()), sep, &last); + if (tok != nullptr && strcmp(tok, "#include") == 0) { + std::string f = strtok_r(nullptr, sep, &last); + if (include_once.find(f) == include_once.end()) { + include_once.insert(f); + // try to load included file. + try { + loadConfigFile(f, doc, include_once); + } catch (std::exception &ex) { + throw std::invalid_argument("Unable to open included file '" + f + "' from '" + fileName + "'"); + } + } + } + } else { + doc << line << "\n"; + } + } + file.close(); + } else { + throw std::invalid_argument("Unable to open and read '" + fileName + "'"); + } + } +} diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h new file mode 100644 index 00000000000..caff3e14002 --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h @@ -0,0 +1,26 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include "ts/nexthop.h" + +TSNextHopSelectionStrategy* createStrategyFromFile(const char *file, const char *strategyName); +TSNextHopSelectionStrategy* createStrategy(const std::string &name, const YAML::Node &node); diff --git a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc new file mode 100644 index 00000000000..6eee97245ca --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc @@ -0,0 +1,146 @@ +/* + * 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 "strategy.h" +#include "consistenthash.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "tscore/HashSip.h" +#include "tscore/ConsistentHash.h" +#include "tscore/ink_assert.h" +#include "ts/ts.h" +#include "ts/remap.h" +#include "ts/nexthop.h" +#include "ts/parentresult.h" + +void +NextHopHealthStatus::insert(std::vector> &hosts) +{ + for (uint32_t ii = 0; ii < hosts.size(); ii++) { + std::shared_ptr h = hosts[ii]; + for(auto protocol = h->protocols.begin(); protocol != h->protocols.end(); ++protocol) { + const std::string host_port = h->getHostPort((*protocol)->port); + host_map.emplace(std::make_pair(host_port, h)); + NH_Debug(NH_DEBUG_TAG, "inserting %s into host_map", host_port.c_str()); + } + } +} + +void +NextHopHealthStatus::markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now) +{ + const time_t _now = now == 0 ? time(nullptr) : now; + TSParentResult* result = TSHttpTxnParentResultGet(txnp); + const int64_t sm_id = TSHttpTxnIdGet(txnp); + + int64_t fail_threshold; // = sm->t_state.txn_conf->parent_fail_threshold; + if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_HTTP_PARENT_PROXY_FAIL_THRESHOLD, &fail_threshold) != TS_SUCCESS) { + NH_Error("markNextHop failed to get parent_fail_threshold, cannot mark next hop"); + return; + } + + int64_t retry_time; // = sm->t_state.txn_conf->parent_retry_time; + if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_HTTP_PARENT_PROXY_RETRY_TIME, &retry_time) != TS_SUCCESS) { + NH_Error("markNextHop failed to get parent_retry_time, cannot mark next hop"); + return; + } + + uint32_t new_fail_count = 0; + + // make sure we're called back with a result structure for a parent + // that is being retried. + if (status == NH_MARK_UP) { + ink_assert(result->retry == true); + } + if (result->result != PARENT_SPECIFIED) { + return; + } + + const std::string host_port = HostRecord::makeHostPort(hostname, port); + auto iter = host_map.find(host_port); + if (iter == host_map.end()) { + NH_Debug(NH_DEBUG_TAG, "[%" PRId64 "] no host named %s found in host_map", sm_id, host_port.c_str()); + return; + } + + std::shared_ptr h = iter->second; + + switch (status) { + // Mark the host up. + case NH_MARK_UP: + if (!h->available) { + h->set_available(); + NH_Note("[%" PRId64 "] http parent proxy %s restored", sm_id, hostname); + } + break; + // Mark the host down. + case NH_MARK_DOWN: + if (h->failedAt == 0 || result->retry == true) { + { // lock guard + std::lock_guard guard(h->_mutex); + if (h->failedAt == 0) { + h->failedAt = _now; + if (result->retry == false) { + new_fail_count = h->failCount = 1; + } + } else if (result->retry == true) { + h->failedAt = _now; + } + } // end lock guard + NH_Note("[%" PRId64 "] NextHop %s marked as down %s", sm_id, (result->retry) ? "retry" : "initially", h->hostname.c_str()); + } else { + int old_count = 0; + // if the last failure was outside the retry window, set the failcount to 1 and failedAt to now. + { // lock guard + std::lock_guard lock(h->_mutex); + if ((h->failedAt + retry_time) < static_cast(_now)) { + h->failCount = 1; + h->failedAt = _now; + } else { + old_count = h->failCount = 1; + } + new_fail_count = old_count + 1; + } // end of lock_guard + NH_Debug(NH_DEBUG_TAG, "[%" PRId64 "] Parent fail count increased to %d for %s", sm_id, new_fail_count, h->hostname.c_str()); + } + + if (new_fail_count >= fail_threshold) { + h->set_unavailable(); + NH_Note("[%" PRId64 "] Failure threshold met failcount:%d >= threshold:%" PRId64 ", http parent proxy %s marked down", sm_id, + new_fail_count, fail_threshold, h->hostname.c_str()); + NH_Debug(NH_DEBUG_TAG, "[%" PRId64 "] NextHop %s marked unavailable, h->available=%s", sm_id, h->hostname.c_str(), + (h->available) ? "true" : "false"); + } + break; + } +} diff --git a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h new file mode 100644 index 00000000000..18bb07d2393 --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "ts/nexthop.h" + +struct HostRecord; + +class NextHopHealthStatus +{ +public: + void insert(std::vector> &hosts); + void markNextHop(TSHttpTxn txn, const char *hostname, const int port, const NHCmd status, const time_t now = 0); + NextHopHealthStatus(){}; + +private: + std::unordered_map> host_map; +}; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc new file mode 100644 index 00000000000..19e696a5764 --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc @@ -0,0 +1,133 @@ +/* + * 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 "strategy.h" +#include "consistenthash.h" +#include "consistenthash_config.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "tscore/HashSip.h" +#include "tscore/ConsistentHash.h" +#include "tscore/ink_assert.h" +#include "ts/ts.h" +#include "ts/remap.h" +#include "ts/nexthop.h" +#include "ts/parentresult.h" + +void +TSRemapDeleteInstance(void *ih) +{ + std::string *config_file_path = static_cast(ih); + delete config_file_path; +} + +TSRemapStatus +TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri) +{ + return TSREMAP_NO_REMAP; +} + +// TODO figure out why TSRemapInitStrategy needs this, but nothing else does. +#ifdef __cplusplus +extern "C" { +#endif + +TSReturnCode +TSRemapInitStrategy(TSNextHopSelectionStrategy *&strategy, void *ih, char *errbuf, int errbuf_size) +{ + NH_Debug(NH_DEBUG_TAG, "%s TSRemapInitStrategy called.", PLUGIN_NAME); + if (ih == nullptr) { + NH_Debug(NH_DEBUG_TAG, "%s TSRemapInitStrategy called with nullptr, returning null strategy.", PLUGIN_NAME); + strategy = nullptr; + return TS_SUCCESS; // TODO determine if we should return TS_ERROR here? + } + strategy = static_cast(ih); + NH_Debug(NH_DEBUG_TAG, "%s is successfully initialized.", PLUGIN_NAME); + return TS_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +TSReturnCode +TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size) +{ + // TODO add ATS API Version check here, to bail if ATS doesn't support the version necessary for strategy plugins + + // if (!api_info) { + // strncpy(errbuf, "[tsstrategy_init] - Invalid TSRemapInterface argument", errbuf_size - 1); + // return TS_ERROR; + // } + + // if (api_info->tsremap_version < TSREMAP_VERSION) { + // snprintf(errbuf, errbuf_size, "[TSStrategyInit] - Incorrect API version %ld.%ld", api_info->tsremap_version >> 16, + // (api_info->tsremap_version & 0xffff)); + // return TS_ERROR; + // } + + NH_Debug(NH_DEBUG_TAG, "%s is successfully initialized.", PLUGIN_NAME); + return TS_SUCCESS; +} + +TSReturnCode +TSRemapNewInstance(int argc, char *argv[], void **ih, char *errbuff, int errbuff_size) +{ + NH_Debug(NH_DEBUG_TAG, "%s TSRemapNewInstance called.", PLUGIN_NAME); + for (int i = 0; i < argc; ++i) { + NH_Debug(NH_DEBUG_TAG, "%s TSRemapNewInstance arg %d '%s'", PLUGIN_NAME, i, argv[i]); + } + + if (argc < 3) { + NH_Error("insufficient number of arguments, %d, no config file argument.", argc); + return TS_ERROR; + } + + if (argc < 3) { + NH_Error("too many arguments, %d, only expected config file argument. Ignoring the rest!", argc); + } + + const char* config_file_path = argv[2]; + + NH_Debug(NH_DEBUG_TAG, "%s TSRemapInitStrategy called with path '%s'", PLUGIN_NAME, config_file_path); + + TSNextHopSelectionStrategy* strategy = createStrategyFromFile(config_file_path, PLUGIN_NAME); + if (strategy == nullptr) { + NH_Debug(NH_DEBUG_TAG, "%s failed to create strategy.", PLUGIN_NAME); + *ih = nullptr; + return TS_ERROR; + } + NH_Debug(NH_DEBUG_TAG, "%s successfully created strategy.", PLUGIN_NAME); + *ih = static_cast(strategy); + return TS_SUCCESS; +} diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc new file mode 100644 index 00000000000..d5890911621 --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc @@ -0,0 +1,344 @@ +/* + * 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 "strategy.h" +#include "consistenthash.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "tscore/HashSip.h" +#include "tscore/ConsistentHash.h" +#include "tscore/ink_assert.h" +#include "ts/ts.h" +#include "ts/remap.h" +#include "ts/nexthop.h" +#include "ts/parentresult.h" + +// +// NextHopSelectionStrategy.cc +// + +// ring mode strings +constexpr std::string_view alternate_rings = "alternate_ring"; +constexpr std::string_view exhaust_rings = "exhaust_ring"; + +// health check strings +constexpr std::string_view active_health_check = "active"; +constexpr std::string_view passive_health_check = "passive"; + +NextHopSelectionStrategy::NextHopSelectionStrategy(const std::string_view &name) +{ + strategy_name = name; +} + +// +// parse out the data for this strategy. +// +bool +NextHopSelectionStrategy::Init(const YAML::Node &n) +{ + NH_Debug(NH_DEBUG_TAG, "calling Init()"); + + try { + if (n["scheme"]) { + auto scheme_val = n["scheme"].Scalar(); + if (scheme_val == "http") { + scheme = NH_SCHEME_HTTP; + } else if (scheme_val == "https") { + scheme = NH_SCHEME_HTTPS; + } else { + scheme = NH_SCHEME_NONE; + NH_Note("Invalid 'scheme' value, '%s', for the strategy named '%s', setting to NH_SCHEME_NONE", scheme_val.c_str(), + strategy_name.c_str()); + } + } + + // go_direct config. + if (n["go_direct"]) { + go_direct = n["go_direct"].as(); + } + + // parent_is_proxy config. + if (n["parent_is_proxy"]) { + parent_is_proxy = n["parent_is_proxy"].as(); + } + + // ignore_self_detect + if (n["ignore_self_detect"]) { + ignore_self_detect = n["ignore_self_detect"].as(); + } + + // failover node. + YAML::Node failover_node; + if (n["failover"]) { + failover_node = n["failover"]; + if (failover_node["ring_mode"]) { + auto ring_mode_val = failover_node["ring_mode"].Scalar(); + if (ring_mode_val == alternate_rings) { + ring_mode = NH_ALTERNATE_RING; + } else if (ring_mode_val == exhaust_rings) { + ring_mode = NH_EXHAUST_RING; + } else { + ring_mode = NH_ALTERNATE_RING; + NH_Note("Invalid 'ring_mode' value, '%s', for the strategy named '%s', using default '%s'.", ring_mode_val.c_str(), + strategy_name.c_str(), alternate_rings.data()); + } + } + if (failover_node["max_simple_retries"]) { + max_simple_retries = failover_node["max_simple_retries"].as(); + } + + YAML::Node resp_codes_node; + if (failover_node["response_codes"]) { + resp_codes_node = failover_node["response_codes"]; + if (resp_codes_node.Type() != YAML::NodeType::Sequence) { + NH_Error("Error in the response_codes definition for the strategy named '%s', skipping response_codes.", + strategy_name.c_str()); + } else { + for (unsigned int k = 0; k < resp_codes_node.size(); ++k) { + auto code = resp_codes_node[k].as(); + if (code > 300 && code < 599) { + resp_codes.add(code); + } else { + NH_Note("Skipping invalid response code '%d' for the strategy named '%s'.", code, strategy_name.c_str()); + } + } + resp_codes.sort(); + } + } + YAML::Node health_check_node; + if (failover_node["health_check"]) { + health_check_node = failover_node["health_check"]; + if (health_check_node.Type() != YAML::NodeType::Sequence) { + NH_Error("Error in the health_check definition for the strategy named '%s', skipping health_checks.", + strategy_name.c_str()); + } else { + for (auto it = health_check_node.begin(); it != health_check_node.end(); ++it) { + auto health_check = it->as(); + if (health_check.compare(active_health_check) == 0) { + health_checks.active = true; + } + if (health_check.compare(passive_health_check) == 0) { + health_checks.passive = true; + } + } + } + } + } + + // parse and load the host data + YAML::Node groups_node; + if (n["groups"]) { + groups_node = n["groups"]; + // a groups list is required. + if (groups_node.Type() != YAML::NodeType::Sequence) { + throw std::invalid_argument("Invalid groups definition, expected a sequence, '" + strategy_name + "' cannot be loaded."); + } else { + uint32_t grp_size = groups_node.size(); + if (grp_size > TS_MAX_GROUP_RINGS) { + NH_Note("the groups list exceeds the maximum of %d for the strategy '%s'. Only the first %d groups will be configured.", + TS_MAX_GROUP_RINGS, strategy_name.c_str(), TS_MAX_GROUP_RINGS); + groups = TS_MAX_GROUP_RINGS; + } else { + groups = groups_node.size(); + } + // resize the hosts vector. + host_groups.reserve(groups); + // loop through the groups + for (unsigned int grp = 0; grp < groups; ++grp) { + YAML::Node hosts_list = groups_node[grp]; + + // a list of hosts is required. + if (hosts_list.Type() != YAML::NodeType::Sequence) { + throw std::invalid_argument("Invalid hosts definition, expected a sequence, '" + strategy_name + "' cannot be loaded."); + } else { + // loop through the hosts list. + std::vector> hosts_inner; + + for (unsigned int hst = 0; hst < hosts_list.size(); ++hst) { + std::shared_ptr host_rec = std::make_shared(hosts_list[hst].as()); + host_rec->group_index = grp; + host_rec->host_index = hst; + if (TSHostnameIsSelf(host_rec->hostname.c_str())) { + TSHostStatusSet(host_rec->hostname.c_str(), TSHostStatus::TS_HOST_STATUS_DOWN, 0, (unsigned int)TS_HOST_STATUS_SELF_DETECT); + } + hosts_inner.push_back(std::move(host_rec)); + num_parents++; + } + passive_health.insert(hosts_inner); + host_groups.push_back(std::move(hosts_inner)); + } + } + } + } + } catch (std::exception &ex) { + NH_Note("Error parsing the strategy named '%s' due to '%s', this strategy will be ignored.", strategy_name.c_str(), ex.what()); + return false; + } + + return true; +} + +void +NextHopSelectionStrategy::markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now) +{ + NH_Debug(NH_DEBUG_TAG, "nhplugin markNextHop calling"); + return passive_health.markNextHop(txnp, hostname, port, status, now); +} + +bool +NextHopSelectionStrategy::nextHopExists(TSHttpTxn txnp) +{ + NH_Debug(NH_DEBUG_TAG, "nhplugin nextHopExists calling"); + + const int64_t sm_id = TSHttpTxnIdGet(txnp); + + for (uint32_t gg = 0; gg < groups; gg++) { + for (uint32_t hh = 0; hh < host_groups[gg].size(); hh++) { + HostRecord *p = host_groups[gg][hh].get(); + if (p->available) { + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] found available next hop %s", sm_id, p->hostname.c_str()); + return true; + } + } + } + return false; +} + +bool +NextHopSelectionStrategy::responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) { + return this->resp_codes.contains(response_code) && + current_retry_attempts < this->max_simple_retries && + current_retry_attempts < this->num_parents; +} + +bool +NextHopSelectionStrategy::onFailureMarkParentDown(TSHttpStatus response_code) { + return static_cast(response_code) >= 500 && static_cast(response_code) <= 599; +} + +bool +NextHopSelectionStrategy::goDirect() +{ + NH_Debug(NH_DEBUG_TAG, "nhplugin goDirect calling"); + return this->go_direct; +} + +bool +NextHopSelectionStrategy::parentIsProxy() +{ + NH_Debug(NH_DEBUG_TAG, "nhplugin parentIsProxy calling"); + return this->parent_is_proxy; +} + +namespace YAML +{ +template <> struct convert { + static bool + decode(const Node &node, HostRecord &nh) + { + YAML::Node nd; + bool merge_tag_used = false; + + // check for YAML merge tag. + if (node["<<"]) { + nd = node["<<"]; + merge_tag_used = true; + } else { + nd = node; + } + + // lookup the hostname + if (nd["host"]) { + nh.hostname = nd["host"].Scalar(); + } else { + throw std::invalid_argument("Invalid host definition, missing host name."); + } + + // lookup the port numbers supported by this host. + YAML::Node proto = nd["protocol"]; + + if (proto.Type() != YAML::NodeType::Sequence) { + throw std::invalid_argument("Invalid host protocol definition, expected a sequence."); + } else { + for (unsigned int ii = 0; ii < proto.size(); ii++) { + YAML::Node protocol_node = proto[ii]; + std::shared_ptr pr = std::make_shared(protocol_node.as()); + nh.protocols.push_back(std::move(pr)); + } + } + + // get the host's weight + YAML::Node weight; + if (merge_tag_used) { + weight = node["weight"]; + nh.weight = weight.as(); + } else if ((weight = nd["weight"])) { + nh.weight = weight.as(); + } else { + NH_Note("No weight is defined for the host '%s', using default 1.0", nh.hostname.data()); + nh.weight = 1.0; + } + + // get the host's optional hash_string + YAML::Node hash; + if ((hash = nd["hash_string"])) { + nh.hash_string = hash.Scalar(); + } + + return true; + } +}; + +template <> struct convert { + static bool + decode(const Node &node, NHProtocol &nh) + { + if (node["scheme"]) { + if (node["scheme"].Scalar() == "http") { + nh.scheme = NH_SCHEME_HTTP; + } else if (node["scheme"].Scalar() == "https") { + nh.scheme = NH_SCHEME_HTTPS; + } else { + nh.scheme = NH_SCHEME_NONE; + } + } + if (node["port"]) { + nh.port = node["port"].as(); + } + if (node["health_check_url"]) { + nh.health_check_url = node["health_check_url"].Scalar(); + } + return true; + } +}; +}; // namespace YAML diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.h b/plugins/experimental/nexthop_strategy_consistenthash/strategy.h new file mode 100644 index 00000000000..fef6095909b --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.h @@ -0,0 +1,233 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tscore/ConsistentHash.h" +#include "ts/ts.h" +#include "ts/nexthop.h" +#include "ts/remap.h" +#include "healthstatus.h" + +// TODO rename, move to respective sub-plugins +#define PLUGIN_NAME "nexthop_strategy_consistenthash.so" + +constexpr const char *NH_DEBUG_TAG = "plugin_nexthop"; + +#define NH_Debug(tag, fmt, ...) TSDebug(tag, "[%s:%d]: " fmt, __FILE__, __LINE__, ##__VA_ARGS__) +#define NH_Error(fmt, ...) TSError("(%s) [%s:%d]: " fmt, PLUGIN_NAME, __FILE__, __LINE__, ##__VA_ARGS__) +#define NH_Note(fmt, ...) TSDebug(NH_DEBUG_TAG, "[%s:%d]: " fmt, __FILE__, __LINE__, ##__VA_ARGS__) + +constexpr const char *policy_strings[] = {"NH_UNDEFINED", "NH_FIRST_LIVE", "NH_RR_STRICT", + "NH_RR_IP", "NH_RR_LATCHED", "NH_CONSISTENT_HASH"}; + +enum NHPolicyType { + NH_UNDEFINED = 0, + NH_FIRST_LIVE, // first available nexthop + NH_RR_STRICT, // strict round robin + NH_RR_IP, // round robin by client ip. + NH_RR_LATCHED, // latched to available next hop. + NH_CONSISTENT_HASH, // consistent hashing strategy. + NH_PLUGIN, // hashing strategy is a plugin +}; + +enum NHSchemeType { NH_SCHEME_NONE = 0, NH_SCHEME_HTTP, NH_SCHEME_HTTPS }; + +enum NHRingMode { NH_ALTERNATE_RING = 0, NH_EXHAUST_RING }; + +// response codes container +struct ResponseCodes { + ResponseCodes(){}; + std::vector codes; + void + add(short code) + { + codes.push_back(code); + } + bool + contains(short code) + { + return std::binary_search(codes.begin(), codes.end(), code); + } + void + sort() + { + std::sort(codes.begin(), codes.end()); + } +}; + +struct HealthChecks { + bool active = false; + bool passive = false; +}; + +struct NHProtocol { + NHSchemeType scheme; + uint32_t port; + std::string health_check_url; +}; + +struct HostRecord : ATSConsistentHashNode { + std::mutex _mutex; + std::string hostname; + time_t failedAt; + uint32_t failCount; + time_t upAt; + float weight; + std::string hash_string; + int host_index; + int group_index; + std::vector> protocols; + + // construct without locking the _mutex. + HostRecord() + { + hostname = ""; + failedAt = 0; + failCount = 0; + upAt = 0; + weight = 0; + hash_string = ""; + host_index = -1; + group_index = -1; + available = true; + } + + // copy constructor to avoid copying the _mutex. + HostRecord(const HostRecord &o) + { + hostname = o.hostname; + failedAt = o.failedAt; + failCount = o.failCount; + upAt = o.upAt; + weight = o.weight; + hash_string = o.hash_string; + host_index = -1; + group_index = -1; + available = true; + protocols = o.protocols; + } + + // assign without copying the _mutex. + HostRecord & + operator=(const HostRecord &o) + { + hostname = o.hostname; + failedAt = o.failedAt; + upAt = o.upAt; + weight = o.weight; + hash_string = o.hash_string; + host_index = o.host_index; + group_index = o.group_index; + available = o.available; + protocols = o.protocols; + return *this; + } + + // locks the record when marking this host down. + void + set_unavailable() + { + if (available) { + std::lock_guard lock(_mutex); + failedAt = time(nullptr); + available = false; + } + } + + // locks the record when marking this host up. + void + set_available() + { + if (!available) { + std::lock_guard lock(_mutex); + failedAt = 0; + failCount = 0; + upAt = time(nullptr); + available = true; + } + } + + int + getPort(NHSchemeType scheme) const + { + int port = 0; + for (uint32_t i = 0; i < protocols.size(); i++) { + if (protocols[i]->scheme == scheme) { + port = protocols[i]->port; + break; + } + } + return port; + } + + static std::string + makeHostPort(const std::string& hostname, const int port) + { + return hostname + ":" + std::to_string(port); + } + + std::string + getHostPort(const int port) const + { + return makeHostPort(this->hostname, port); + } +}; + +class NextHopSelectionStrategy : public TSNextHopSelectionStrategy +{ +public: + NextHopSelectionStrategy(); + NextHopSelectionStrategy(const std::string_view &name); + virtual ~NextHopSelectionStrategy(){}; + bool Init(const YAML::Node &n); + + virtual void findNextHop(TSHttpTxn txnp, time_t now = 0) = 0; + virtual void markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now = 0); + virtual bool nextHopExists(TSHttpTxn txnp); + virtual bool responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code); + virtual bool onFailureMarkParentDown(TSHttpStatus response_code); + virtual bool goDirect(); + virtual bool parentIsProxy(); +protected: + std::string strategy_name; + bool go_direct = true; + bool parent_is_proxy = true; + bool ignore_self_detect = false; + NHSchemeType scheme = NH_SCHEME_NONE; + NHRingMode ring_mode = NH_ALTERNATE_RING; + ResponseCodes resp_codes; + HealthChecks health_checks; + NextHopHealthStatus passive_health; + std::vector>> host_groups; + uint32_t max_simple_retries = 1; + uint32_t groups = 0; + uint32_t grp_index = 0; + uint32_t hst_index = 0; + uint32_t num_parents = 0; + uint32_t distance = 0; // index into the strategies list. +}; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/util.h b/plugins/experimental/nexthop_strategy_consistenthash/util.h new file mode 100644 index 00000000000..473ef975874 --- /dev/null +++ b/plugins/experimental/nexthop_strategy_consistenthash/util.h @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#pragma once + +// ScopedFreeMLoc frees the given TSMLoc with TSHandleMLocRelease(buf, parent, *m) when it goes out of scope. +// The lifetime of buf and parent must exceed this. +// The parent must be allocated before this (if it exists). +// The parent may be TS_NULL_MLOC. +// If mloc is set to TS_NULL_MLOC or never allocated, it will not be freed. +struct ScopedFreeMLoc { + ScopedFreeMLoc(TSMBuffer *_buf, TSMLoc _parent, TSMLoc *_mloc) : mloc(_mloc), parent(_parent), buf(_buf) {}; + ~ScopedFreeMLoc(){ + if (*mloc != TS_NULL_MLOC) { + TSHandleMLocRelease(*buf, parent, *mloc); + } + }; +private: + TSMLoc *mloc; + TSMLoc parent; + TSMBuffer *buf; +}; + +// StrVal is a string as returned by TSUrlStringGet and other TS API functions. +// Zeroes on initialization. +struct StrVal { + StrVal() : ptr(nullptr), len(0) {}; + char *ptr; + int len; +}; + +// ScopedFreeStrVal frees the ptr in the given Strval when it goes out of scope. +struct ScopedFreeStrVal { + ScopedFreeStrVal(StrVal *_strval) : strval(_strval) {}; + ~ScopedFreeStrVal(){ + TSfree(strval->ptr); + }; +private: + StrVal *strval; +}; diff --git a/proxy/HostStatus.h b/proxy/HostStatus.h index 2cc18130a7c..133e90a0be7 100644 --- a/proxy/HostStatus.h +++ b/proxy/HostStatus.h @@ -41,15 +41,12 @@ // host_status stats prefix. static const std::string stat_prefix = "proxy.process.host_status."; -enum HostStatus_t { - HOST_STATUS_INIT, - HOST_STATUS_DOWN, - HOST_STATUS_UP, -}; - static const constexpr char *HostStatusNames[3] = {"HOST_STATUS_INIT", "HOST_STATUS_DOWN", "HOST_STATUS_UP"}; static const constexpr char *ReasonStatus[2] = {"UP", "DOWN"}; +/* MUST match apidefs.h.in TSHostStatusReason + * If a value is added here, it MUST be added there with the same value. + */ struct Reason { static constexpr const unsigned int ACTIVE = 0x1; static constexpr const unsigned int LOCAL = 0x2; @@ -97,7 +94,7 @@ struct Reason { // host status POD struct HostStatRec { - HostStatus_t status; + TSHostStatus status; unsigned int reasons; // time the host was marked down for a given reason. time_t active_marked_down; @@ -186,7 +183,7 @@ struct HostStatus { static HostStatus instance; return instance; } - void setHostStatus(const char *name, const HostStatus_t status, const unsigned int down_time, const unsigned int reason); + void setHostStatus(const char *name, const TSHostStatus status, const unsigned int down_time, const unsigned int reason); HostStatRec *getHostStatus(const char *name); void createHostStat(const char *name, const char *data = nullptr); void loadHostStatusFromStats(); diff --git a/proxy/ParentConsistentHash.cc b/proxy/ParentConsistentHash.cc index 568fba97d92..550e6bfcf79 100644 --- a/proxy/ParentConsistentHash.cc +++ b/proxy/ParentConsistentHash.cc @@ -142,7 +142,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques uint32_t last_lookup; pRecord *prtmp = nullptr, *pRec = nullptr; HostStatus &pStatus = HostStatus::instance(); - HostStatus_t host_stat = HostStatus_t::HOST_STATUS_INIT; + TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_INIT; Debug("parent_select", "ParentConsistentHash::%s(): Using a consistent hash parent selection strategy.", __func__); ink_assert(numParents(result) > 0 || result->rec->go_direct == true); @@ -150,12 +150,12 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques // Should only get into this state if we are supposed to go direct. if (parents[PRIMARY] == nullptr && parents[SECONDARY] == nullptr) { if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; return; } @@ -173,7 +173,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques last_lookup = PRIMARY; break; case 3: - if (result->first_choice_status == HOST_STATUS_DOWN && chash[SECONDARY] != nullptr) { + if (result->ts_result.first_choice_status == TS_HOST_STATUS_DOWN && chash[SECONDARY] != nullptr) { last_lookup = SECONDARY; } else { last_lookup = PRIMARY; @@ -193,8 +193,8 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques path_hash = getPathHash(request_info, (ATSHash64 *)&hash); fhash = chash[last_lookup]; do { // search until we've selected a different parent if !firstCall - prtmp = chash_lookup(fhash, path_hash, &result->chashIter[last_lookup], &wrap_around[last_lookup], &hash, - &result->chash_init[last_lookup], &result->mapWrapped[last_lookup]); + prtmp = chash_lookup(fhash, path_hash, &result->ts_result.chashIter[last_lookup], &wrap_around[last_lookup], &hash, + &result->ts_result.chash_init[last_lookup], &result->ts_result.mapWrapped[last_lookup]); lookups++; if (prtmp) { pRec = (parents[last_lookup] + prtmp->idx); @@ -203,10 +203,10 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques } if (firstCall) { HostStatRec *hst = (pRec) ? pStatus.getHostStatus(pRec->hostname) : nullptr; - result->first_choice_status = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + result->ts_result.first_choice_status = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; break; } - } while (pRec && !firstCall && last_lookup == PRIMARY && strcmp(pRec->hostname, result->hostname) == 0); + } while (pRec && !firstCall && last_lookup == PRIMARY && strcmp(pRec->hostname, result->ts_result.hostname) == 0); Debug("parent_select", "Initial parent lookups: %d", lookups); @@ -216,28 +216,28 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques // didn't find a parent or the parent is marked unavailable or the parent is marked down HostStatRec *hst = (pRec) ? pStatus.getHostStatus(pRec->hostname) : nullptr; - host_stat = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + host_stat = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble - if ((pRec && result->rec->ignore_self_detect) && (hst && hst->status == HOST_STATUS_DOWN)) { + if ((pRec && result->rec->ignore_self_detect) && (hst && hst->status == TS_HOST_STATUS_DOWN)) { if (hst->reasons == Reason::SELF_DETECT) { - host_stat = HOST_STATUS_UP; + host_stat = TS_HOST_STATUS_UP; } } - if (!pRec || (pRec && !pRec->available) || host_stat == HOST_STATUS_DOWN) { + if (!pRec || (pRec && !pRec->available) || host_stat == TS_HOST_STATUS_DOWN) { do { // check if the host is retryable. It's retryable if the retry window has elapsed - // and the global host status is HOST_STATUS_UP - if (pRec && !pRec->available && host_stat == HOST_STATUS_UP) { + // and the global host status is TS_HOST_STATUS_UP + if (pRec && !pRec->available && host_stat == TS_HOST_STATUS_UP) { Debug("parent_select", "Parent.failedAt = %u, retry = %u, xact_start = %u", (unsigned int)pRec->failedAt, (unsigned int)retry_time, (unsigned int)request_info->xact_start); if ((pRec->failedAt + retry_time) < request_info->xact_start) { parentRetry = true; // make sure that the proper state is recorded in the result structure - result->last_parent = pRec->idx; - result->last_lookup = last_lookup; - result->retry = parentRetry; - result->result = PARENT_SPECIFIED; + result->ts_result.last_parent = pRec->idx; + result->ts_result.last_lookup = last_lookup; + result->ts_result.retry = parentRetry; + result->ts_result.result = PARENT_SPECIFIED; Debug("parent_select", "Down parent %s is now retryable, marked it available.", pRec->hostname); break; } @@ -254,7 +254,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques } break; case 3: - if (result->first_choice_status == HOST_STATUS_DOWN) { + if (result->ts_result.first_choice_status == TS_HOST_STATUS_DOWN) { if (chash[SECONDARY] != nullptr && !wrap_around[SECONDARY]) { last_lookup = SECONDARY; } else if (!wrap_around[PRIMARY]) { @@ -277,8 +277,8 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques } } fhash = chash[last_lookup]; - prtmp = chash_lookup(fhash, path_hash, &result->chashIter[last_lookup], &wrap_around[last_lookup], &hash, - &result->chash_init[last_lookup], &result->mapWrapped[last_lookup]); + prtmp = chash_lookup(fhash, path_hash, &result->ts_result.chashIter[last_lookup], &wrap_around[last_lookup], &hash, + &result->ts_result.chash_init[last_lookup], &result->ts_result.mapWrapped[last_lookup]); lookups++; if (prtmp) { pRec = (parents[last_lookup] + prtmp->idx); @@ -296,15 +296,15 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques break; } hst = (pRec) ? pStatus.getHostStatus(pRec->hostname) : nullptr; - host_stat = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + host_stat = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble - if ((pRec && result->rec->ignore_self_detect) && (hst && hst->status == HOST_STATUS_DOWN)) { + if ((pRec && result->rec->ignore_self_detect) && (hst && hst->status == TS_HOST_STATUS_DOWN)) { if (hst->reasons == Reason::SELF_DETECT) { - host_stat = HOST_STATUS_UP; + host_stat = TS_HOST_STATUS_UP; } } - } while (!pRec || !pRec->available || host_stat == HOST_STATUS_DOWN); + } while (!pRec || !pRec->available || host_stat == TS_HOST_STATUS_DOWN); } Debug("parent_select", "Additional parent lookups: %d", lookups); @@ -315,33 +315,33 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques // use the available or marked for retry parent. hst = (pRec) ? pStatus.getHostStatus(pRec->hostname) : nullptr; - host_stat = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + host_stat = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble - if ((pRec && result->rec->ignore_self_detect) && (hst && hst->status == HOST_STATUS_DOWN)) { + if ((pRec && result->rec->ignore_self_detect) && (hst && hst->status == TS_HOST_STATUS_DOWN)) { if (hst->reasons == Reason::SELF_DETECT) { - host_stat = HOST_STATUS_UP; + host_stat = TS_HOST_STATUS_UP; } } - if (pRec && host_stat == HOST_STATUS_UP && (pRec->available || result->retry)) { - result->result = PARENT_SPECIFIED; - result->hostname = pRec->hostname; - result->port = pRec->port; - result->last_parent = pRec->idx; - result->last_lookup = last_lookup; - result->retry = parentRetry; - ink_assert(result->hostname != nullptr); - ink_assert(result->port != 0); - Debug("parent_select", "Chosen parent: %s.%d", result->hostname, result->port); + if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->ts_result.retry)) { + result->ts_result.result = PARENT_SPECIFIED; + result->ts_result.hostname = pRec->hostname; + result->ts_result.port = pRec->port; + result->ts_result.last_parent = pRec->idx; + result->ts_result.last_lookup = last_lookup; + result->ts_result.retry = parentRetry; + ink_assert(result->ts_result.hostname != nullptr); + ink_assert(result->ts_result.port != 0); + Debug("parent_select", "Chosen parent: %s.%d", result->ts_result.hostname, result->ts_result.port); } else { if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; - result->retry = false; + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; + result->ts_result.retry = false; } return; @@ -352,7 +352,7 @@ ParentConsistentHash::numParents(ParentResult *result) const { uint32_t n = 0; - switch (result->last_lookup) { + switch (result->ts_result.last_lookup) { case PRIMARY: n = result->rec->num_parents; break; @@ -371,9 +371,9 @@ ParentConsistentHash::markParentUp(ParentResult *result) // Make sure that we are being called back with with a // result structure with a parent that is being retried - ink_release_assert(result->retry == true); - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { + ink_release_assert(result->ts_result.retry == true); + ink_assert(result->ts_result.result == PARENT_SPECIFIED); + if (result->ts_result.result != PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover @@ -383,8 +383,8 @@ ParentConsistentHash::markParentUp(ParentResult *result) return; } - ink_assert((result->last_parent) < numParents(result)); - pRec = parents[result->last_lookup] + result->last_parent; + ink_assert((result->ts_result.last_parent) < numParents(result)); + pRec = parents[result->ts_result.last_lookup] + result->ts_result.last_parent; ink_atomic_swap(&pRec->available, true); Debug("parent_select", "%s:%s(): marked %s:%d available.", __FILE__, __func__, pRec->hostname, pRec->port); diff --git a/proxy/ParentConsistentHash.h b/proxy/ParentConsistentHash.h index 3a8ee582789..4ce904353e6 100644 --- a/proxy/ParentConsistentHash.h +++ b/proxy/ParentConsistentHash.h @@ -55,7 +55,7 @@ class ParentConsistentHash : public ParentSelectionStrategy pRecord * getParents(ParentResult *result) override { - return parents[result->last_lookup]; + return parents[result->ts_result.last_lookup]; } uint64_t getPathHash(HttpRequestData *hrdata, ATSHash64 *h); void selectParent(bool firstCall, ParentResult *result, RequestData *rdata, unsigned int fail_threshold, diff --git a/proxy/ParentRoundRobin.cc b/proxy/ParentRoundRobin.cc index 5c955bb2415..1cf0ee92f2f 100644 --- a/proxy/ParentRoundRobin.cc +++ b/proxy/ParentRoundRobin.cc @@ -63,7 +63,7 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat bool parentUp = false; bool parentRetry = false; HostStatus &pStatus = HostStatus::instance(); - HostStatus_t host_stat = HostStatus_t::HOST_STATUS_UP; + TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_UP; HttpRequestData *request_info = static_cast(rdata); @@ -76,13 +76,13 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat ink_assert(result->rec->go_direct == true); // Could not find a parent if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; return; } else { switch (round_robin_type) { @@ -93,20 +93,20 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat // preserved for now anyway as ats_ip_hash returns the 32-bit address in // that case. if (rdata->get_client_ip() != nullptr) { - cur_index = result->start_parent = ntohl(ats_ip_hash(rdata->get_client_ip())) % num_parents; + cur_index = result->ts_result.start_parent = ntohl(ats_ip_hash(rdata->get_client_ip())) % num_parents; } else { cur_index = 0; } break; case P_STRICT_ROUND_ROBIN: - cur_index = result->start_parent = + cur_index = result->ts_result.start_parent = ink_atomic_increment(reinterpret_cast(&result->rec->rr_next), 1) % num_parents; break; case P_NO_ROUND_ROBIN: - cur_index = result->start_parent = 0; + cur_index = result->ts_result.start_parent = 0; break; case P_LATCHED_ROUND_ROBIN: - cur_index = result->start_parent = latched_parent; + cur_index = result->ts_result.start_parent = latched_parent; break; default: ink_release_assert(0); @@ -114,20 +114,20 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat } } else { // Move to next parent due to failure - latched_parent = cur_index = (result->last_parent + 1) % num_parents; + latched_parent = cur_index = (result->ts_result.last_parent + 1) % num_parents; // Check to see if we have wrapped around - if (static_cast(cur_index) == result->start_parent) { + if (static_cast(cur_index) == result->ts_result.start_parent) { // We've wrapped around so bypass if we can if (result->rec->go_direct == true) { // Could not find a parent if (result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; return; } } @@ -137,28 +137,28 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat // should be retried do { HostStatRec *hst = pStatus.getHostStatus(parents[cur_index].hostname); - host_stat = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + host_stat = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble - if (result->rec->ignore_self_detect && (hst && hst->status == HOST_STATUS_DOWN)) { + if (result->rec->ignore_self_detect && (hst && hst->status == TS_HOST_STATUS_DOWN)) { if (hst->reasons == Reason::SELF_DETECT) { - host_stat = HOST_STATUS_UP; + host_stat = TS_HOST_STATUS_UP; } } - Debug("parent_select", "cur_index: %d, result->start_parent: %d", cur_index, result->start_parent); + Debug("parent_select", "cur_index: %d, result->ts_result.start_parent: %d", cur_index, result->ts_result.start_parent); // DNS ParentOnly inhibits bypassing the parent so always return that t if ((parents[cur_index].failedAt == 0) || (parents[cur_index].failCount < static_cast(fail_threshold))) { - if (host_stat == HOST_STATUS_UP) { + if (host_stat == TS_HOST_STATUS_UP) { Debug("parent_select", "FailThreshold = %d", fail_threshold); Debug("parent_select", "Selecting a parent due to little failCount (faileAt: %u failCount: %d)", (unsigned)parents[cur_index].failedAt, parents[cur_index].failCount); parentUp = true; } } else { - if ((result->wrap_around) || - ((parents[cur_index].failedAt + retry_time) < request_info->xact_start && host_stat == HOST_STATUS_UP)) { + if ((result->ts_result.wrap_around) || + ((parents[cur_index].failedAt + retry_time) < request_info->xact_start && host_stat == TS_HOST_STATUS_UP)) { Debug("parent_select", "Parent[%d].failedAt = %u, retry = %u,xact_start = %" PRId64 " but wrap = %d", cur_index, - (unsigned)parents[cur_index].failedAt, retry_time, (int64_t)request_info->xact_start, result->wrap_around); + (unsigned)parents[cur_index].failedAt, retry_time, (int64_t)request_info->xact_start, result->ts_result.wrap_around); // Reuse the parent parentUp = true; parentRetry = true; @@ -168,29 +168,29 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat } } - if (parentUp == true && host_stat != HOST_STATUS_DOWN) { + if (parentUp == true && host_stat != TS_HOST_STATUS_DOWN) { Debug("parent_select", "status for %s: %d", parents[cur_index].hostname, host_stat); - result->result = PARENT_SPECIFIED; - result->hostname = parents[cur_index].hostname; - result->port = parents[cur_index].port; - result->last_parent = cur_index; - result->retry = parentRetry; - ink_assert(result->hostname != nullptr); - ink_assert(result->port != 0); - Debug("parent_select", "Chosen parent = %s.%d", result->hostname, result->port); + result->ts_result.result = PARENT_SPECIFIED; + result->ts_result.hostname = parents[cur_index].hostname; + result->ts_result.port = parents[cur_index].port; + result->ts_result.last_parent = cur_index; + result->ts_result.retry = parentRetry; + ink_assert(result->ts_result.hostname != nullptr); + ink_assert(result->ts_result.port != 0); + Debug("parent_select", "Chosen parent = %s.%d", result->ts_result.hostname, result->ts_result.port); return; } latched_parent = cur_index = (cur_index + 1) % num_parents; - } while (static_cast(cur_index) != result->start_parent); + } while (static_cast(cur_index) != result->ts_result.start_parent); if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; } uint32_t diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc index 08254a453d8..34cc98e35ee 100644 --- a/proxy/ParentSelection.cc +++ b/proxy/ParentSelection.cc @@ -109,14 +109,14 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns // Check to see if the parent was set through the // api if (apiParentExists(rdata)) { - result->result = PARENT_SPECIFIED; - result->hostname = rdata->api_info->parent_proxy_name; - result->port = rdata->api_info->parent_proxy_port; + result->ts_result.result = PARENT_SPECIFIED; + result->ts_result.hostname = rdata->api_info->parent_proxy_name; + result->ts_result.port = rdata->api_info->parent_proxy_port; result->rec = extApiRecord; - result->start_parent = 0; - result->last_parent = 0; + result->ts_result.start_parent = 0; + result->ts_result.last_parent = 0; - Debug("parent_select", "Result for %s was API set parent %s:%d", rdata->get_host(), result->hostname, result->port); + Debug("parent_select", "Result for %s was API set parent %s:%d", rdata->get_host(), result->ts_result.hostname, result->ts_result.port); return; } @@ -133,7 +133,7 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns if (defaultPtr != nullptr) { rec = result->rec = defaultPtr; } else { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; Debug("parent_select", "Returning PARENT_DIRECT (no parents were found)"); return; } @@ -145,21 +145,21 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns const char *host = rdata->get_host(); - switch (result->result) { + switch (result->ts_result.result) { case PARENT_UNDEFINED: Debug("parent_select", "PARENT_UNDEFINED"); - Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->result]); + Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->ts_result.result]); break; case PARENT_FAIL: Debug("parent_select", "PARENT_FAIL"); break; case PARENT_DIRECT: Debug("parent_select", "PARENT_DIRECT"); - Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->result]); + Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->ts_result.result]); break; case PARENT_SPECIFIED: Debug("parent_select", "PARENT_SPECIFIED"); - Debug("parent_select", "Result for %s was parent %s:%d", host, result->hostname, result->port); + Debug("parent_select", "Result for %s was parent %s:%d", host, result->ts_result.hostname, result->ts_result.port); break; default: // Handled here: @@ -177,19 +177,19 @@ ParentConfigParams::nextParent(HttpRequestData *rdata, ParentResult *result, uns // Make sure that we are being called back with a // result structure with a parent - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { - result->result = PARENT_FAIL; + ink_assert(result->ts_result.result == PARENT_SPECIFIED); + if (result->ts_result.result != PARENT_SPECIFIED) { + result->ts_result.result = PARENT_FAIL; return; } // If we were set through the API we currently have not failover // so just return fail if (result->is_api_result()) { - Debug("parent_select", "Retry result for %s was %s", rdata->get_host(), ParentResultStr[result->result]); - result->result = PARENT_FAIL; + Debug("parent_select", "Retry result for %s was %s", rdata->get_host(), ParentResultStr[result->ts_result.result]); + result->ts_result.result = PARENT_FAIL; return; } - Debug("parent_select", "ParentConfigParams::nextParent(): result->r: %d, tablePtr: %p", result->result, tablePtr); + Debug("parent_select", "ParentConfigParams::nextParent(): result->r: %d, tablePtr: %p", result->ts_result.result, tablePtr); // Find the next parent in the array Debug("parent_select", "Calling selectParent() from nextParent"); @@ -197,21 +197,21 @@ ParentConfigParams::nextParent(HttpRequestData *rdata, ParentResult *result, uns const char *host = rdata->get_host(); - switch (result->result) { + switch (result->ts_result.result) { case PARENT_UNDEFINED: Debug("parent_select", "PARENT_UNDEFINED"); - Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); + Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->ts_result.result]); break; case PARENT_FAIL: Debug("parent_select", "PARENT_FAIL"); - Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); + Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->ts_result.result]); break; case PARENT_DIRECT: Debug("parent_select", "PARENT_DIRECT"); - Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); + Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->ts_result.result]); break; case PARENT_SPECIFIED: - Debug("parent_select", "Retry result for %s was parent %s:%d", host, result->hostname, result->port); + Debug("parent_select", "Retry result for %s was parent %s:%d", host, result->ts_result.hostname, result->ts_result.port); break; default: // Handled here: @@ -397,7 +397,7 @@ ParentRecord::PreProcessParents(const char *val, const int line_num, char *buf, continue; } else { Debug("parent_select", "token: %s, matches this machine. Marking down self from parent list at line %d", fqdn, line_num); - hs.setHostStatus(fqdn, HostStatus_t::HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); + hs.setHostStatus(fqdn, TSHostStatus::TS_HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); } } } else { @@ -409,7 +409,7 @@ ParentRecord::PreProcessParents(const char *val, const int line_num, char *buf, } else { Debug("parent_select", "token: %s, matches this machine. Marking down self from parent list at line %d", token, line_num); - hs.setHostStatus(token, HostStatus_t::HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); + hs.setHostStatus(token, TSHostStatus::TS_HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); } } } @@ -841,9 +841,9 @@ ParentRecord::Init(matcher_line *line_info) void ParentRecord::UpdateMatch(ParentResult *result, RequestData *rdata) { - if (this->CheckForMatch((HttpRequestData *)rdata, result->line_number) == true) { + if (this->CheckForMatch((HttpRequestData *)rdata, result->ts_result.line_number) == true) { result->rec = this; - result->line_number = this->line_num; + result->ts_result.line_number = this->line_num; Debug("parent_select", "Matched with %p parent node from line %d", this, this->line_num); } @@ -1106,11 +1106,11 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // from records.snap as DOWN due to previous testing. // HostStatus &_st = HostStatus::instance(); - _st.setHostStatus("furry", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("fluffy", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("frisky", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("fuzzy", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("curly", HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("furry", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fluffy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("frisky", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("curly", TS_HOST_STATUS_UP, 0, Reason::MANUAL); // Test 1 tbl[0] = '\0'; @@ -1496,7 +1496,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // Test 184 // mark fuzzy down with HostStatus API. - _st.setHostStatus("fuzzy", HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); ST(184); REINIT; @@ -1507,7 +1507,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // Test 185 // mark fluffy down and expect furry to be chosen - _st.setHostStatus("fluffy", HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("fluffy", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); ST(185); REINIT; @@ -1518,9 +1518,9 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // Test 186 // mark furry and frisky down, fuzzy up and expect fuzzy to be chosen - _st.setHostStatus("furry", HOST_STATUS_DOWN, 0, Reason::MANUAL); - _st.setHostStatus("frisky", HOST_STATUS_DOWN, 0, Reason::MANUAL); - _st.setHostStatus("fuzzy", HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("furry", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("frisky", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); ST(186); REINIT; @@ -1538,10 +1538,10 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REBUILD; // mark all up. - _st.setHostStatus("furry", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("fluffy", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("frisky", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("fuzzy", HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("furry", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fluffy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("frisky", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); REINIT; br(request, "i.am.rabbit.net"); @@ -1551,7 +1551,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // Test 188 // mark fuzzy down and expect fluffy. - _st.setHostStatus("fuzzy", HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); ST(188); REINIT; @@ -1562,7 +1562,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // Test 189 // mark fuzzy back up and expect fuzzy. - _st.setHostStatus("fuzzy", HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); ST(189); REINIT; @@ -1578,7 +1578,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // because the host status is set to down. params->markParentDown(result, fail_threshold, retry_time); // set host status down - _st.setHostStatus("fuzzy", HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); // sleep long enough so that fuzzy is retryable sleep(params->policy.ParentRetryTime + 1); ST(190); @@ -1589,7 +1589,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // now set the host status on fuzzy to up and it should now // be retried. - _st.setHostStatus("fuzzy", HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); ST(191); REINIT; br(request, "i.am.rabbit.net"); @@ -1602,10 +1602,10 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, T("dest_domain=rabbit.net parent=fuzzy:80,fluffy:80,furry:80,frisky:80 round_robin=false go_direct=true\n"); REBUILD; // mark all up. - _st.setHostStatus("fuzzy", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("fluffy", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("furry", HOST_STATUS_UP, 0, Reason::MANUAL); - _st.setHostStatus("frisky", HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fluffy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("furry", TS_HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("frisky", TS_HOST_STATUS_UP, 0, Reason::MANUAL); // fuzzy should be chosen. sleep(1); REINIT; @@ -1620,7 +1620,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, sleep(params->policy.ParentRetryTime + 1); // since the host status is down even though fuzzy is // retryable, fluffy should be chosen - _st.setHostStatus("fuzzy", HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); REINIT; br(request, "i.am.rabbit.net"); FP; @@ -1630,7 +1630,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // set the host status for fuzzy back up and since its // retryable fuzzy should be chosen ST(194); - _st.setHostStatus("fuzzy", HOST_STATUS_UP, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_UP, 0, Reason::MANUAL); REINIT; br(request, "i.am.rabbit.net"); FP; @@ -1751,7 +1751,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, T("dest_domain=rabbit.net parent=fuzzy:80|1.0;fluffy:80|1.0 secondary_parent=furry:80|1.0;frisky:80|1.0 " "round_robin=consistent_hash go_direct=false secondary_mode=3\n"); REBUILD; - _st.setHostStatus("fuzzy", HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("fuzzy", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); REINIT; br(request, "i.am.rabbit.net"); FP; @@ -1822,7 +1822,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, "round_robin=consistent_hash go_direct=false\n"); REBUILD; REINIT; - _st.setHostStatus("curly", HOST_STATUS_DOWN, 0, Reason::MANUAL); + _st.setHostStatus("curly", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); br(request, "i.am.stooges.net"); FP; RE(verify(result, PARENT_SPECIFIED, "carol", 80), 211); @@ -1837,12 +1837,12 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // verify returns 1 iff the test passes int -verify(ParentResult *r, ParentResultType e, const char *h, int p) +verify(ParentResult *r, TSParentResultType e, const char *h, int p) { if (is_debug_tag_set("parent_select")) { show_result(r); } - return (r->result != e) ? 0 : ((e != PARENT_SPECIFIED) ? 1 : (strcmp(r->hostname, h) ? 0 : ((r->port == p) ? 1 : 0))); + return (r->ts_result.result != e) ? 0 : ((e != PARENT_SPECIFIED) ? 1 : (strcmp(r->ts_result.hostname, h) ? 0 : ((r->ts_result.port == p) ? 1 : 0))); } // br creates an HttpRequestData object @@ -1864,7 +1864,7 @@ br(HttpRequestData *h, const char *os_hostname, sockaddr const *dest_ip) void show_result(ParentResult *p) { - switch (p->result) { + switch (p->ts_result.result) { case PARENT_UNDEFINED: printf("result is PARENT_UNDEFINED\n"); break; @@ -1873,8 +1873,8 @@ show_result(ParentResult *p) break; case PARENT_SPECIFIED: printf("result is PARENT_SPECIFIED\n"); - printf("hostname is %s\n", p->hostname); - printf("port is %d\n", p->port); + printf("hostname is %s\n", p->ts_result.hostname); + printf("port is %d\n", p->ts_result.port); break; case PARENT_FAIL: printf("result is PARENT_FAIL\n"); diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h index 010fcba509a..95085cbe3ed 100644 --- a/proxy/ParentSelection.h +++ b/proxy/ParentSelection.h @@ -37,6 +37,7 @@ #include "tscore/ConsistentHash.h" #include "tscore/Tokenizer.h" #include "tscore/ink_apidefs.h" +#include "ts/parentresult.h" #include "HostStatus.h" #include @@ -51,16 +52,6 @@ struct OverridableHttpConfigParams; class ParentRecord; class ParentSelectionStrategy; -enum ParentResultType { - PARENT_UNDEFINED, - PARENT_DIRECT, - PARENT_SPECIFIED, - PARENT_AGENT, - PARENT_FAIL, -}; - -static const char *ParentResultStr[] = {"PARENT_UNDEFINED", "PARENT_DIRECT", "PARENT_SPECIFIED", "PARENT_AGENT", "PARENT_FAIL"}; - enum ParentRR_t { P_NO_ROUND_ROBIN = 0, P_STRICT_ROUND_ROBIN, @@ -174,29 +165,19 @@ class ParentRecord : public ControlBase // between HttpTransact & the parent selection code. The following ParentRecord *const extApiRecord = (ParentRecord *)0xeeeeffff; -// used here to to set the number of ATSConsistentHashIter's -// used in NextHopSelectionStrategy to limit the host group -// size as well, group size is one to one with the number of rings -constexpr const uint32_t MAX_GROUP_RINGS = 5; - struct ParentResult { + TSParentResult ts_result; + ParentResult() { reset(); } - // For outside consumption - ParentResultType result; - const char *hostname; - int port; - bool retry; - bool chash_init[MAX_GROUP_RINGS] = {false}; - HostStatus_t first_choice_status = HostStatus_t::HOST_STATUS_INIT; void reset() { ink_zero(*this); - line_number = -1; - result = PARENT_UNDEFINED; - mapWrapped[0] = false; - mapWrapped[1] = false; + ts_result.line_number = -1; + ts_result.result = PARENT_UNDEFINED; + ts_result.mapWrapped[0] = false; + ts_result.mapWrapped[1] = false; } bool @@ -213,7 +194,7 @@ struct ParentResult { // If we don't have a result, we either haven't done a parent // lookup yet (PARENT_UNDEFINED), or the lookup didn't match // anything (PARENT_DIRECT). - ink_assert(result == PARENT_UNDEFINED || result == PARENT_DIRECT); + ink_assert(ts_result.result == PARENT_UNDEFINED || ts_result.result == PARENT_DIRECT); return false; } @@ -281,7 +262,7 @@ struct ParentResult { return false; } else { // Caller should check for a valid result beforehand. - ink_assert(result != PARENT_UNDEFINED); + ink_assert(ts_result.result != PARENT_UNDEFINED); ink_assert(is_some()); return rec->bypass_ok(); } @@ -292,23 +273,14 @@ struct ParentResult { { printf("ParentResult - hostname: %s, port: %d, retry: %s, line_number: %d, last_parent: %d, start_parent: %d, wrap_around: %s, " "last_lookup: %d, result: %s\n", - hostname, port, (retry) ? "true" : "false", line_number, last_parent, start_parent, (wrap_around) ? "true" : "false", - last_lookup, ParentResultStr[result]); + ts_result.hostname, ts_result.port, (ts_result.retry) ? "true" : "false", ts_result.line_number, ts_result.last_parent, ts_result.start_parent, (ts_result.wrap_around) ? "true" : "false", + ts_result.last_lookup, ParentResultStr[ts_result.result]); } private: // Internal use only // Not to be modified by HTTP - int line_number; ParentRecord *rec; - uint32_t last_parent; - uint32_t start_parent; - uint32_t last_group; - bool wrap_around; - bool mapWrapped[2]; - // state for consistent hash. - int last_lookup; - ATSConsistentHashIter chashIter[MAX_GROUP_RINGS]; friend class NextHopSelectionStrategy; friend class NextHopRoundRobin; @@ -440,7 +412,7 @@ ParentRecord *createDefaultParent(char *val); // Unit Test Functions void show_result(ParentResult *aParentResult); void br(HttpRequestData *h, const char *os_hostname, sockaddr const *dest_ip = nullptr); // short for build request -int verify(ParentResult *r, ParentResultType e, const char *h, int p); +int verify(ParentResult *r, TSParentResultType e, const char *h, int p); /* For supporting multiple Socks servers, we essentially use the diff --git a/proxy/ParentSelectionStrategy.cc b/proxy/ParentSelectionStrategy.cc index cf067b41ea3..3fa9d3d8e0f 100644 --- a/proxy/ParentSelectionStrategy.cc +++ b/proxy/ParentSelectionStrategy.cc @@ -32,8 +32,8 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ // Make sure that we are being called back with with a // result structure with a parent - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { + ink_assert(result->ts_result.result == PARENT_SPECIFIED); + if (result->ts_result.result != PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover @@ -42,8 +42,8 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ return; } - ink_assert((result->last_parent) < numParents(result)); - pRec = (parents + result->last_parent); + ink_assert((result->ts_result.last_parent) < numParents(result)); + pRec = (parents + result->ts_result.last_parent); // If the parent has already been marked down, just increment // the failure count. If this is the first mark down on a @@ -53,7 +53,7 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ // handle this condition. If this was the result of a retry, we // must update move the failedAt timestamp to now so that we continue // negative cache the parent - if (pRec->failedAt == 0 || result->retry == true) { + if (pRec->failedAt == 0 || result->ts_result.retry == true) { // Reread the current time. We want this to be accurate since // it relates to how long the parent has been down. now = time(nullptr); @@ -63,11 +63,11 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ // If this is clean mark down and not a failed retry, we // must set the count to reflect this - if (result->retry == false) { + if (result->ts_result.retry == false) { new_fail_count = pRec->failCount = 1; } - Note("Parent %s marked as down %s:%d", (result->retry) ? "retry" : "initially", pRec->hostname, pRec->port); + Note("Parent %s marked as down %s:%d", (result->ts_result.retry) ? "retry" : "initially", pRec->hostname, pRec->port); } else { int old_count = 0; @@ -103,9 +103,9 @@ ParentSelectionStrategy::markParentUp(ParentResult *result) // Make sure that we are being called back with with a // result structure with a parent that is being retried - ink_release_assert(result->retry == true); - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { + ink_release_assert(result->ts_result.retry == true); + ink_assert(result->ts_result.result == PARENT_SPECIFIED); + if (result->ts_result.result != PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover @@ -115,8 +115,8 @@ ParentSelectionStrategy::markParentUp(ParentResult *result) return; } - ink_assert((int)(result->last_parent) < num_parents); - pRec = parents + result->last_parent; + ink_assert((int)(result->ts_result.last_parent) < num_parents); + pRec = parents + result->ts_result.last_parent; ink_atomic_swap(&pRec->available, true); ink_atomic_swap(&pRec->failedAt, static_cast(0)); diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 6991b95c8ef..e4d5d6cbfea 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -7411,7 +7411,7 @@ HttpSM::set_next_state() call_transact_and_set_next_state(nullptr); break; } else if (t_state.http_config_param->use_client_target_addr == 2 && !t_state.url_remap_success && - t_state.parent_result.result != PARENT_SPECIFIED && t_state.client_info.is_transparent && + t_state.parent_result.ts_result.result != PARENT_SPECIFIED && t_state.client_info.is_transparent && t_state.dns_info.os_addr_style == HttpTransact::DNSLookupInfo::OS_Addr::OS_ADDR_TRY_DEFAULT && ats_is_ip(addr = ua_txn->get_netvc()->get_local_addr())) { /* If the connection is client side transparent and the URL @@ -7440,14 +7440,14 @@ HttpSM::set_next_state() t_state.dns_info.os_addr_style = HttpTransact::DNSLookupInfo::OS_Addr::OS_ADDR_TRY_CLIENT; call_transact_and_set_next_state(nullptr); break; - } else if (t_state.parent_result.result == PARENT_UNDEFINED && t_state.dns_info.lookup_success) { + } else if (t_state.parent_result.ts_result.result == PARENT_UNDEFINED && t_state.dns_info.lookup_success) { // Already set, and we don't have a parent proxy to lookup ink_assert(ats_is_ip(t_state.host_db_info.ip())); SMDebug("dns", "[HttpTransact::HandleRequest] Skipping DNS lookup, provided by plugin"); call_transact_and_set_next_state(nullptr); break; } else if (t_state.dns_info.looking_up == HttpTransact::ORIGIN_SERVER && t_state.http_config_param->no_dns_forward_to_parent && - t_state.parent_result.result != PARENT_UNDEFINED) { + t_state.parent_result.ts_result.result != PARENT_UNDEFINED) { t_state.dns_info.lookup_success = true; call_transact_and_set_next_state(nullptr); break; diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index ebec4d33c82..7d812987c13 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -99,7 +99,7 @@ bypass_ok(HttpTransact::State *s) if (mp && mp->strategy) { // remap strategies do not support the TSHttpTxnParentProxySet API. - r = mp->strategy->go_direct; + r = mp->strategy->goDirect(); } else if (s->parent_params) { r = s->parent_result.bypass_ok(); } @@ -154,7 +154,7 @@ parent_is_proxy(HttpTransact::State *s) url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - r = mp->strategy->parent_is_proxy; + r = mp->strategy->parentIsProxy(); } else if (s->parent_params) { r = s->parent_result.parent_is_proxy(); } @@ -196,8 +196,7 @@ markParentDown(HttpTransact::State *s) url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, - s->parent_result.port, NH_MARK_DOWN); + return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.ts_result.hostname, s->parent_result.ts_result.port, NH_MARK_DOWN); } else if (s->parent_params) { return s->parent_params->markParentDown(&s->parent_result, s->txn_conf->parent_fail_threshold, s->txn_conf->parent_retry_time); } @@ -210,8 +209,7 @@ markParentUp(HttpTransact::State *s) { url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, - s->parent_result.port, NH_MARK_UP); + return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.ts_result.hostname, s->parent_result.ts_result.port, NH_MARK_UP); } else if (s->parent_params) { return s->parent_params->markParentUp(&s->parent_result); } @@ -343,8 +341,8 @@ response_is_retryable(HttpTransact::State *s, HTTPStatus response_code) const url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - if (mp->strategy->responseIsRetryable(s->current.simple_retry_attempts, response_code)) { - if (mp->strategy->onFailureMarkParentDown(response_code)) { + if (mp->strategy->responseIsRetryable(s->current.simple_retry_attempts, static_cast(response_code))) { + if (mp->strategy->onFailureMarkParentDown(static_cast(response_code))) { return PARENT_RETRY_UNAVAILABLE_SERVER; } else { return PARENT_RETRY_SIMPLE; @@ -535,16 +533,16 @@ find_server_and_update_current_info(HttpTransact::State *s) // I just wanted to do this for cop heartbeats, someone else // wanted it for all requests to local_host. TxnDebug("http_trans", "request is from localhost, so bypass parent"); - s->parent_result.result = PARENT_DIRECT; + s->parent_result.ts_result.result = PARENT_DIRECT; } else if (s->method == HTTP_WKSIDX_CONNECT && s->http_config_param->disable_ssl_parenting) { - if (s->parent_result.result == PARENT_SPECIFIED) { + if (s->parent_result.ts_result.result == PARENT_SPECIFIED) { nextParent(s); } else { findParent(s); } if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) { TxnDebug("http_trans", "request not cacheable, so bypass parent"); - s->parent_result.result = PARENT_DIRECT; + s->parent_result.ts_result.result = PARENT_DIRECT; } } else if (s->txn_conf->uncacheable_requests_bypass_parent && s->http_config_param->no_dns_forward_to_parent == 0 && !HttpTransact::is_request_cache_lookupable(s)) { @@ -554,17 +552,17 @@ find_server_and_update_current_info(HttpTransact::State *s) // we are assuming both child and parent have similar configuration // with respect to whether a request is cacheable or not. // For example, the cache_urls_that_look_dynamic variable. - if (s->parent_result.result == PARENT_SPECIFIED) { + if (s->parent_result.ts_result.result == PARENT_SPECIFIED) { nextParent(s); } else { findParent(s); } if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) { TxnDebug("http_trans", "request not cacheable, so bypass parent"); - s->parent_result.result = PARENT_DIRECT; + s->parent_result.ts_result.result = PARENT_DIRECT; } } else { - switch (s->parent_result.result) { + switch (s->parent_result.ts_result.result) { case PARENT_UNDEFINED: findParent(s); break; @@ -575,9 +573,9 @@ find_server_and_update_current_info(HttpTransact::State *s) // We already have a parent that failed, if we are now told // to go the origin server, we can only obey this if we // dns'ed the origin server - if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 0) { + if (s->parent_result.ts_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 0) { ink_assert(!s->server_info.dst_addr.isValid()); - s->parent_result.result = PARENT_FAIL; + s->parent_result.ts_result.result = PARENT_FAIL; } break; case PARENT_FAIL: @@ -588,7 +586,7 @@ find_server_and_update_current_info(HttpTransact::State *s) // 3) the parent was not set from API if (s->http_config_param->no_dns_forward_to_parent == 0 && bypass_ok(s) && parent_is_proxy(s) && !s->parent_params->apiParentExists(&s->request_data)) { - s->parent_result.result = PARENT_DIRECT; + s->parent_result.ts_result.result = PARENT_DIRECT; } break; default: @@ -602,9 +600,9 @@ find_server_and_update_current_info(HttpTransact::State *s) } } - switch (s->parent_result.result) { + switch (s->parent_result.ts_result.result) { case PARENT_SPECIFIED: - s->parent_info.name = s->arena.str_store(s->parent_result.hostname, strlen(s->parent_result.hostname)); + s->parent_info.name = s->arena.str_store(s->parent_result.ts_result.hostname, strlen(s->parent_result.ts_result.hostname)); update_current_info(&s->current, &s->parent_info, HttpTransact::PARENT_PROXY, (s->current.attempts)++); update_dns_info(&s->dns_info, &s->current); ink_assert(s->dns_info.looking_up == HttpTransact::PARENT_PROXY); @@ -621,7 +619,7 @@ find_server_and_update_current_info(HttpTransact::State *s) // we're unable to go direct to the origin. if (s->http_config_param->no_dns_forward_to_parent) { Warning("no available parents and the config proxy.config.http.no_dns_just_forward_to_parent, prevents origin lookups."); - s->parent_result.result = PARENT_FAIL; + s->parent_result.ts_result.result = PARENT_FAIL; return HttpTransact::HOST_NONE; } /* fall through */ @@ -1733,7 +1731,7 @@ HttpTransact::PPDNSLookup(State *s) if (!s->current.server->dst_addr.isValid()) { if (s->current.request_to == PARENT_PROXY) { TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, PPDNSLookup); - } else if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { + } else if (s->parent_result.ts_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { // We ran out of parents but parent configuration allows us to go to Origin Server directly return CallOSDNSLookup(s); } else { @@ -1746,7 +1744,7 @@ HttpTransact::PPDNSLookup(State *s) } else { // lookup succeeded, open connection to p.p. ats_ip_copy(&s->parent_info.dst_addr, s->host_db_info.ip()); - s->parent_info.dst_addr.port() = htons(s->parent_result.port); + s->parent_info.dst_addr.port() = htons(s->parent_result.ts_result.port); get_ka_info_from_host_db(s, &s->parent_info, &s->client_info, &s->host_db_info); char addrbuf[INET6_ADDRSTRLEN]; @@ -2149,7 +2147,7 @@ HttpTransact::LookupSkipOpenServer(State *s) if (s->current.request_to == PARENT_PROXY) { TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, PPDNSLookup); - } else if (s->parent_result.result == PARENT_FAIL) { + } else if (s->parent_result.ts_result.result == PARENT_FAIL) { handle_parent_died(s); return; } @@ -2591,7 +2589,7 @@ HttpTransact::CallOSDNSLookup(State *s) TxnDebug("http", "[HttpTransact::callos] %s ", s->server_info.name); HostStatus &pstatus = HostStatus::instance(); HostStatRec *hst = pstatus.getHostStatus(s->server_info.name); - if (hst && hst->status == HostStatus_t::HOST_STATUS_DOWN) { + if (hst && hst->status == TSHostStatus::TS_HOST_STATUS_DOWN) { TxnDebug("http", "[HttpTransact::callos] %d ", s->cache_lookup_result); s->current.state = OUTBOUND_CONGESTION; if (s->cache_lookup_result == CACHE_LOOKUP_HIT_STALE || s->cache_lookup_result == CACHE_LOOKUP_HIT_WARNING || @@ -2833,7 +2831,7 @@ HttpTransact::HandleCacheOpenReadHit(State *s) } // a parent lookup could come back as PARENT_FAIL if in parent.config, go_direct == false and // there are no available parents (all down). - else if (s->current.request_to == HOST_NONE && s->parent_result.result == PARENT_FAIL) { + else if (s->current.request_to == HOST_NONE && s->parent_result.ts_result.result == PARENT_FAIL) { if (is_server_negative_cached(s) && response_returnable == true && is_stale_cache_response_returnable(s) == true) { server_up = false; update_current_info(&s->current, nullptr, UNDEFINED_LOOKUP, 0); @@ -3275,14 +3273,14 @@ HttpTransact::HandleCacheOpenReadMiss(State *s) find_server_and_update_current_info(s); // a parent lookup could come back as PARENT_FAIL if in parent.config go_direct == false and // there are no available parents (all down). - if (s->parent_result.result == PARENT_FAIL) { + if (s->parent_result.ts_result.result == PARENT_FAIL) { handle_parent_died(s); return; } if (!s->current.server->dst_addr.isValid()) { - ink_release_assert(s->parent_result.result == PARENT_DIRECT || s->current.request_to == PARENT_PROXY || + ink_release_assert(s->parent_result.ts_result.result == PARENT_DIRECT || s->current.request_to == PARENT_PROXY || s->http_config_param->no_dns_forward_to_parent != 0); - if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { + if (s->parent_result.ts_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { return CallOSDNSLookup(s); } if (s->current.request_to == PARENT_PROXY) { @@ -3550,7 +3548,7 @@ HttpTransact::handle_response_from_parent(State *s) TxnDebug("http_trans", "[hrfp] connection alive"); s->current.server->connect_result = 0; SET_VIA_STRING(VIA_DETAIL_PP_CONNECT, VIA_DETAIL_PP_SUCCESS); - if (s->parent_result.retry) { + if (s->parent_result.ts_result.retry) { markParentUp(s); } handle_forward_server_connection_open(s); @@ -3587,7 +3585,7 @@ HttpTransact::handle_response_from_parent(State *s) if (s->current.state != OUTBOUND_CONGESTION) { markParentDown(s); } - s->parent_result.result = PARENT_FAIL; + s->parent_result.ts_result.result = PARENT_FAIL; handle_parent_died(s); return; } @@ -3625,7 +3623,7 @@ HttpTransact::handle_response_from_parent(State *s) if (s->current.state == CONNECTION_ERROR) { markParentDown(s); } - s->parent_result.result = PARENT_FAIL; + s->parent_result.ts_result.result = PARENT_FAIL; next_lookup = HOST_NONE; } break; @@ -7453,7 +7451,7 @@ HttpTransact::AuthenticationNeeded(const OverridableHttpConfigParams *p, HTTPHdr void HttpTransact::handle_parent_died(State *s) { - ink_assert(s->parent_result.result == PARENT_FAIL); + ink_assert(s->parent_result.ts_result.result == PARENT_FAIL); if (s->current.state == OUTBOUND_CONGESTION) { build_error_response(s, HTTP_STATUS_SERVICE_UNAVAILABLE, "Next Hop Congested", "congestion#retryAfter"); diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h index 5bce8fb92a4..7679e86dc95 100644 --- a/proxy/http/HttpTransact.h +++ b/proxy/http/HttpTransact.h @@ -693,8 +693,8 @@ class HttpTransact TransactFunc_t pending_work = nullptr; HttpRequestData request_data; - ParentConfigParams *parent_params = nullptr; - std::shared_ptr next_hop_strategy = nullptr; + ParentConfigParams *parent_params = nullptr; + std::shared_ptr next_hop_strategy = nullptr; ParentResult parent_result; CacheControlResult cache_control; CacheLookupResult_t cache_lookup_result = CACHE_LOOKUP_NONE; diff --git a/proxy/http/remap/NextHopConsistentHash.cc b/proxy/http/remap/NextHopConsistentHash.cc index c14c971bf9a..d7b9c276c57 100644 --- a/proxy/http/remap/NextHopConsistentHash.cc +++ b/proxy/http/remap/NextHopConsistentHash.cc @@ -56,6 +56,10 @@ chash_lookup(const std::shared_ptr &ring, uint64_t hash_key, return host_rec; } +NextHopConsistentHash::NextHopConsistentHash(const std::string_view name) + : NextHopSelectionStrategy(name) +{} + NextHopConsistentHash::~NextHopConsistentHash() { NH_Debug(NH_DEBUG_TAG, "destructor called for strategy named: %s", strategy_name.c_str()); @@ -208,7 +212,7 @@ NextHopConsistentHash::getHashKey(uint64_t sm_id, HttpRequestData *hrdata, ATSHa } void -NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void *ih, time_t now) +NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) { HttpSM *sm = reinterpret_cast(txnp); ParentResult *result = &sm->t_state.parent_result; @@ -227,39 +231,39 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void *ih, time_t now) HostRecord *hostRec = nullptr; std::shared_ptr pRec = nullptr; HostStatus &pStatus = HostStatus::instance(); - HostStatus_t host_stat = HostStatus_t::HOST_STATUS_INIT; + TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_INIT; HostStatRec *hst = nullptr; - if (result->line_number == -1 && result->result == PARENT_UNDEFINED) { + if (result->ts_result.line_number == -1 && result->ts_result.result == PARENT_UNDEFINED) { firstcall = true; } if (firstcall) { - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] firstcall, line_number: %d, result: %s", sm_id, result->line_number, - ParentResultStr[result->result]); - result->line_number = distance; + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] firstcall, line_number: %d, result: %s", sm_id, result->ts_result.line_number, + ParentResultStr[result->ts_result.result]); + result->ts_result.line_number = NextHopConsistentHash::LineNumberPlaceholder; cur_ring = 0; for (uint32_t i = 0; i < groups; i++) { - result->chash_init[i] = false; + result->ts_result.chash_init[i] = false; wrap_around[i] = false; } } else { - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] not firstcall, line_number: %d, result: %s", sm_id, result->line_number, - ParentResultStr[result->result]); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] not firstcall, line_number: %d, result: %s", sm_id, result->ts_result.line_number, + ParentResultStr[result->ts_result.result]); switch (ring_mode) { case NH_ALTERNATE_RING: if (groups > 1) { - cur_ring = (result->last_group + 1) % groups; + cur_ring = (result->ts_result.last_group + 1) % groups; } else { - cur_ring = result->last_group; + cur_ring = result->ts_result.last_group; } break; case NH_EXHAUST_RING: default: if (!wrapped) { - cur_ring = result->last_group; + cur_ring = result->ts_result.last_group; } else if (groups > 1) { - cur_ring = (result->last_group + 1) % groups; + cur_ring = (result->ts_result.last_group + 1) % groups; } break; } @@ -270,8 +274,8 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void *ih, time_t now) do { // search until we've selected a different parent if !firstcall std::shared_ptr r = rings[cur_ring]; - hostRec = chash_lookup(r, hash_key, &result->chashIter[cur_ring], &wrapped, &hash, &result->chash_init[cur_ring], - &result->mapWrapped[cur_ring], sm_id); + hostRec = chash_lookup(r, hash_key, &result->ts_result.chashIter[cur_ring], &wrapped, &hash, &result->ts_result.chash_init[cur_ring], + &result->ts_result.mapWrapped[cur_ring], sm_id); wrap_around[cur_ring] = wrapped; lookups++; // the 'available' flag is maintained in 'host_groups' and not the hash ring. @@ -279,13 +283,13 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void *ih, time_t now) pRec = host_groups[hostRec->group_index][hostRec->host_index]; if (firstcall) { hst = (pRec) ? pStatus.getHostStatus(pRec->hostname.c_str()) : nullptr; - result->first_choice_status = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + result->ts_result.first_choice_status = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; break; } } else { pRec = nullptr; } - } while (pRec && result->hostname && strcmp(pRec->hostname.c_str(), result->hostname) == 0); + } while (pRec && result->ts_result.hostname && strcmp(pRec->hostname.c_str(), result->ts_result.hostname) == 0); NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Initial parent lookups: %d", sm_id, lookups); @@ -294,26 +298,26 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void *ih, time_t now) // ---------------------------------------------------------------------------------------------------- hst = (pRec) ? pStatus.getHostStatus(pRec->hostname.c_str()) : nullptr; - host_stat = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + host_stat = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble - if ((pRec && ignore_self_detect) && (hst && hst->status == HOST_STATUS_DOWN)) { + if ((pRec && ignore_self_detect) && (hst && hst->status == TS_HOST_STATUS_DOWN)) { if (hst->reasons == Reason::SELF_DETECT) { - host_stat = HOST_STATUS_UP; + host_stat = TS_HOST_STATUS_UP; } } - if (!pRec || (pRec && !pRec->available) || host_stat == HOST_STATUS_DOWN) { + if (!pRec || (pRec && !pRec->available) || host_stat == TS_HOST_STATUS_DOWN) { do { // check if an unavailable server is now retryable, use it if it is. - if (pRec && !pRec->available && host_stat == HOST_STATUS_UP) { + if (pRec && !pRec->available && host_stat == TS_HOST_STATUS_UP) { _now == 0 ? _now = time(nullptr) : _now = now; // check if the host is retryable. It's retryable if the retry window has elapsed if ((pRec->failedAt + retry_time) < static_cast(_now)) { nextHopRetry = true; - result->last_parent = pRec->host_index; - result->last_lookup = pRec->group_index; - result->retry = nextHopRetry; - result->result = PARENT_SPECIFIED; + result->ts_result.last_parent = pRec->host_index; + result->ts_result.last_lookup = pRec->group_index; + result->ts_result.retry = nextHopRetry; + result->ts_result.result = PARENT_SPECIFIED; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next hop %s is now retryable, marked it available.", sm_id, pRec->hostname.c_str()); break; } @@ -332,25 +336,25 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void *ih, time_t now) break; } std::shared_ptr r = rings[cur_ring]; - hostRec = chash_lookup(r, hash_key, &result->chashIter[cur_ring], &wrapped, &hash, &result->chash_init[cur_ring], - &result->mapWrapped[cur_ring], sm_id); + hostRec = chash_lookup(r, hash_key, &result->ts_result.chashIter[cur_ring], &wrapped, &hash, &result->ts_result.chash_init[cur_ring], + &result->ts_result.mapWrapped[cur_ring], sm_id); wrap_around[cur_ring] = wrapped; lookups++; if (hostRec) { pRec = host_groups[hostRec->group_index][hostRec->host_index]; hst = (pRec) ? pStatus.getHostStatus(pRec->hostname.c_str()) : nullptr; - host_stat = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + host_stat = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble - if ((pRec && ignore_self_detect) && (hst && hst->status == HOST_STATUS_DOWN)) { + if ((pRec && ignore_self_detect) && (hst && hst->status == TS_HOST_STATUS_DOWN)) { if (hst->reasons == Reason::SELF_DETECT) { - host_stat = HOST_STATUS_UP; + host_stat = TS_HOST_STATUS_UP; } } NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Selected a new parent: %s, available: %s, wrapped: %s, lookups: %d.", sm_id, pRec->hostname.c_str(), (pRec->available) ? "true" : "false", (wrapped) ? "true" : "false", lookups); // use available host. - if (pRec->available && host_stat == HOST_STATUS_UP) { + if (pRec->available && host_stat == TS_HOST_STATUS_UP) { break; } } else { @@ -369,43 +373,40 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void *ih, time_t now) } break; } - } while (!pRec || (pRec && !pRec->available) || host_stat == HOST_STATUS_DOWN); + } while (!pRec || (pRec && !pRec->available) || host_stat == TS_HOST_STATUS_DOWN); } // ---------------------------------------------------------------------------------------------------- // Validate and return the final result. // ---------------------------------------------------------------------------------------------------- - if (pRec && host_stat == HOST_STATUS_UP && (pRec->available || result->retry)) { - result->result = PARENT_SPECIFIED; - result->hostname = pRec->hostname.c_str(); - result->last_parent = pRec->host_index; - result->last_lookup = result->last_group = cur_ring; + if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->ts_result.retry)) { + result->ts_result.result = PARENT_SPECIFIED; + result->ts_result.hostname = pRec->hostname.c_str(); + result->ts_result.last_parent = pRec->host_index; + result->ts_result.last_lookup = result->ts_result.last_group = cur_ring; switch (scheme) { case NH_SCHEME_NONE: case NH_SCHEME_HTTP: - result->port = pRec->getPort(scheme); - break; case NH_SCHEME_HTTPS: - result->port = pRec->getPort(scheme); + result->ts_result.port = pRec->getPort(scheme); break; } - result->retry = nextHopRetry; - ink_assert(result->hostname != nullptr); - ink_assert(result->port != 0); - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s Chosen parent: %s.%d", sm_id, ParentResultStr[result->result], - result->hostname, result->port); + result->ts_result.retry = nextHopRetry; + ink_assert(result->ts_result.hostname != nullptr); + ink_assert(result->ts_result.port != 0); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->ts_result.result: %s Chosen parent: %s.%d", sm_id, ParentResultStr[result->ts_result.result], + result->ts_result.hostname, result->ts_result.port); } else { if (go_direct == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; - result->retry = false; - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, - ParentResultStr[result->result]); + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; + result->ts_result.retry = false; + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->ts_result.result: %s set hostname null port 0 retry false", sm_id, ParentResultStr[result->ts_result.result]); } return; diff --git a/proxy/http/remap/NextHopConsistentHash.h b/proxy/http/remap/NextHopConsistentHash.h index 6ce8cffb877..d71854a2854 100644 --- a/proxy/http/remap/NextHopConsistentHash.h +++ b/proxy/http/remap/NextHopConsistentHash.h @@ -38,16 +38,17 @@ enum NHHashKeyType { class NextHopConsistentHash : public NextHopSelectionStrategy { - std::vector> rings; - - uint64_t getHashKey(uint64_t sm_id, HttpRequestData *hrdata, ATSHash64 *h); - public: + const uint32_t LineNumberPlaceholder = 99999; + NHHashKeyType hash_key = NH_PATH_HASH_KEY; NextHopConsistentHash() = delete; - NextHopConsistentHash(const std::string_view name, const NHPolicyType &policy) : NextHopSelectionStrategy(name, policy) {} + NextHopConsistentHash(const std::string_view name); ~NextHopConsistentHash(); bool Init(const YAML::Node &n); - void findNextHop(TSHttpTxn txnp, void *ih = nullptr, time_t now = 0) override; + void findNextHop(TSHttpTxn txnp, time_t now = 0) override; +//private: + std::vector> rings; + uint64_t getHashKey(uint64_t sm_id, HttpRequestData *hrdata, ATSHash64 *h); }; diff --git a/proxy/http/remap/NextHopHealthStatus.cc b/proxy/http/remap/NextHopHealthStatus.cc index afb43c7222c..861d45327a6 100644 --- a/proxy/http/remap/NextHopHealthStatus.cc +++ b/proxy/http/remap/NextHopHealthStatus.cc @@ -39,33 +39,11 @@ NextHopHealthStatus::insert(std::vector> &hosts) } } -/** - * check that hostname is available for use. - */ -bool -NextHopHealthStatus::isNextHopAvailable(TSHttpTxn txn, const char *hostname, const int port, void *ih) -{ - HttpSM *sm = reinterpret_cast(txn); - int64_t sm_id = sm->sm_id; - - const std::string host_port = HostRecord::makeHostPort(hostname, port); - auto iter = host_map.find(host_port); - - if (iter == host_map.end()) { - NH_Debug(NH_DEBUG_TAG, "[%" PRId64 "] no host named %s found in host_map", sm_id, host_port.c_str()); - return false; - } - - std::shared_ptr p = iter->second; - return p->available; -} - /** * mark up or down the indicated host */ void -NextHopHealthStatus::markNextHop(TSHttpTxn txn, const char *hostname, const int port, const NHCmd status, void *ih, - const time_t now) +NextHopHealthStatus::markNextHop(TSHttpTxn txn, const char *hostname, const int port, const NHCmd status, const time_t now) { time_t _now; now == 0 ? _now = time(nullptr) : _now = now; @@ -80,9 +58,9 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txn, const char *hostname, const int // make sure we're called back with a result structure for a parent // that is being retried. if (status == NH_MARK_UP) { - ink_assert(result.retry == true); + ink_assert(result.ts_result.retry == true); } - if (result.result != PARENT_SPECIFIED) { + if (result.ts_result.result != PARENT_SPECIFIED) { return; } @@ -110,19 +88,19 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txn, const char *hostname, const int break; // Mark the host down. case NH_MARK_DOWN: - if (h->failedAt == 0 || result.retry == true) { + if (h->failedAt == 0 || result.ts_result.retry == true) { { // lock guard std::lock_guard guard(h->_mutex); if (h->failedAt == 0) { h->failedAt = _now; - if (result.retry == false) { + if (result.ts_result.retry == false) { new_fail_count = h->failCount = 1; } - } else if (result.retry == true) { + } else if (result.ts_result.retry == true) { h->failedAt = _now; } } // end lock guard - NH_Note("[%" PRId64 "] NextHop %s marked as down %s", sm_id, (result.retry) ? "retry" : "initially", h->hostname.c_str()); + NH_Note("[%" PRId64 "] NextHop %s marked as down %s", sm_id, (result.ts_result.retry) ? "retry" : "initially", h->hostname.c_str()); } else { int old_count = 0; // if the last failure was outside the retry window, set the failcount to 1 and failedAt to now. diff --git a/proxy/http/remap/NextHopRoundRobin.cc b/proxy/http/remap/NextHopRoundRobin.cc index 0bbcc298726..46782249c71 100644 --- a/proxy/http/remap/NextHopRoundRobin.cc +++ b/proxy/http/remap/NextHopRoundRobin.cc @@ -27,13 +27,20 @@ #include "HttpSM.h" #include "NextHopRoundRobin.h" +NextHopRoundRobin::NextHopRoundRobin(const std::string_view &name, const NHPolicyType &policy) + : NextHopSelectionStrategy(name) + , policy_type(policy) +{ + NH_Debug(NH_DEBUG_TAG, "Using a selection strategy of type %s", policy_strings[policy]); +} + NextHopRoundRobin::~NextHopRoundRobin() { NH_Debug(NH_DEBUG_TAG, "destructor called for strategy named: %s", strategy_name.c_str()); } void -NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) +NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) { HttpSM *sm = reinterpret_cast(txnp); ParentResult *result = &sm->t_state.parent_result; @@ -45,7 +52,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) bool firstcall = true; bool parentUp = false; bool parentRetry = false; - bool wrapped = result->wrap_around; + bool wrapped = result->ts_result.wrap_around; std::vector wrap_around(groups, false); uint32_t cur_hst_index = 0; uint32_t cur_grp_index = 0; @@ -54,39 +61,38 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) uint32_t start_host = 0; std::shared_ptr cur_host; HostStatus &pStatus = HostStatus::instance(); - HostStatus_t host_stat = HostStatus_t::HOST_STATUS_UP; + TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_UP; - if (result->line_number != -1 && result->result != PARENT_UNDEFINED) { + if (result->ts_result.line_number != -1 && result->ts_result.result != PARENT_UNDEFINED) { firstcall = false; } if (firstcall) { - // distance is the index into the strategies map, this is the equivalent to the old line_number in parent.config. - result->line_number = distance; - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] first call , cur_grp_index: %d, cur_hst_index: %d, distance: %d", sm_id, cur_grp_index, - cur_hst_index, distance); + result->ts_result.line_number = NextHopRoundRobin::LineNumberPlaceholder; + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] first call , cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, + cur_hst_index); switch (policy_type) { case NH_FIRST_LIVE: - result->start_parent = cur_hst_index = 0; + result->ts_result.start_parent = cur_hst_index = 0; cur_grp_index = 0; break; case NH_RR_STRICT: { std::lock_guard lock(_mutex); - cur_hst_index = result->start_parent = this->hst_index; + cur_hst_index = result->ts_result.start_parent = this->hst_index; cur_grp_index = 0; this->hst_index = (this->hst_index + 1) % hst_size; } break; case NH_RR_IP: cur_grp_index = 0; if (request_info.get_client_ip() != nullptr) { - cur_hst_index = result->start_parent = ntohl(ats_ip_hash(request_info.get_client_ip())) % hst_size; + cur_hst_index = result->ts_result.start_parent = ntohl(ats_ip_hash(request_info.get_client_ip())) % hst_size; } else { cur_hst_index = this->hst_index; } break; case NH_RR_LATCHED: cur_grp_index = 0; - cur_hst_index = result->start_parent = latched_index; + cur_hst_index = result->ts_result.start_parent = latched_index; break; default: ink_assert(0); @@ -95,23 +101,23 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) cur_host = host_groups[cur_grp_index][cur_hst_index]; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] first call, cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, cur_hst_index); } else { - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next call, cur_grp_index: %d, cur_hst_index: %d, distance: %d", sm_id, cur_grp_index, - cur_hst_index, distance); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next call, cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, + cur_hst_index); // Move to next parent due to failure - latched_index = cur_hst_index = (result->last_parent + 1) % hst_size; + latched_index = cur_hst_index = (result->ts_result.last_parent + 1) % hst_size; cur_host = host_groups[cur_grp_index][cur_hst_index]; // Check to see if we have wrapped around - if (static_cast(cur_hst_index) == result->start_parent) { + if (static_cast(cur_hst_index) == result->ts_result.start_parent) { // We've wrapped around so bypass if we can if (go_direct == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; - result->wrap_around = true; + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; + result->ts_result.wrap_around = true; return; } } @@ -122,12 +128,12 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) // should be retried do { HostStatRec *hst = pStatus.getHostStatus(cur_host->hostname.c_str()); - host_stat = (hst) ? hst->status : HostStatus_t::HOST_STATUS_UP; + host_stat = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble - if (ignore_self_detect && (hst && hst->status == HOST_STATUS_DOWN)) { + if (ignore_self_detect && (hst && hst->status == TS_HOST_STATUS_DOWN)) { if (hst->reasons == Reason::SELF_DETECT) { - host_stat = HOST_STATUS_UP; + host_stat = TS_HOST_STATUS_UP; } } @@ -138,7 +144,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) request_info.xact_start); // check if 'cur_host' is available, mark it up if it is. if ((cur_host->failedAt == 0) || (cur_host->failCount < fail_threshold)) { - if (host_stat == HOST_STATUS_UP) { + if (host_stat == TS_HOST_STATUS_UP) { NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Selecting a parent, %s, due to little failCount (faileAt: %d failCount: %d), FailThreshold: %" PRIu64, @@ -148,8 +154,8 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) } else { // if not available, check to see if it can be retried. If so, set the retry flag and temporairly mark it as // available. _now == 0 ? _now = time(nullptr) : _now = now; - if (((result->wrap_around) || (cur_host->failedAt + retry_time) < static_cast(_now)) && - host_stat == HOST_STATUS_UP) { + if (((result->ts_result.wrap_around) || (cur_host->failedAt + retry_time) < static_cast(_now)) && + host_stat == TS_HOST_STATUS_UP) { // Reuse the parent parentUp = true; parentRetry = true; @@ -163,17 +169,17 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) cur_host->hostname.c_str(), HostStatusNames[host_stat]); // The selected host is available or retryable, return the search result. - if (parentUp == true && host_stat != HOST_STATUS_DOWN) { + if (parentUp == true && host_stat != TS_HOST_STATUS_DOWN) { NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] status for %s: %s", sm_id, cur_host->hostname.c_str(), HostStatusNames[host_stat]); - result->result = PARENT_SPECIFIED; - result->hostname = cur_host->hostname.c_str(); - result->port = cur_host->getPort(scheme); - result->last_parent = cur_hst_index; - result->last_group = cur_grp_index; - result->retry = parentRetry; - ink_assert(result->hostname != nullptr); - ink_assert(result->port != 0); - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Chosen parent = %s.%d", sm_id, result->hostname, result->port); + result->ts_result.result = PARENT_SPECIFIED; + result->ts_result.hostname = cur_host->hostname.c_str(); + result->ts_result.port = cur_host->getPort(scheme); + result->ts_result.last_parent = cur_hst_index; + result->ts_result.last_group = cur_grp_index; + result->ts_result.retry = parentRetry; + ink_assert(result->ts_result.hostname != nullptr); + ink_assert(result->ts_result.port != 0); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Chosen parent = %s.%d", sm_id, result->ts_result.hostname, result->ts_result.port); return; } @@ -181,7 +187,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) if (groups == 1) { latched_index = cur_hst_index = (cur_hst_index + 1) % hst_size; if (start_host == cur_hst_index) { - wrap_around[cur_grp_index] = wrapped = result->wrap_around = true; + wrap_around[cur_grp_index] = wrapped = result->ts_result.wrap_around = true; } } else { // search the fail over groups. if (ring_mode == NH_ALTERNATE_RING) { // use alternating ring mode. @@ -190,7 +196,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) if (cur_grp_index == start_group) { latched_index = cur_hst_index = (cur_hst_index + 1) % hst_size; if (cur_hst_index == start_host) { - wrapped = wrap_around[cur_grp_index] = result->wrap_around = true; + wrapped = wrap_around[cur_grp_index] = result->ts_result.wrap_around = true; } } } else { // use the exhaust ring mode. @@ -199,7 +205,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) wrap_around[cur_grp_index] = true; cur_grp_index = (cur_grp_index + 1) % groups; if (cur_grp_index == start_group) { - wrapped = wrap_around[cur_grp_index] = result->wrap_around = true; + wrapped = wrap_around[cur_grp_index] = result->ts_result.wrap_around = true; } else { start_host = cur_hst_index = 0; } @@ -214,11 +220,11 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void *ih, time_t now) } while (!wrapped); if (go_direct == true) { - result->result = PARENT_DIRECT; + result->ts_result.result = PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->ts_result.result = PARENT_FAIL; } - result->hostname = nullptr; - result->port = 0; + result->ts_result.hostname = nullptr; + result->ts_result.port = 0; } diff --git a/proxy/http/remap/NextHopRoundRobin.h b/proxy/http/remap/NextHopRoundRobin.h index a7cb8233153..0caa5fe6774 100644 --- a/proxy/http/remap/NextHopRoundRobin.h +++ b/proxy/http/remap/NextHopRoundRobin.h @@ -28,17 +28,20 @@ class NextHopRoundRobin : public NextHopSelectionStrategy { - std::mutex _mutex; - uint32_t latched_index = 0; - public: + const uint32_t LineNumberPlaceholder = 99999; + NextHopRoundRobin() = delete; - NextHopRoundRobin(const std::string_view &name, const NHPolicyType &policy) : NextHopSelectionStrategy(name, policy) {} + NextHopRoundRobin(const std::string_view &name, const NHPolicyType &policy); ~NextHopRoundRobin(); bool Init(const YAML::Node &n) { return NextHopSelectionStrategy::Init(n); } - void findNextHop(TSHttpTxn txnp, void *ih = nullptr, time_t now = 0) override; + void findNextHop(TSHttpTxn txnp, time_t now = 0) override; +//private: + std::mutex _mutex; + uint32_t latched_index = 0; + NHPolicyType policy_type = NH_UNDEFINED; }; diff --git a/proxy/http/remap/NextHopSelectionStrategy.cc b/proxy/http/remap/NextHopSelectionStrategy.cc index e589c3ebc2f..0b75d193124 100644 --- a/proxy/http/remap/NextHopSelectionStrategy.cc +++ b/proxy/http/remap/NextHopSelectionStrategy.cc @@ -34,14 +34,9 @@ constexpr std::string_view exhaust_rings = "exhaust_ring"; constexpr std::string_view active_health_check = "active"; constexpr std::string_view passive_health_check = "passive"; -constexpr const char *policy_strings[] = {"NH_UNDEFINED", "NH_FIRST_LIVE", "NH_RR_STRICT", - "NH_RR_IP", "NH_RR_LATCHED", "NH_CONSISTENT_HASH"}; - -NextHopSelectionStrategy::NextHopSelectionStrategy(const std::string_view &name, const NHPolicyType &policy) +NextHopSelectionStrategy::NextHopSelectionStrategy(const std::string_view &name) { strategy_name = name; - policy_type = policy; - NH_Debug(NH_DEBUG_TAG, "Using a selection strategy of type %s", policy_strings[policy]); } // @@ -150,10 +145,10 @@ NextHopSelectionStrategy::Init(const YAML::Node &n) Machine *mach = Machine::instance(); HostStatus &h_stat = HostStatus::instance(); uint32_t grp_size = groups_node.size(); - if (grp_size > MAX_GROUP_RINGS) { + if (grp_size > TS_MAX_GROUP_RINGS) { NH_Note("the groups list exceeds the maximum of %d for the strategy '%s'. Only the first %d groups will be configured.", - MAX_GROUP_RINGS, strategy_name.c_str(), MAX_GROUP_RINGS); - groups = MAX_GROUP_RINGS; + TS_MAX_GROUP_RINGS, strategy_name.c_str(), TS_MAX_GROUP_RINGS); + groups = TS_MAX_GROUP_RINGS; } else { groups = groups_node.size(); } @@ -175,7 +170,7 @@ NextHopSelectionStrategy::Init(const YAML::Node &n) host_rec->group_index = grp; host_rec->host_index = hst; if (mach->is_self(host_rec->hostname.c_str())) { - h_stat.setHostStatus(host_rec->hostname.c_str(), HostStatus_t::HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); + h_stat.setHostStatus(host_rec->hostname.c_str(), TSHostStatus::TS_HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); } hosts_inner.push_back(std::move(host_rec)); num_parents++; @@ -195,14 +190,13 @@ NextHopSelectionStrategy::Init(const YAML::Node &n) } void -NextHopSelectionStrategy::markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, void *ih, - const time_t now) +NextHopSelectionStrategy::markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now) { - return passive_health.markNextHop(txnp, hostname, port, status, ih, now); + return passive_health.markNextHop(txnp, hostname, port, status, now); } bool -NextHopSelectionStrategy::nextHopExists(TSHttpTxn txnp, void *ih) +NextHopSelectionStrategy::nextHopExists(TSHttpTxn txnp) { HttpSM *sm = reinterpret_cast(txnp); int64_t sm_id = sm->sm_id; @@ -220,16 +214,27 @@ NextHopSelectionStrategy::nextHopExists(TSHttpTxn txnp, void *ih) } bool -NextHopSelectionStrategy::responseIsRetryable(unsigned int current_retry_attempts, HTTPStatus response_code) +NextHopSelectionStrategy::responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) { + return this->resp_codes.contains(static_cast(response_code)) && + current_retry_attempts < this->max_simple_retries && + current_retry_attempts < this->num_parents; +} + +bool +NextHopSelectionStrategy::onFailureMarkParentDown(TSHttpStatus response_code) { + return static_cast(response_code) >= 500 && static_cast(response_code) <= 599; +} + +bool +NextHopSelectionStrategy::goDirect() { - return this->resp_codes.contains(response_code) && current_retry_attempts < this->max_simple_retries && - current_retry_attempts < this->num_parents; + return this->go_direct; } bool -NextHopSelectionStrategy::onFailureMarkParentDown(HTTPStatus response_code) +NextHopSelectionStrategy::parentIsProxy() { - return static_cast(response_code) >= 500 && static_cast(response_code) <= 599; + return this->parent_is_proxy; } namespace YAML diff --git a/proxy/http/remap/NextHopSelectionStrategy.h b/proxy/http/remap/NextHopSelectionStrategy.h index 6076188f00c..39ece2f6dfb 100644 --- a/proxy/http/remap/NextHopSelectionStrategy.h +++ b/proxy/http/remap/NextHopSelectionStrategy.h @@ -37,6 +37,9 @@ constexpr const char *NH_DEBUG_TAG = "next_hop"; +constexpr const char *policy_strings[] = {"NH_UNDEFINED", "NH_FIRST_LIVE", "NH_RR_STRICT", + "NH_RR_IP", "NH_RR_LATCHED", "NH_CONSISTENT_HASH"}; + namespace YAML { class Node; @@ -44,11 +47,12 @@ class Node; enum NHPolicyType { NH_UNDEFINED = 0, - NH_FIRST_LIVE, // first available nexthop - NH_RR_STRICT, // strict round robin - NH_RR_IP, // round robin by client ip. - NH_RR_LATCHED, // latched to available next hop. - NH_CONSISTENT_HASH // consistent hashing strategy. + NH_FIRST_LIVE, // first available nexthop + NH_RR_STRICT, // strict round robin + NH_RR_IP, // round robin by client ip. + NH_RR_LATCHED, // latched to available next hop. + NH_CONSISTENT_HASH, // consistent hashing strategy. + NH_PLUGIN, // hashing strategy is a plugin }; enum NHSchemeType { NH_SCHEME_NONE = 0, NH_SCHEME_HTTP, NH_SCHEME_HTTPS }; @@ -196,39 +200,37 @@ struct HostRecord : ATSConsistentHashNode { } }; -class NextHopHealthStatus : public NHHealthStatus +class NextHopHealthStatus { public: void insert(std::vector> &hosts); - bool isNextHopAvailable(TSHttpTxn txn, const char *hostname, const int port, void *ih = nullptr) override; - void markNextHop(TSHttpTxn txn, const char *hostname, const int port, const NHCmd status, void *ih = nullptr, - const time_t now = 0) override; + void markNextHop(TSHttpTxn txn, const char *hostname, const int port, const NHCmd status, const time_t now = 0); NextHopHealthStatus(){}; private: std::unordered_map> host_map; }; -class NextHopSelectionStrategy +class NextHopSelectionStrategy : public TSNextHopSelectionStrategy { public: NextHopSelectionStrategy(); - NextHopSelectionStrategy(const std::string_view &name, const NHPolicyType &type); + NextHopSelectionStrategy(const std::string_view &name); virtual ~NextHopSelectionStrategy(){}; bool Init(const YAML::Node &n); - virtual void findNextHop(TSHttpTxn txnp, void *ih = nullptr, time_t now = 0) = 0; - void markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, void *ih = nullptr, - const time_t now = 0); - bool nextHopExists(TSHttpTxn txnp, void *ih = nullptr); - - virtual bool responseIsRetryable(unsigned int current_retry_attempts, HTTPStatus response_code); - virtual bool onFailureMarkParentDown(HTTPStatus response_code); + virtual void findNextHop(TSHttpTxn txnp, time_t now = 0) = 0; + virtual void markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now = 0); + virtual bool nextHopExists(TSHttpTxn txnp); + virtual bool responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code); + virtual bool onFailureMarkParentDown(TSHttpStatus response_code); + virtual bool goDirect(); + virtual bool parentIsProxy(); +// protected: std::string strategy_name; bool go_direct = true; bool parent_is_proxy = true; bool ignore_self_detect = false; - NHPolicyType policy_type = NH_UNDEFINED; NHSchemeType scheme = NH_SCHEME_NONE; NHRingMode ring_mode = NH_ALTERNATE_RING; ResponseCodes resp_codes; diff --git a/proxy/http/remap/NextHopStrategyFactory.cc b/proxy/http/remap/NextHopStrategyFactory.cc index 4de0b8aa521..202c3f0c50c 100644 --- a/proxy/http/remap/NextHopStrategyFactory.cc +++ b/proxy/http/remap/NextHopStrategyFactory.cc @@ -111,7 +111,7 @@ NextHopStrategyFactory::~NextHopStrategyFactory() void NextHopStrategyFactory::createStrategy(const std::string &name, const NHPolicyType policy_type, const YAML::Node &node) { - std::shared_ptr strat; + std::shared_ptr strat; std::shared_ptr strat_rr; std::shared_ptr strat_chash; @@ -134,7 +134,7 @@ NextHopStrategyFactory::createStrategy(const std::string &name, const NHPolicyTy } break; case NH_CONSISTENT_HASH: - strat_chash = std::make_shared(name, policy_type); + strat_chash = std::make_shared(name); if (strat_chash->Init(node)) { _strategies.emplace(std::make_pair(std::string(name), strat_chash)); } else { @@ -146,26 +146,34 @@ NextHopStrategyFactory::createStrategy(const std::string &name, const NHPolicyTy }; } -std::shared_ptr +std::shared_ptr NextHopStrategyFactory::strategyInstance(const char *name) { - std::shared_ptr ps_strategy; - if (!strategies_loaded) { NH_Error("no strategy configurations were defined, see defintions in '%s' file", fn.c_str()); return nullptr; - } else { - auto it = _strategies.find(name); - if (it == _strategies.end()) { - // NH_Error("no strategy found for name: %s", name); - return nullptr; - } else { - ps_strategy = it->second; - ps_strategy->distance = std::distance(_strategies.begin(), it); - } } + auto strategy = _strategies.find(name); + if (strategy == _strategies.end()) { + // NH_Error("no strategy found for name: %s", name); + return nullptr; + } + return strategy->second; +} - return ps_strategy; +/* + * Adds a new strategy to the factory. + * Designed for plugins which want to dynamically add strategies. + */ +bool +NextHopStrategyFactory::addStrategy(const std::string &name, std::shared_ptr strategy) { + if (_strategies.find(name) != _strategies.end()) { + NH_Error("failed to add strategy '%s' because a strategy with that name already exists", name.c_str()); + return false; + } + _strategies[name] = strategy; + strategies_loaded = true; + return true; } /* diff --git a/proxy/http/remap/NextHopStrategyFactory.h b/proxy/http/remap/NextHopStrategyFactory.h index ecb25a8943c..6865d529b8f 100644 --- a/proxy/http/remap/NextHopStrategyFactory.h +++ b/proxy/http/remap/NextHopStrategyFactory.h @@ -42,7 +42,8 @@ class NextHopStrategyFactory NextHopStrategyFactory() = delete; NextHopStrategyFactory(const char *file); ~NextHopStrategyFactory(); - std::shared_ptr strategyInstance(const char *name); + std::shared_ptr strategyInstance(const char *name); + bool addStrategy(const std::string& name, std::shared_ptr strategy); bool strategies_loaded; @@ -50,5 +51,6 @@ class NextHopStrategyFactory std::string fn; void loadConfigFile(const std::string &file, std::stringstream &doc, std::unordered_set &include_once); void createStrategy(const std::string &name, const NHPolicyType policy_type, const YAML::Node &node); - std::unordered_map> _strategies; + void createStrategyPlugin(const std::string &name, const YAML::Node &node); + std::unordered_map> _strategies; }; diff --git a/proxy/http/remap/PluginDso.cc b/proxy/http/remap/PluginDso.cc index 76e302f215a..95490a14447 100644 --- a/proxy/http/remap/PluginDso.cc +++ b/proxy/http/remap/PluginDso.cc @@ -284,6 +284,12 @@ PluginDso::instanceCount() return _instanceCount.refcount(); } +fs::path +PluginDso::configPath() const +{ + return _configPath; +} + bool PluginDso::isDynamicReloadEnabled() const { diff --git a/proxy/http/remap/PluginDso.h b/proxy/http/remap/PluginDso.h index 9e6df2d1a74..031e9fadb1e 100644 --- a/proxy/http/remap/PluginDso.h +++ b/proxy/http/remap/PluginDso.h @@ -94,6 +94,7 @@ class PluginDso : public PluginThreadContext void decInstanceCount(); int instanceCount(); bool isDynamicReloadEnabled() const; + virtual fs::path configPath() const; class LoadedPlugins : public RefCountObj { diff --git a/proxy/http/remap/PluginFactory.cc b/proxy/http/remap/PluginFactory.cc index 1837ddd7411..056134f6987 100644 --- a/proxy/http/remap/PluginFactory.cc +++ b/proxy/http/remap/PluginFactory.cc @@ -76,6 +76,16 @@ RemapPluginInst::doRemap(TSHttpTxn rh, TSRemapRequestInfo *rri) return _plugin.doRemap(_instance, rh, rri); } +std::shared_ptr +RemapPluginInst::getStrategy() +{ + return _plugin.initStrategy(this->_instance); +} + +std::string RemapPluginInst::name() const { + return _plugin.configPath().string(); +} + void RemapPluginInst::osResponse(TSHttpTxn rh, int os_response_type) { diff --git a/proxy/http/remap/PluginFactory.h b/proxy/http/remap/PluginFactory.h index eb2ca5c1366..111bf21f3a8 100644 --- a/proxy/http/remap/PluginFactory.h +++ b/proxy/http/remap/PluginFactory.h @@ -54,6 +54,10 @@ class RemapPluginInst TSRemapStatus doRemap(TSHttpTxn rh, TSRemapRequestInfo *rri); void osResponse(TSHttpTxn rh, int os_response_type); + /* gets the Strategy if the plugin has a TSRemapInitStrategy function. Returns a nullptr if not. */ + std::shared_ptr getStrategy(); + std::string name() const; + /* List used by the plugin factory */ using self_type = RemapPluginInst; ///< Self reference type. self_type *_next = nullptr; diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc index c9d06e9d4fb..1acbcfdae9f 100644 --- a/proxy/http/remap/RemapConfig.cc +++ b/proxy/http/remap/RemapConfig.cc @@ -1277,25 +1277,6 @@ remap_parse_config_bti(const char *path, BUILD_TABLE_INFO *bti) } } - // check for a 'strategy' and if wire it up if one exists. - if ((bti->remap_optflg & REMAP_OPTFLG_STRATEGY) != 0 && - (maptype == FORWARD_MAP || maptype == FORWARD_MAP_REFERER || maptype == FORWARD_MAP_WITH_RECV_PORT)) { - const char *strategy = strchr(bti->argv[0], static_cast('=')); - if (strategy == nullptr) { - errStr = "missing 'strategy' name argument, unable to add mapping rule"; - goto MAP_ERROR; - } else { - strategy++; - new_mapping->strategy = bti->rewrite->strategyFactory->strategyInstance(strategy); - if (!new_mapping->strategy) { - snprintf(errStrBuf, sizeof(errStrBuf), "no strategy named '%s' is defined in the config", strategy); - errStr = errStrBuf; - goto MAP_ERROR; - } - Debug("url_rewrite_regex", "mapped the 'strategy' named %s", strategy); - } - } - // Check "remap" plugin options and load .so object if ((bti->remap_optflg & REMAP_OPTFLG_PLUGIN) != 0 && (maptype == FORWARD_MAP || maptype == FORWARD_MAP_REFERER || maptype == FORWARD_MAP_WITH_RECV_PORT)) { @@ -1323,6 +1304,40 @@ remap_parse_config_bti(const char *path, BUILD_TABLE_INFO *bti) } } + for (std::size_t pi = 0, pend = new_mapping->plugin_instance_count(); pi != pend; ++pi) { + RemapPluginInst *pluginInst = new_mapping->get_plugin_instance(pi); + if (pluginInst == nullptr) { + continue; // TODO error? + } + std::shared_ptr strategy = pluginInst->getStrategy(); + const std::string pluginName = pluginInst->name(); + if (strategy != nullptr) { + Debug("remap_plugin", "Remap plugin got strategy '%s'", pluginName.c_str()); + bti->rewrite->strategyFactory->addStrategy(pluginName, strategy); // will log an error if the name already exists + } else { + Debug("remap_plugin", "Remap plugin has no strategy in '%s'", pluginName.c_str()); + } + } + + // check for a 'strategy' and if wire it up if one exists. + if ((bti->remap_optflg & REMAP_OPTFLG_STRATEGY) != 0 && + (maptype == FORWARD_MAP || maptype == FORWARD_MAP_REFERER || maptype == FORWARD_MAP_WITH_RECV_PORT)) { + const char *strategy = strchr(bti->argv[0], static_cast('=')); + if (strategy == nullptr) { + errStr = "missing 'strategy' name argument, unable to add mapping rule"; + goto MAP_ERROR; + } else { + strategy++; + new_mapping->strategy = bti->rewrite->strategyFactory->strategyInstance(strategy); + if (!new_mapping->strategy) { + snprintf(errStrBuf, sizeof(errStrBuf), "no strategy named '%s' is defined in the config", strategy); + errStr = errStrBuf; + goto MAP_ERROR; + } + Debug("url_rewrite_regex", "mapped the 'strategy' named %s", strategy); + } + } + // Now add the mapping to appropriate container if (!bti->rewrite->InsertMapping(maptype, new_mapping, reg_map, fromHost_lower, is_cur_mapping_regex)) { errStr = "unable to add mapping rule to lookup table"; diff --git a/proxy/http/remap/RemapPluginInfo.cc b/proxy/http/remap/RemapPluginInfo.cc index 736fd4d6727..91cfd990a6e 100644 --- a/proxy/http/remap/RemapPluginInfo.cc +++ b/proxy/http/remap/RemapPluginInfo.cc @@ -30,6 +30,7 @@ #include "tscore/ink_apidefs.h" #include "RemapPluginInfo.h" +#include "NextHopSelectionStrategy.h" #ifdef PLUGIN_DSO_TESTS #include "unit-tests/plugin_testing_common.h" #else @@ -93,6 +94,7 @@ RemapPluginInfo::load(std::string &error) delete_instance_cb = getFunctionSymbol(TSREMAP_FUNCNAME_DELETE_INSTANCE); do_remap_cb = getFunctionSymbol(TSREMAP_FUNCNAME_DO_REMAP); os_response_cb = getFunctionSymbol(TSREMAP_FUNCNAME_OS_RESPONSE); + init_strategy_cb = getFunctionSymbol(TSREMAP_FUNCNAME_INIT_STRATEGY); /* Validate if the callback TSREMAP functions are specified correctly in the plugin. */ bool valid = true; @@ -271,6 +273,31 @@ RemapPluginInfo::indicatePostReload(TSRemapReloadStatus reloadStatus) resetPluginContext(); } +/* Initialize strategy (optional). */ +std::shared_ptr RemapPluginInfo::initStrategy(void *ih) +{ + if (!init_strategy_cb) { + PluginDebug(_tag, "plugin '%s' has no init_strategy_cb, returning nullptr", _configPath.c_str()); + return std::shared_ptr(); + } + char tmpbuf[2048]; + ink_zero(tmpbuf); + TSNextHopSelectionStrategy *strategy_raw = nullptr; + if (init_strategy_cb(strategy_raw, ih, tmpbuf, sizeof(tmpbuf) - 1) != TS_SUCCESS) { + PluginDebug(_tag, "plugin '%s' has init_strategy_cb but not success, returning error", _configPath.c_str()); + std::string error; + error.assign("failed to initialize plugin ") + .append(_configPath.string()) + .append(": ") + .append(tmpbuf[0] ? tmpbuf : "Unknown plugin error"); + PluginError("plugin '%s' initializing strategy returned error: %s", _configPath.c_str(), error.c_str()); + return std::shared_ptr(); + } + PluginDebug(_tag, "plugin '%s' has init_strategy_cb, returning strategy", _configPath.c_str()); + return std::shared_ptr(strategy_raw); +} + + inline void RemapPluginInfo::setPluginContext() { diff --git a/proxy/http/remap/RemapPluginInfo.h b/proxy/http/remap/RemapPluginInfo.h index 16156dc749c..d7faa95ccf0 100644 --- a/proxy/http/remap/RemapPluginInfo.h +++ b/proxy/http/remap/RemapPluginInfo.h @@ -26,6 +26,7 @@ #include #include +#include #include "tscore/ink_platform.h" #include "ts/apidefs.h" @@ -33,6 +34,7 @@ #include "PluginDso.h" class url_mapping; +class TSNextHopSelectionStrategy; extern thread_local PluginThreadContext *pluginThreadContext; @@ -44,6 +46,7 @@ static constexpr const char *const TSREMAP_FUNCNAME_NEW_INSTANCE = "TSRema static constexpr const char *const TSREMAP_FUNCNAME_DELETE_INSTANCE = "TSRemapDeleteInstance"; static constexpr const char *const TSREMAP_FUNCNAME_DO_REMAP = "TSRemapDoRemap"; static constexpr const char *const TSREMAP_FUNCNAME_OS_RESPONSE = "TSRemapOSResponse"; +static constexpr const char *const TSREMAP_FUNCNAME_INIT_STRATEGY = "TSRemapInitStrategy"; /** * Holds information for a remap plugin, remap specific callback entry points for plugin init/done and instance init/done, do_remap, @@ -68,6 +71,8 @@ class RemapPluginInfo : public PluginDso using Do_Remap_F = TSRemapStatus(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri); /// I have no idea what this is for. using OS_Response_F = void(void *ih, TSHttpTxn rh, int os_response_type); + /// Initialization function to create a new strategy, called on strategies load. + using Init_Strategy_F = TSReturnCode(TSNextHopSelectionStrategy *&strategy, void *ih, char *errbuf, int errbuf_size); void *dl_handle = nullptr; /* "handle" for the dynamic library */ Init_F *init_cb = nullptr; @@ -78,6 +83,7 @@ class RemapPluginInfo : public PluginDso Delete_Instance_F *delete_instance_cb = nullptr; Do_Remap_F *do_remap_cb = nullptr; OS_Response_F *os_response_cb = nullptr; + Init_Strategy_F *init_strategy_cb = nullptr; RemapPluginInfo(const fs::path &configPath, const fs::path &effectivePath, const fs::path &runtimePath); ~RemapPluginInfo(); @@ -101,6 +107,8 @@ class RemapPluginInfo : public PluginDso void indicatePreReload() override; void indicatePostReload(TSRemapReloadStatus reloadStatus) override; + /* Used by strategies on initialization, to add plugin-defined strategies for use by remaps */ + std::shared_ptr initStrategy(void *ih); protected: /* Utility to be used only with unit testing */ std::string missingRequiredSymbolError(const std::string &pluginName, const char *required, const char *requiring = nullptr); diff --git a/proxy/http/remap/UrlMapping.h b/proxy/http/remap/UrlMapping.h index a0482c14c2f..1f0aa26ab6a 100644 --- a/proxy/http/remap/UrlMapping.h +++ b/proxy/http/remap/UrlMapping.h @@ -34,7 +34,7 @@ #include "tscore/Regex.h" #include "tscore/List.h" -class NextHopSelectionStrategy; +class TSNextHopSelectionStrategy; /** * Used to store http referer strings (and/or regexp) @@ -111,7 +111,7 @@ class url_mapping bool ip_allow_check_enabled_p = false; acl_filter_rule *filter = nullptr; // acl filtering (list of rules) LINK(url_mapping, link); // For use with the main Queue linked list holding all the mapping - std::shared_ptr strategy = nullptr; + std::shared_ptr strategy = nullptr; int getRank() const diff --git a/proxy/http/remap/unit-tests/nexthop_test_stubs.cc b/proxy/http/remap/unit-tests/nexthop_test_stubs.cc index 6eb2d7e7046..f83217c24cc 100644 --- a/proxy/http/remap/unit-tests/nexthop_test_stubs.cc +++ b/proxy/http/remap/unit-tests/nexthop_test_stubs.cc @@ -203,14 +203,14 @@ HostStatus::getHostStatus(const char *name) if (this->hosts_statuses[name] == nullptr) { // for unit tests only, always return a record with HOST_STATUS_UP, if it wasn't set with setHostStatus static HostStatRec rec; - rec.status = HostStatus_t::HOST_STATUS_UP; + rec.status = TSHostStatus::TS_HOST_STATUS_UP; return &rec; } return this->hosts_statuses[name]; } void -HostStatus::setHostStatus(char const *host, HostStatus_t status, unsigned int down_time, unsigned int reason) +HostStatus::setHostStatus(char const *host, TSHostStatus status, unsigned int down_time, unsigned int reason) { if (this->hosts_statuses[host] == nullptr) { this->hosts_statuses[host] = new (HostStatRec); diff --git a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc index 47660d6cbee..aec42253155 100644 --- a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc +++ b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc @@ -51,9 +51,11 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", GIVEN("Loading the consistent-hash-tests.yaml config for 'consistent_hash' tests.") { // load the configuration strtegies. - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); strategy = nhf.strategyInstance("consistent-hash-1"); + NextHopConsistentHash *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); WHEN("the config is loaded.") { @@ -61,7 +63,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->groups == 3); + REQUIRE(ptr->groups == 3); } } @@ -94,74 +96,74 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); // mark down p1.foo.com. markNextHop looks at the 'result' // and uses the host index there mark down the host selected // from a - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // second request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "p2.foo.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); // mark down p2.foo.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // third request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "s2.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "s2.bar.com") == 0); // mark down s2.bar.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fourth request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10004, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "s1.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); // mark down s1.bar.com. - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fifth request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10005, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "q1.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "q1.bar.com") == 0); // mark down q1.bar.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // sixth request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10006, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "q2.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "q2.bar.com") == 0); // mark down q2.bar.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // seventh request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10007, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_DIRECT); - CHECK(result->hostname == nullptr); + CHECK(result->ts_result.result == TSParentResultType::PARENT_DIRECT); + CHECK(result->ts_result.hostname == nullptr); // sleep and test that q2 is becomes retryable; time_t now = time(nullptr) + 5; @@ -169,9 +171,9 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", // eighth request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10008, &sm, nullptr, "rabbit.net", nullptr); - strategy->findNextHop(txnp, nullptr, now); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "q2.bar.com") == 0); + strategy->findNextHop(txnp, now); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "q2.bar.com") == 0); // free up request resources. br_destroy(sm); @@ -190,9 +192,11 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co GIVEN("Loading the consistent-hash-tests.yaml config for 'consistent_hash' tests.") { - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); strategy = nhf.strategyInstance("consistent-hash-1"); + NextHopConsistentHash *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); WHEN("the config is loaded.") { @@ -200,7 +204,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->groups == 3); + REQUIRE(ptr->groups == 3); } } @@ -225,55 +229,55 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co build_request(20001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); // mark down p1.foo.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // second request build_request(20002, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "p2.foo.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); // mark down p2.foo.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // third request result->reset(); build_request(20003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "s2.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "s2.bar.com") == 0); // mark down s2.bar.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fourth request result->reset(); build_request(20004, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "s1.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); // mark down s1.bar.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fifth request result->reset(); build_request(20005, &sm, nullptr, "rabbit.net/asset1", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "q1.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "q1.bar.com") == 0); // sixth request - wait and p1 should now become available time_t now = time(nullptr) + 5; result->reset(); build_request(20006, &sm, nullptr, "rabbit.net", nullptr); - strategy->findNextHop(txnp, nullptr, now); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + strategy->findNextHop(txnp, now); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); } // free up request resources. br_destroy(sm); @@ -292,12 +296,14 @@ SCENARIO("Testing NextHop ignore_self_detect false", "[NextHopConsistentHash]") GIVEN("Loading the consistent-hash-tests.yaml config for 'consistent_hash' tests.") { // load the configuration strtegies. - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); strategy = nhf.strategyInstance("ignore-self-detect-false"); + NextHopConsistentHash *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); HostStatus &hs = HostStatus::instance(); - hs.setHostStatus("localhost", HostStatus_t::HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); + hs.setHostStatus("localhost", TSHostStatus::TS_HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); WHEN("the config is loaded.") { @@ -305,7 +311,7 @@ SCENARIO("Testing NextHop ignore_self_detect false", "[NextHopConsistentHash]") { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->groups == 2); + REQUIRE(ptr->groups == 2); } } @@ -323,8 +329,8 @@ SCENARIO("Testing NextHop ignore_self_detect false", "[NextHopConsistentHash]") build_request(10001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_DIRECT); - CHECK(result->hostname == nullptr); + CHECK(result->ts_result.result == TSParentResultType::PARENT_DIRECT); + CHECK(result->ts_result.hostname == nullptr); br_destroy(sm); } } @@ -342,12 +348,14 @@ SCENARIO("Testing NextHop ignore_self_detect true", "[NextHopConsistentHash]") GIVEN("Loading the consistent-hash-tests.yaml config for 'consistent_hash' tests.") { // load the configuration strtegies. - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); strategy = nhf.strategyInstance("ignore-self-detect-true"); + NextHopConsistentHash *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); HostStatus &hs = HostStatus::instance(); - hs.setHostStatus("localhost", HostStatus_t::HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); + hs.setHostStatus("localhost", TSHostStatus::TS_HOST_STATUS_DOWN, 0, Reason::SELF_DETECT); WHEN("the config is loaded.") { @@ -355,7 +363,7 @@ SCENARIO("Testing NextHop ignore_self_detect true", "[NextHopConsistentHash]") { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->groups == 2); + REQUIRE(ptr->groups == 2); } } @@ -372,9 +380,9 @@ SCENARIO("Testing NextHop ignore_self_detect true", "[NextHopConsistentHash]") build_request(10001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "localhost") == 0); - CHECK(result->port == 8000); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); + CHECK(result->ts_result.port == 8000); br_destroy(sm); } } @@ -392,9 +400,11 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne GIVEN("Loading the consistent-hash-tests.yaml config for 'consistent_hash' tests.") { // load the configuration strtegies. - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); strategy = nhf.strategyInstance("same-host-different-port"); + NextHopConsistentHash *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); WHEN("the config is loaded.") { @@ -402,7 +412,7 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->groups == 3); + REQUIRE(ptr->groups == 3); } } @@ -422,27 +432,27 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "localhost") == 0); - CHECK(result->port == 8000); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); + CHECK(result->ts_result.port == 8000); - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "localhost") == 0); - CHECK(result->port == 8002); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); + CHECK(result->ts_result.port == 8002); - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); build_request(10003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "localhost") == 0); - CHECK(result->port == 8004); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); + CHECK(result->ts_result.port == 8004); br_destroy(sm); } } @@ -460,9 +470,11 @@ SCENARIO("Testing NextHopConsistentHash hash_string override", "[NextHopConsiste GIVEN("Loading the consistent-hash-tests.yaml config for 'consistent_hash' tests.") { // load the configuration strtegies. - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); strategy = nhf.strategyInstance("hash-string-override"); + NextHopConsistentHash *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); WHEN("the config is loaded.") { @@ -470,7 +482,7 @@ SCENARIO("Testing NextHopConsistentHash hash_string override", "[NextHopConsiste { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->groups == 2); + REQUIRE(ptr->groups == 2); } } @@ -492,17 +504,17 @@ SCENARIO("Testing NextHopConsistentHash hash_string override", "[NextHopConsiste // We happen to know that 'foo.test' will be first if the hostname is the hash // and foo.test will be first for the hash 'first' and the bar.test hash 'second'. // So, if the hash_string override isn't getting applied, this will fail. - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "bar.test") == 0); - CHECK(result->port == 80); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "bar.test") == 0); + CHECK(result->ts_result.port == 80); - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "foo.test") == 0); - CHECK(result->port == 80); + CHECK(strcmp(result->ts_result.hostname, "foo.test") == 0); + CHECK(result->ts_result.port == 80); br_destroy(sm); } } @@ -519,9 +531,11 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy GIVEN("Loading the consistent-hash-tests.yaml config for 'consistent_hash' tests.") { - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); strategy = nhf.strategyInstance("consistent-hash-2"); + NextHopConsistentHash *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); WHEN("the config is loaded.") { @@ -529,7 +543,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->groups == 3); + REQUIRE(ptr->groups == 3); } } @@ -550,70 +564,70 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy build_request(30001, &sm, nullptr, "bunny.net/asset1", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "c2.foo.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "c2.foo.com") == 0); // simulated failure, mark c2 down and retry request - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // second request build_request(30002, &sm, nullptr, "bunny.net.net/asset1", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "c3.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "c3.bar.com") == 0); // mark down c3.bar.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // third request build_request(30003, &sm, nullptr, "bunny.net/asset2", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "c6.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "c6.bar.com") == 0); // just mark it down and retry request - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fourth request build_request(30004, &sm, nullptr, "bunny.net/asset2", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "c1.foo.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "c1.foo.com") == 0); // mark it down - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fifth request - new request build_request(30005, &sm, nullptr, "bunny.net/asset3", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "c4.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "c4.bar.com") == 0); // mark it down and retry - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // sixth request result->reset(); build_request(30006, &sm, nullptr, "bunny.net/asset3", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "c5.bar.com") == 0); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "c5.bar.com") == 0); // mark it down - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // seventh request - new request with all hosts down and go_direct is false. result->reset(); build_request(30007, &sm, nullptr, "bunny.net/asset4", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_FAIL); - CHECK(result->hostname == nullptr); + CHECK(result->ts_result.result == TSParentResultType::PARENT_FAIL); + CHECK(result->ts_result.hostname == nullptr); // eighth request - retry after waiting for the retry window to expire. time_t now = time(nullptr) + 5; result->reset(); build_request(30008, &sm, nullptr, "bunny.net/asset4", nullptr); - strategy->findNextHop(txnp, nullptr, now); - CHECK(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "c2.foo.com") == 0); + strategy->findNextHop(txnp, now); + CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "c2.foo.com") == 0); } // free up request resources. br_destroy(sm); diff --git a/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc b/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc index 506d6470391..ba5464fea56 100644 --- a/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc +++ b/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc @@ -47,17 +47,20 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-strict'", "[NextHopR GIVEN("Loading the round-robin-tests.yaml config for round robin 'rr-strict' tests.") { - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/round-robin-tests.yaml"); strategy = nhf.strategyInstance("rr-strict-exhaust-ring"); + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + WHEN("the config is loaded.") { THEN("the rr-strict strategy is ready for use.") { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->policy_type == NH_RR_STRICT); + REQUIRE(ptr->policy_type == NH_RR_STRICT); } } @@ -75,67 +78,67 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-strict'", "[NextHopR // first request. build_request(10001, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); // second request. build_request(10002, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); // third request. build_request(10003, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); // did not reset result, kept it as last parent selected was p1.fo.com, mark it down and we should only select p2.foo.com - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fourth request, p1 is down should select p2. build_request(10004, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); // fifth request, p1 is down should still select p2. build_request(10005, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); // mark down p2. - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // fifth request, p1 and p2 are both down, should get s1.bar.com from failover ring. build_request(10006, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "s1.bar.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); // sixth request, p1 and p2 are still down, should get s1.bar.com from failover ring. build_request(10007, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "s1.bar.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); // mark down s1. - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // seventh request, p1, p2, s1 are down, should get s2.bar.com from failover ring. build_request(10008, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "s2.bar.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "s2.bar.com") == 0); // mark down s2. - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // eighth request, p1, p2, s1, s2 are down, should get PARENT_DIRECT as go_direct is true build_request(10009, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == ParentResultType::PARENT_DIRECT); + CHECK(result->ts_result.result == TSParentResultType::PARENT_DIRECT); // check that nextHopExists() returns false when all parents are down. CHECK(strategy->nextHopExists(txnp) == false); @@ -146,16 +149,16 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-strict'", "[NextHopR // ninth request, p1 and p2 are still down, should get p2.foo.com as it will be retried build_request(10010, &sm, nullptr, "rabbit.net", nullptr); result->reset(); - strategy->findNextHop(txnp, nullptr, now); - REQUIRE(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "p2.foo.com") == 0); + strategy->findNextHop(txnp, now); + REQUIRE(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); // tenth request, p1 should now be retried. build_request(10011, &sm, nullptr, "rabbit.net", nullptr); result->reset(); - strategy->findNextHop(txnp, nullptr, now); - REQUIRE(result->result == ParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + strategy->findNextHop(txnp, now); + REQUIRE(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); } br_destroy(sm); } @@ -172,17 +175,20 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'first-live'", "[NextHop GIVEN("Loading the round-robin-tests.yaml config for round robin 'first-live' tests.") { - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/round-robin-tests.yaml"); strategy = nhf.strategyInstance("first-live"); + REQUIRE(strategy != nullptr); + + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); WHEN("the config is loaded.") { THEN("the 'first-live' strategy is available.") { REQUIRE(nhf.strategies_loaded == true); - REQUIRE(strategy != nullptr); - REQUIRE(strategy->policy_type == NH_FIRST_LIVE); + REQUIRE(ptr->policy_type == NH_FIRST_LIVE); } } @@ -200,22 +206,22 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'first-live'", "[NextHop // first request. build_request(10012, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); // second request. build_request(10013, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); // mark down p1. - strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); // third request. build_request(10014, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); // change the request time to trigger a retry. time_t now = (time(nullptr) + 5); @@ -223,8 +229,8 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'first-live'", "[NextHop // fourth request, p1 should be marked for retry build_request(10015, &sm, nullptr, "rabbit.net", nullptr); result->reset(); - strategy->findNextHop(txnp, nullptr, now); - CHECK(strcmp(result->hostname, "p1.foo.com") == 0); + strategy->findNextHop(txnp, now); + CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); } br_destroy(sm); } @@ -241,9 +247,13 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound GIVEN("Loading the round-robin-tests.yaml config for round robin 'rr-ip' tests.") { - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/round-robin-tests.yaml"); strategy = nhf.strategyInstance("rr-ip"); + REQUIRE(strategy != nullptr); + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + sockaddr_in sa1, sa2; sa1.sin_port = 10000; sa1.sin_family = AF_INET; @@ -261,7 +271,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->policy_type == NH_RR_IP); + REQUIRE(ptr->policy_type == NH_RR_IP); } } @@ -280,7 +290,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound // memcpy(&rdata.client_ip, &sa1, sizeof(sa1)); build_request(10016, &sm, &sa1, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); // call and test parentExists(), this call should not affect // findNextHop round robin strict results. @@ -291,7 +301,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound build_request(10017, &sm, &sa2, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); // call and test parentExists(), this call should not affect // findNextHop() round robin strict results @@ -301,7 +311,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound build_request(10018, &sm, &sa2, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); // call and test parentExists(), this call should not affect // findNextHop() round robin strict results. @@ -311,7 +321,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound // being selected. build_request(10019, &sm, &sa2, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); } } br_destroy(sm); @@ -328,9 +338,12 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'latched'", "[NextHopRou GIVEN("Loading the round-robin-tests.yaml config for round robin 'latched' tests.") { - std::shared_ptr strategy; + std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/round-robin-tests.yaml"); strategy = nhf.strategyInstance("latched"); + REQUIRE(strategy != nullptr); + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); WHEN("the config is loaded.") { @@ -338,7 +351,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'latched'", "[NextHopRou { REQUIRE(nhf.strategies_loaded == true); REQUIRE(strategy != nullptr); - REQUIRE(strategy->policy_type == NH_RR_LATCHED); + REQUIRE(ptr->policy_type == NH_RR_LATCHED); } } @@ -356,29 +369,29 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'latched'", "[NextHopRou // first request should select p3 build_request(10020, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); // second request should select p3 build_request(10021, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); // third request, use previous result to simulate a failure, we should now select p4. build_request(10022, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); // fourth request we should be latched on p4 build_request(10023, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); // fifth request, use previous result to simulate a failure, we should now select p3. build_request(10024, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); } br_destroy(sm); } diff --git a/proxy/http/remap/unit-tests/test_NextHopStrategyFactory.cc b/proxy/http/remap/unit-tests/test_NextHopStrategyFactory.cc index de9a71f8aa8..e0fdb3604a9 100644 --- a/proxy/http/remap/unit-tests/test_NextHopStrategyFactory.cc +++ b/proxy/http/remap/unit-tests/test_NextHopStrategyFactory.cc @@ -63,11 +63,11 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("Expect that these results for 'strategy-1'") { - std::shared_ptr strategy = nhf.strategyInstance("strategy-1"); + std::shared_ptr strategy = nhf.strategyInstance("strategy-1"); REQUIRE(strategy != nullptr); - CHECK(strategy->parent_is_proxy == true); - CHECK(strategy->max_simple_retries == 1); - CHECK(strategy->policy_type == NH_CONSISTENT_HASH); + CHECK(strategy->parentIsProxy() == true); + CHECK(strategy->responseIsRetryable(0, static_cast(503))); + CHECK(!strategy->responseIsRetryable(1, static_cast(503))); // down cast here using the stored pointer so that I can verify the hash_key was set // properly. @@ -75,16 +75,16 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") REQUIRE(ptr != nullptr); CHECK(ptr->hash_key == NH_CACHE_HASH_KEY); - CHECK(strategy->go_direct == false); - CHECK(strategy->scheme == NH_SCHEME_HTTP); - CHECK(strategy->ring_mode == NH_EXHAUST_RING); - CHECK(strategy->groups == 2); - std::shared_ptr h = strategy->host_groups[0][0]; + CHECK(strategy->goDirect() == false); + // CHECK(ptr->scheme == NH_SCHEME_HTTP); // TODO fix + CHECK(ptr->ring_mode == NH_EXHAUST_RING); + CHECK(ptr->groups == 2); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -138,9 +138,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } @@ -148,19 +148,21 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("Expect that these results for 'strategy-2'") { - std::shared_ptr strategy = nhf.strategyInstance("strategy-2"); + std::shared_ptr strategy = nhf.strategyInstance("strategy-2"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_RR_STRICT); - CHECK(strategy->go_direct == true); - CHECK(strategy->scheme == NH_SCHEME_HTTP); - CHECK(strategy->ring_mode == NH_EXHAUST_RING); - CHECK(strategy->groups == 2); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->policy_type == NH_RR_STRICT); + CHECK(ptr->go_direct == true); + CHECK(ptr->scheme == NH_SCHEME_HTTP); + CHECK(ptr->ring_mode == NH_EXHAUST_RING); + CHECK(ptr->groups == 2); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -210,9 +212,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } } @@ -235,19 +237,21 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("Expect that these results for 'strategy-3'") { - std::shared_ptr strategy = nhf.strategyInstance("strategy-3"); + std::shared_ptr strategy = nhf.strategyInstance("strategy-3"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_RR_IP); - CHECK(strategy->go_direct == true); - CHECK(strategy->scheme == NH_SCHEME_HTTPS); - CHECK(strategy->ring_mode == NH_EXHAUST_RING); - CHECK(strategy->groups == 2); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->policy_type == NH_RR_IP); + CHECK(ptr->go_direct == true); + CHECK(ptr->scheme == NH_SCHEME_HTTPS); + CHECK(ptr->ring_mode == NH_EXHAUST_RING); + CHECK(ptr->groups == 2); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -300,9 +304,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } @@ -310,19 +314,21 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("Expect that these results for 'strategy-4'") { - std::shared_ptr strategy = nhf.strategyInstance("strategy-4"); + std::shared_ptr strategy = nhf.strategyInstance("strategy-4"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_RR_LATCHED); - CHECK(strategy->go_direct == true); - CHECK(strategy->scheme == NH_SCHEME_HTTP); - CHECK(strategy->ring_mode == NH_ALTERNATE_RING); - CHECK(strategy->groups == 1); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->policy_type == NH_RR_LATCHED); + CHECK(ptr->go_direct == true); + CHECK(ptr->scheme == NH_SCHEME_HTTP); + CHECK(ptr->ring_mode == NH_ALTERNATE_RING); + CHECK(ptr->groups == 1); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -351,9 +357,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } } @@ -376,26 +382,28 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("expect the following details.") { - std::shared_ptr strategy = nhf.strategyInstance("mid-tier-north"); + std::shared_ptr strategy = nhf.strategyInstance("mid-tier-north"); REQUIRE(strategy != nullptr); - CHECK(strategy->parent_is_proxy == false); - CHECK(strategy->max_simple_retries == 2); - CHECK(strategy->policy_type == NH_RR_IP); - CHECK(strategy->go_direct == true); - CHECK(strategy->scheme == NH_SCHEME_HTTP); - CHECK(strategy->ring_mode == NH_EXHAUST_RING); - CHECK(strategy->groups == 2); - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(502)); - CHECK(!strategy->resp_codes.contains(604)); - CHECK(strategy->health_checks.active == true); - CHECK(strategy->health_checks.passive == true); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->parent_is_proxy == false); + CHECK(ptr->max_simple_retries == 2); + CHECK(ptr->policy_type == NH_RR_IP); + CHECK(ptr->go_direct == true); + CHECK(ptr->scheme == NH_SCHEME_HTTP); + CHECK(ptr->ring_mode == NH_EXHAUST_RING); + CHECK(ptr->groups == 2); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(502)); + CHECK(!ptr->resp_codes.contains(604)); + CHECK(ptr->health_checks.active == true); + CHECK(ptr->health_checks.passive == true); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -445,9 +453,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } @@ -455,27 +463,29 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("expect the following results.") { - std::shared_ptr strategy = nhf.strategyInstance("mid-tier-south"); + std::shared_ptr strategy = nhf.strategyInstance("mid-tier-south"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_RR_LATCHED); - CHECK(strategy->parent_is_proxy == false); - CHECK(strategy->ignore_self_detect == false); - CHECK(strategy->max_simple_retries == 2); - CHECK(strategy->go_direct == false); - CHECK(strategy->scheme == NH_SCHEME_HTTP); - CHECK(strategy->ring_mode == NH_ALTERNATE_RING); - CHECK(strategy->groups == 2); - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(502)); - CHECK(!strategy->resp_codes.contains(604)); - CHECK(strategy->health_checks.active == true); - CHECK(strategy->health_checks.passive == true); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->policy_type == NH_RR_LATCHED); + CHECK(ptr->parent_is_proxy == false); + CHECK(ptr->ignore_self_detect == false); + CHECK(ptr->max_simple_retries == 2); + CHECK(ptr->go_direct == false); + CHECK(ptr->scheme == NH_SCHEME_HTTP); + CHECK(ptr->ring_mode == NH_ALTERNATE_RING); + CHECK(ptr->groups == 2); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(502)); + CHECK(!ptr->resp_codes.contains(604)); + CHECK(ptr->health_checks.active == true); + CHECK(ptr->health_checks.passive == true); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -525,9 +535,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } @@ -535,27 +545,29 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("expect the following results.") { - std::shared_ptr strategy = nhf.strategyInstance("mid-tier-east"); + std::shared_ptr strategy = nhf.strategyInstance("mid-tier-east"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_FIRST_LIVE); - CHECK(strategy->parent_is_proxy == false); - CHECK(strategy->ignore_self_detect == true); - CHECK(strategy->max_simple_retries == 2); - CHECK(strategy->go_direct == false); - CHECK(strategy->scheme == NH_SCHEME_HTTPS); - CHECK(strategy->ring_mode == NH_ALTERNATE_RING); - CHECK(strategy->groups == 2); - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(502)); - CHECK(!strategy->resp_codes.contains(604)); - CHECK(strategy->health_checks.active == false); - CHECK(strategy->health_checks.passive == true); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->policy_type == NH_FIRST_LIVE); + CHECK(ptr->parent_is_proxy == false); + CHECK(ptr->ignore_self_detect == true); + CHECK(ptr->max_simple_retries == 2); + CHECK(ptr->go_direct == false); + CHECK(ptr->scheme == NH_SCHEME_HTTPS); + CHECK(ptr->ring_mode == NH_ALTERNATE_RING); + CHECK(ptr->groups == 2); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(502)); + CHECK(!ptr->resp_codes.contains(604)); + CHECK(ptr->health_checks.active == false); + CHECK(ptr->health_checks.passive == true); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -605,9 +617,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } @@ -615,26 +627,28 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("expect the following results.") { - std::shared_ptr strategy = nhf.strategyInstance("mid-tier-west"); + std::shared_ptr strategy = nhf.strategyInstance("mid-tier-west"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_RR_STRICT); - CHECK(strategy->go_direct == true); - CHECK(strategy->scheme == NH_SCHEME_HTTPS); - CHECK(strategy->parent_is_proxy == false); - CHECK(strategy->max_simple_retries == 2); - CHECK(strategy->ring_mode == NH_EXHAUST_RING); - CHECK(strategy->groups == 2); - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(502)); - CHECK(!strategy->resp_codes.contains(604)); - CHECK(strategy->health_checks.active == true); - CHECK(strategy->health_checks.passive == false); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->policy_type == NH_RR_STRICT); + CHECK(ptr->go_direct == true); + CHECK(ptr->scheme == NH_SCHEME_HTTPS); + CHECK(ptr->parent_is_proxy == false); + CHECK(ptr->max_simple_retries == 2); + CHECK(ptr->ring_mode == NH_EXHAUST_RING); + CHECK(ptr->groups == 2); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(502)); + CHECK(!ptr->resp_codes.contains(604)); + CHECK(ptr->health_checks.active == true); + CHECK(ptr->health_checks.passive == false); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -684,9 +698,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } @@ -694,33 +708,28 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") { THEN("expect the following results.") { - std::shared_ptr strategy = nhf.strategyInstance("mid-tier-midwest"); + std::shared_ptr strategy = nhf.strategyInstance("mid-tier-midwest"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_CONSISTENT_HASH); - CHECK(strategy->parent_is_proxy == false); - CHECK(strategy->max_simple_retries == 2); - - // I need to down cast here using the stored pointer so that I can verify that - // the hash_key was set properly. NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); + CHECK(ptr->parent_is_proxy == false); + CHECK(ptr->max_simple_retries == 2); CHECK(ptr->hash_key == NH_CACHE_HASH_KEY); - - CHECK(strategy->go_direct == true); - CHECK(strategy->scheme == NH_SCHEME_HTTPS); - CHECK(strategy->ring_mode == NH_EXHAUST_RING); - CHECK(strategy->groups == 2); - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(502)); - CHECK(!strategy->resp_codes.contains(604)); - CHECK(strategy->health_checks.active == true); - CHECK(strategy->health_checks.passive == false); - std::shared_ptr h = strategy->host_groups[0][0]; + CHECK(ptr->go_direct == true); + CHECK(ptr->scheme == NH_SCHEME_HTTPS); + CHECK(ptr->ring_mode == NH_EXHAUST_RING); + CHECK(ptr->groups == 2); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(502)); + CHECK(!ptr->resp_codes.contains(604)); + CHECK(ptr->health_checks.active == true); + CHECK(ptr->health_checks.passive == false); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -770,9 +779,9 @@ SCENARIO("factory tests loading yaml configs", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } } @@ -798,26 +807,28 @@ SCENARIO("factory tests loading yaml configs from a directory", "[loadConfig]") { THEN("expect the following results.") { - std::shared_ptr strategy = nhf.strategyInstance("mid-tier-north"); + std::shared_ptr strategy = nhf.strategyInstance("mid-tier-north"); REQUIRE(strategy != nullptr); - CHECK(strategy->parent_is_proxy == false); - CHECK(strategy->max_simple_retries == 2); - CHECK(strategy->policy_type == NH_RR_IP); - CHECK(strategy->go_direct == true); - CHECK(strategy->scheme == NH_SCHEME_HTTP); - CHECK(strategy->ring_mode == NH_EXHAUST_RING); - CHECK(strategy->groups == 2); - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(502)); - CHECK(!strategy->resp_codes.contains(604)); - CHECK(strategy->health_checks.active == true); - CHECK(strategy->health_checks.passive == true); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->parent_is_proxy == false); + CHECK(ptr->max_simple_retries == 2); + CHECK(ptr->policy_type == NH_RR_IP); + CHECK(ptr->go_direct == true); + CHECK(ptr->scheme == NH_SCHEME_HTTP); + CHECK(ptr->ring_mode == NH_EXHAUST_RING); + CHECK(ptr->groups == 2); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(502)); + CHECK(!ptr->resp_codes.contains(604)); + CHECK(ptr->health_checks.active == true); + CHECK(ptr->health_checks.passive == true); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -867,9 +878,9 @@ SCENARIO("factory tests loading yaml configs from a directory", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } @@ -877,27 +888,29 @@ SCENARIO("factory tests loading yaml configs from a directory", "[loadConfig]") { THEN("expect the following results.") { - std::shared_ptr strategy = nhf.strategyInstance("mid-tier-south"); + std::shared_ptr strategy = nhf.strategyInstance("mid-tier-south"); REQUIRE(strategy != nullptr); - CHECK(strategy->policy_type == NH_RR_LATCHED); - CHECK(strategy->parent_is_proxy == false); - CHECK(strategy->ignore_self_detect == false); - CHECK(strategy->max_simple_retries == 2); - CHECK(strategy->go_direct == false); - CHECK(strategy->scheme == NH_SCHEME_HTTP); - CHECK(strategy->ring_mode == NH_ALTERNATE_RING); - CHECK(strategy->groups == 2); - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(502)); - CHECK(!strategy->resp_codes.contains(604)); - CHECK(strategy->health_checks.active == true); - CHECK(strategy->health_checks.passive == true); - std::shared_ptr h = strategy->host_groups[0][0]; + NextHopRoundRobin *ptr = static_cast(strategy.get()); + REQUIRE(ptr != nullptr); + CHECK(ptr->policy_type == NH_RR_LATCHED); + CHECK(ptr->parent_is_proxy == false); + CHECK(ptr->ignore_self_detect == false); + CHECK(ptr->max_simple_retries == 2); + CHECK(ptr->go_direct == false); + CHECK(ptr->scheme == NH_SCHEME_HTTP); + CHECK(ptr->ring_mode == NH_ALTERNATE_RING); + CHECK(ptr->groups == 2); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(502)); + CHECK(!ptr->resp_codes.contains(604)); + CHECK(ptr->health_checks.active == true); + CHECK(ptr->health_checks.passive == true); + std::shared_ptr h = ptr->host_groups[0][0]; CHECK(h != nullptr); - for (unsigned int i = 0; i < strategy->groups; i++) { - CHECK(strategy->host_groups[i].size() == 2); - for (unsigned int j = 0; j < strategy->host_groups[i].size(); j++) { - h = strategy->host_groups[i][j]; + for (unsigned int i = 0; i < ptr->groups; i++) { + CHECK(ptr->host_groups[i].size() == 2); + for (unsigned int j = 0; j < ptr->host_groups[i].size(); j++) { + h = ptr->host_groups[i][j]; switch (i) { case 0: switch (j) { @@ -947,9 +960,9 @@ SCENARIO("factory tests loading yaml configs from a directory", "[loadConfig]") } } } - CHECK(strategy->resp_codes.contains(404)); - CHECK(strategy->resp_codes.contains(503)); - CHECK(!strategy->resp_codes.contains(604)); + CHECK(ptr->resp_codes.contains(404)); + CHECK(ptr->resp_codes.contains(503)); + CHECK(!ptr->resp_codes.contains(604)); } } } diff --git a/src/traffic_server/HostStatus.cc b/src/traffic_server/HostStatus.cc index ea4372209a5..40c176b2c20 100644 --- a/src/traffic_server/HostStatus.cc +++ b/src/traffic_server/HostStatus.cc @@ -58,7 +58,7 @@ mgmt_host_status_up_callback(ts::MemSpan span) if (hs.getHostStat(stat_name, buf, 1024) == REC_ERR_FAIL) { hs.createHostStat(name); } - hs.setHostStatus(name, HostStatus_t::HOST_STATUS_UP, down_time, reason); + hs.setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, down_time, reason); } } @@ -90,12 +90,12 @@ mgmt_host_status_down_callback(ts::MemSpan span) if (hs.getHostStat(stat_name, buf, 1024) == REC_ERR_FAIL) { hs.createHostStat(name); } - hs.setHostStatus(name, HostStatus_t::HOST_STATUS_DOWN, down_time, reason); + hs.setHostStatus(name, TSHostStatus::TS_HOST_STATUS_DOWN, down_time, reason); } } HostStatRec::HostStatRec() - : status(HOST_STATUS_UP), + : status(TS_HOST_STATUS_UP), reasons(0), active_marked_down(0), local_marked_down(0), @@ -126,9 +126,9 @@ HostStatRec::HostStatRec(std::string str) for (unsigned int i = 0; i < v1.size(); i++) { if (i == 0) { // set the status field if (v1.at(i).compare("HOST_STATUS_UP") == 0) { - status = HOST_STATUS_UP; + status = TS_HOST_STATUS_UP; } else if (v1.at(i).compare("HOST_STATUS_DOWN") == 0) { - status = HOST_STATUS_DOWN; + status = TS_HOST_STATUS_DOWN; } } else { // parse and set remaining reason fields. std::vector v2; @@ -246,7 +246,7 @@ HostStatus::loadRecord(std::string &name, HostStatRec &h) } void -HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned int down_time, const unsigned int reason) +HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned int down_time, const unsigned int reason) { std::string stat_name; char buf[1024] = {0}; @@ -260,7 +260,7 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned RecErrT result = getHostStat(stat_name, buf, 1024); // update / insert status. - // using the hash table pointer to store the HostStatus_t value. + // using the hash table pointer to store the TSHostStatus value. HostStatRec *host_stat = nullptr; ink_rwlock_wrlock(&host_status_rwlock); { @@ -273,7 +273,7 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned } if (reason & Reason::ACTIVE) { Debug("host_statuses", "for host %s set status: %s, Reason:ACTIVE", name, HostStatusNames[status]); - if (status == HostStatus_t::HOST_STATUS_DOWN) { + if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->active_marked_down = time(0); host_stat->active_down_time = down_time; host_stat->reasons |= Reason::ACTIVE; @@ -287,7 +287,7 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned } if (reason & Reason::LOCAL) { Debug("host_statuses", "for host %s set status: %s, Reason:LOCAL", name, HostStatusNames[status]); - if (status == HostStatus_t::HOST_STATUS_DOWN) { + if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->local_marked_down = time(0); host_stat->local_down_time = down_time; host_stat->reasons |= Reason::LOCAL; @@ -301,7 +301,7 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned } if (reason & Reason::MANUAL) { Debug("host_statuses", "for host %s set status: %s, Reason:MANUAL", name, HostStatusNames[status]); - if (status == HostStatus_t::HOST_STATUS_DOWN) { + if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->manual_marked_down = time(0); host_stat->manual_down_time = down_time; host_stat->reasons |= Reason::MANUAL; @@ -315,7 +315,7 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned } if (reason & Reason::SELF_DETECT) { Debug("host_statuses", "for host %s set status: %s, Reason:SELF_DETECT", name, HostStatusNames[status]); - if (status == HostStatus_t::HOST_STATUS_DOWN) { + if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->self_detect_marked_down = time(0); host_stat->reasons |= Reason::SELF_DETECT; } else { @@ -325,9 +325,9 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned } } } - if (status == HostStatus_t::HOST_STATUS_UP) { + if (status == TSHostStatus::TS_HOST_STATUS_UP) { if (host_stat->reasons == 0) { - host_stat->status = HostStatus_t::HOST_STATUS_UP; + host_stat->status = TSHostStatus::TS_HOST_STATUS_UP; } Debug("host_statuses", "reasons: %d, status: %s", host_stat->reasons, HostStatusNames[host_stat->status]); } else { @@ -342,7 +342,7 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned std::stringstream status_rec; status_rec << *host_stat; RecSetRecordString(stat_name.c_str(), const_cast(status_rec.str().c_str()), REC_SOURCE_EXPLICIT, true); - if (status == HostStatus_t::HOST_STATUS_UP) { + if (status == TSHostStatus::TS_HOST_STATUS_UP) { Debug("host_statuses", "set status up for name: %s, status: %d, stat_name: %s", name, status, stat_name.c_str()); } else { Debug("host_statuses", "set status down for name: %s, status: %d, stat_name: %s", name, status, stat_name.c_str()); @@ -351,7 +351,7 @@ HostStatus::setHostStatus(const char *name, HostStatus_t status, const unsigned Debug("host_statuses", "name: %s, status: %d", name, status); // log it. - if (status == HostStatus_t::HOST_STATUS_DOWN) { + if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { Note("Host %s has been marked down, down_time: %d - %s.", name, down_time, down_time == 0 ? "indefinitely." : "seconds."); } else { Note("Host %s has been marked up.", name); @@ -377,13 +377,13 @@ HostStatus::getHostStatus(const char *name) ink_rwlock_unlock(&host_status_rwlock); // if the host was marked down and it's down_time has elapsed, mark it up. - if (lookup && _status->status == HostStatus_t::HOST_STATUS_DOWN) { + if (lookup && _status->status == TSHostStatus::TS_HOST_STATUS_DOWN) { unsigned int reasons = _status->reasons; if ((_status->reasons & Reason::ACTIVE) && _status->active_down_time > 0) { if ((_status->active_down_time + _status->active_marked_down) < now) { Debug("host_statuses", "name: %s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", name, now, _status->active_down_time, _status->active_marked_down, Reason::ACTIVE_REASON); - setHostStatus(name, HostStatus_t::HOST_STATUS_UP, 0, Reason::ACTIVE); + setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::ACTIVE); reasons ^= Reason::ACTIVE; } } @@ -391,7 +391,7 @@ HostStatus::getHostStatus(const char *name) if ((_status->local_down_time + _status->local_marked_down) < now) { Debug("host_statuses", "name: %s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", name, now, _status->local_down_time, _status->local_marked_down, Reason::LOCAL_REASON); - setHostStatus(name, HostStatus_t::HOST_STATUS_UP, 0, Reason::LOCAL); + setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::LOCAL); reasons ^= Reason::LOCAL; } } @@ -399,7 +399,7 @@ HostStatus::getHostStatus(const char *name) if ((_status->manual_down_time + _status->manual_marked_down) < now) { Debug("host_statuses", "name: %s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", name, now, _status->manual_down_time, _status->manual_marked_down, Reason::MANUAL_REASON); - setHostStatus(name, HostStatus_t::HOST_STATUS_UP, 0, Reason::MANUAL); + setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::MANUAL); reasons ^= Reason::MANUAL; } } diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 178fe150119..467d3acdb7d 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -74,6 +74,7 @@ #include "I_Machine.h" #include "HttpProxyServerMain.h" #include "shared/overridable_txn_vars.h" +#include "ts/parentresult.h" #include "ts/ts.h" @@ -9909,6 +9910,42 @@ TSHttpTxnRedoCacheLookup(TSHttpTxn txnp, const char *url, int length) return TS_ERROR; } +bool +TSHostnameIsSelf(const char* hostname) +{ + return Machine::instance()->is_self(hostname); +} + +bool +TSHostStatusGet(const char *hostname, TSHostStatus* status, unsigned int *reason) +{ + HostStatRec *hst = HostStatus::instance().getHostStatus(hostname); + if (hst == nullptr) { + return false; + } + if (status != nullptr) { + *status = hst->status; + } + if (reason != nullptr) { + *reason = hst->reasons; + } + return true; +} + +void +TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int down_time, const unsigned int reason) +{ + HostStatus::instance().setHostStatus(hostname, status, down_time, reason); +} + +TSParentResult* +TSHttpTxnParentResultGet(TSHttpTxn txnp) +{ + HttpSM *sm = reinterpret_cast(txnp); + ParentResult *result = &sm->t_state.parent_result; + return &result->ts_result; +} + namespace { // Function that contains the common logic for TSRemapFrom/ToUrlGet(). From 0f1b33a42d8a6632a3c34915fe10cf735cef92b0 Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Thu, 23 Jul 2020 23:44:17 -0600 Subject: [PATCH 02/15] Change NextHop Plugin API to copy result --- include/ts/parentresult.h | 3 - include/ts/ts.h | 10 +- iocore/net/Socks.cc | 14 +- .../consistenthash.cc | 18 +- .../healthstatus.cc | 4 +- .../plugin_consistenthash.cc | 20 +-- proxy/ParentConsistentHash.cc | 74 ++++---- proxy/ParentConsistentHash.h | 2 +- proxy/ParentRoundRobin.cc | 60 +++---- proxy/ParentSelection.cc | 98 ++++++++--- proxy/ParentSelection.h | 37 ++-- proxy/ParentSelectionStrategy.cc | 24 +-- proxy/http/HttpSM.cc | 6 +- proxy/http/HttpTransact.cc | 50 +++--- proxy/http/remap/NextHopConsistentHash.cc | 76 ++++---- proxy/http/remap/NextHopHealthStatus.cc | 12 +- proxy/http/remap/NextHopRoundRobin.cc | 62 +++---- .../unit-tests/test_NextHopConsistentHash.cc | 164 +++++++++--------- .../unit-tests/test_NextHopRoundRobin.cc | 62 +++---- src/traffic_server/InkAPI.cc | 17 +- 20 files changed, 444 insertions(+), 369 deletions(-) diff --git a/include/ts/parentresult.h b/include/ts/parentresult.h index 149533b3675..a5611147557 100644 --- a/include/ts/parentresult.h +++ b/include/ts/parentresult.h @@ -37,15 +37,12 @@ struct TSParentResult { TSParentResultType result; bool chash_init[TS_MAX_GROUP_RINGS] = {false}; TSHostStatus first_choice_status = TSHostStatus::TS_HOST_STATUS_INIT; - // Internal use only - // Not to be modified by HTTP int line_number; uint32_t last_parent; uint32_t start_parent; uint32_t last_group; bool wrap_around; bool mapWrapped[2]; - // state for consistent hash. int last_lookup; ATSConsistentHashIter chashIter[TS_MAX_GROUP_RINGS]; }; diff --git a/include/ts/ts.h b/include/ts/ts.h index cecc482fe6d..908eafa1557 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -2633,11 +2633,13 @@ struct TSParentResult; /* * Gets the Transaction Parent Result pointer. - * Note this is the actual pointer inside the TSHttpTxn. - * It MUST NOT be freed. The data it points to may be modified. */ -struct TSParentResult* -TSHttpTxnParentResultGet(TSHttpTxn txnp); +void TSHttpTxnParentResultGet(TSHttpTxn txnp, struct TSParentResult* result); + +/* +* Sets the Transaction Parent Result pointer. +*/ +void TSHttpTxnParentResultSet(TSHttpTxn txnp, struct TSParentResult* result); #ifdef __cplusplus } diff --git a/iocore/net/Socks.cc b/iocore/net/Socks.cc index 251396092a4..dbc2a02835a 100644 --- a/iocore/net/Socks.cc +++ b/iocore/net/Socks.cc @@ -90,7 +90,7 @@ SocksEntry::findServer() #ifdef SOCKS_WITH_TS if (nattempts == 1) { - ink_assert(server_result.ts_result.result == PARENT_UNDEFINED); + ink_assert(server_result.result == PARENT_UNDEFINED); server_params->findParent(&req_data, &server_result, fail_threshold, retry_time); } else { socks_conf_struct *conf = netProcessor.socks_conf_stuff; @@ -101,21 +101,21 @@ SocksEntry::findServer() server_params->markParentDown(&server_result, fail_threshold, retry_time); if (nattempts > conf->connection_attempts) { - server_result.ts_result.result = PARENT_FAIL; + server_result.result = PARENT_FAIL; } else { server_params->nextParent(&req_data, &server_result, fail_threshold, retry_time); } } - switch (server_result.ts_result.result) { + switch (server_result.result) { case PARENT_SPECIFIED: // Original was inet_addr, but should hostnames work? // ats_ip_pton only supports numeric (because other clients // explicitly want to avoid hostname lookups). - if (0 == ats_ip_pton(server_result.ts_result.hostname, &server_addr)) { - ats_ip_port_cast(&server_addr) = htons(server_result.ts_result.port); + if (0 == ats_ip_pton(server_result.hostname, &server_addr)) { + ats_ip_port_cast(&server_addr) = htons(server_result.port); } else { - Debug("SocksParent", "Invalid parent server specified %s", server_result.ts_result.hostname); + Debug("SocksParent", "Invalid parent server specified %s", server_result.hostname); } break; @@ -151,7 +151,7 @@ SocksEntry::free() } #ifdef SOCKS_WITH_TS - if (!lerrno && netVConnection && server_result.ts_result.retry) { + if (!lerrno && netVConnection && server_result.retry) { server_params->markParentUp(&server_result); } #endif diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index 662c685eddd..6e35cadb282 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -224,10 +224,11 @@ NextHopConsistentHash::getHashKey(uint64_t sm_id, TSMBuffer reqp, TSMLoc url, TS return h->get(); } -static void setParentResultErr(TSParentResult *result) { +static void setParentResultErr(TSHttpTxn txnp, TSParentResult *result) { result->hostname = nullptr; result->port = 0; result->retry = false; + TSHttpTxnParentResultSet(txnp, result); } void @@ -235,7 +236,10 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) { NH_Debug(NH_DEBUG_TAG, "NH plugin findNexthop calling"); - TSParentResult* result = TSHttpTxnParentResultGet(txnp); + TSParentResult result_obj; + TSParentResult *result = &result_obj; + TSHttpTxnParentResultGet(txnp, result); + int64_t sm_id = TSHttpTxnIdGet(txnp); TSMBuffer reqp; // TODO verify doesn't need freed @@ -243,7 +247,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSMLoc hdr; ScopedFreeMLoc hdr_cleanup(&reqp, TS_NULL_MLOC, &hdr); if (TSHttpTxnClientReqGet(txnp, &reqp, &hdr) == TS_ERROR) { - setParentResultErr(result); + setParentResultErr(txnp, result); return; } @@ -251,7 +255,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) ScopedFreeMLoc parent_selection_url_cleanup(&reqp, TS_NULL_MLOC, &parent_selection_url); if (TSUrlCreate(reqp, &parent_selection_url) != TS_SUCCESS) { NH_Error("nexthop failed to create url for parent_selection_url"); - setParentResultErr(result); + setParentResultErr(txnp, result); return; } if (TSHttpTxnParentSelectionUrlGet(txnp, reqp, parent_selection_url) != TS_SUCCESS) { @@ -262,7 +266,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) ScopedFreeMLoc url_cleanup(&reqp, hdr, &url); if (TSHttpHdrUrlGet(reqp, hdr, &url) != TS_SUCCESS) { NH_Error("failed to get header url, cannot find next hop"); - setParentResultErr(result); + setParentResultErr(txnp, result); return; } @@ -273,7 +277,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_HTTP_PARENT_PROXY_RETRY_TIME, &retry_time) != TS_SUCCESS) { // TODO get and cache on init, to prevent potential runtime failure? NH_Error("failed to get parent retry time, cannot find next hop"); - setParentResultErr(result); + setParentResultErr(txnp, result); return; } @@ -473,4 +477,6 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) result->retry = false; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, ParentResultStr[result->result]); } + + TSHttpTxnParentResultSet(txnp, result); } diff --git a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc index 6eee97245ca..85c2f93107d 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc @@ -60,7 +60,9 @@ void NextHopHealthStatus::markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now) { const time_t _now = now == 0 ? time(nullptr) : now; - TSParentResult* result = TSHttpTxnParentResultGet(txnp); + TSParentResult result_obj; + TSParentResult *result = &result_obj; + TSHttpTxnParentResultGet(txnp, result); const int64_t sm_id = TSHttpTxnIdGet(txnp); int64_t fail_threshold; // = sm->t_state.txn_conf->parent_fail_threshold; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc index 19e696a5764..c87cc18d98e 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc @@ -85,16 +85,16 @@ TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size) { // TODO add ATS API Version check here, to bail if ATS doesn't support the version necessary for strategy plugins - // if (!api_info) { - // strncpy(errbuf, "[tsstrategy_init] - Invalid TSRemapInterface argument", errbuf_size - 1); - // return TS_ERROR; - // } - - // if (api_info->tsremap_version < TSREMAP_VERSION) { - // snprintf(errbuf, errbuf_size, "[TSStrategyInit] - Incorrect API version %ld.%ld", api_info->tsremap_version >> 16, - // (api_info->tsremap_version & 0xffff)); - // return TS_ERROR; - // } + if (!api_info) { + strncpy(errbuf, "[tsstrategy_init] - Invalid TSRemapInterface argument", errbuf_size - 1); + return TS_ERROR; + } + + if (api_info->tsremap_version < TSREMAP_VERSION) { + snprintf(errbuf, errbuf_size, "[TSStrategyInit] - Incorrect API version %ld.%ld", api_info->tsremap_version >> 16, + (api_info->tsremap_version & 0xffff)); + return TS_ERROR; + } NH_Debug(NH_DEBUG_TAG, "%s is successfully initialized.", PLUGIN_NAME); return TS_SUCCESS; diff --git a/proxy/ParentConsistentHash.cc b/proxy/ParentConsistentHash.cc index 550e6bfcf79..ab9d11d62c3 100644 --- a/proxy/ParentConsistentHash.cc +++ b/proxy/ParentConsistentHash.cc @@ -150,12 +150,12 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques // Should only get into this state if we are supposed to go direct. if (parents[PRIMARY] == nullptr && parents[SECONDARY] == nullptr) { if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; + result->hostname = nullptr; + result->port = 0; return; } @@ -173,7 +173,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques last_lookup = PRIMARY; break; case 3: - if (result->ts_result.first_choice_status == TS_HOST_STATUS_DOWN && chash[SECONDARY] != nullptr) { + if (result->first_choice_status == TS_HOST_STATUS_DOWN && chash[SECONDARY] != nullptr) { last_lookup = SECONDARY; } else { last_lookup = PRIMARY; @@ -193,8 +193,8 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques path_hash = getPathHash(request_info, (ATSHash64 *)&hash); fhash = chash[last_lookup]; do { // search until we've selected a different parent if !firstCall - prtmp = chash_lookup(fhash, path_hash, &result->ts_result.chashIter[last_lookup], &wrap_around[last_lookup], &hash, - &result->ts_result.chash_init[last_lookup], &result->ts_result.mapWrapped[last_lookup]); + prtmp = chash_lookup(fhash, path_hash, &result->chashIter[last_lookup], &wrap_around[last_lookup], &hash, + &result->chash_init[last_lookup], &result->mapWrapped[last_lookup]); lookups++; if (prtmp) { pRec = (parents[last_lookup] + prtmp->idx); @@ -203,10 +203,10 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques } if (firstCall) { HostStatRec *hst = (pRec) ? pStatus.getHostStatus(pRec->hostname) : nullptr; - result->ts_result.first_choice_status = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; + result->first_choice_status = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; break; } - } while (pRec && !firstCall && last_lookup == PRIMARY && strcmp(pRec->hostname, result->ts_result.hostname) == 0); + } while (pRec && !firstCall && last_lookup == PRIMARY && strcmp(pRec->hostname, result->hostname) == 0); Debug("parent_select", "Initial parent lookups: %d", lookups); @@ -234,10 +234,10 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques if ((pRec->failedAt + retry_time) < request_info->xact_start) { parentRetry = true; // make sure that the proper state is recorded in the result structure - result->ts_result.last_parent = pRec->idx; - result->ts_result.last_lookup = last_lookup; - result->ts_result.retry = parentRetry; - result->ts_result.result = PARENT_SPECIFIED; + result->last_parent = pRec->idx; + result->last_lookup = last_lookup; + result->retry = parentRetry; + result->result = PARENT_SPECIFIED; Debug("parent_select", "Down parent %s is now retryable, marked it available.", pRec->hostname); break; } @@ -254,7 +254,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques } break; case 3: - if (result->ts_result.first_choice_status == TS_HOST_STATUS_DOWN) { + if (result->first_choice_status == TS_HOST_STATUS_DOWN) { if (chash[SECONDARY] != nullptr && !wrap_around[SECONDARY]) { last_lookup = SECONDARY; } else if (!wrap_around[PRIMARY]) { @@ -277,8 +277,8 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques } } fhash = chash[last_lookup]; - prtmp = chash_lookup(fhash, path_hash, &result->ts_result.chashIter[last_lookup], &wrap_around[last_lookup], &hash, - &result->ts_result.chash_init[last_lookup], &result->ts_result.mapWrapped[last_lookup]); + prtmp = chash_lookup(fhash, path_hash, &result->chashIter[last_lookup], &wrap_around[last_lookup], &hash, + &result->chash_init[last_lookup], &result->mapWrapped[last_lookup]); lookups++; if (prtmp) { pRec = (parents[last_lookup] + prtmp->idx); @@ -323,25 +323,25 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques host_stat = TS_HOST_STATUS_UP; } } - if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->ts_result.retry)) { - result->ts_result.result = PARENT_SPECIFIED; - result->ts_result.hostname = pRec->hostname; - result->ts_result.port = pRec->port; - result->ts_result.last_parent = pRec->idx; - result->ts_result.last_lookup = last_lookup; - result->ts_result.retry = parentRetry; - ink_assert(result->ts_result.hostname != nullptr); - ink_assert(result->ts_result.port != 0); - Debug("parent_select", "Chosen parent: %s.%d", result->ts_result.hostname, result->ts_result.port); + if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->retry)) { + result->result = PARENT_SPECIFIED; + result->hostname = pRec->hostname; + result->port = pRec->port; + result->last_parent = pRec->idx; + result->last_lookup = last_lookup; + result->retry = parentRetry; + ink_assert(result->hostname != nullptr); + ink_assert(result->port != 0); + Debug("parent_select", "Chosen parent: %s.%d", result->hostname, result->port); } else { if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; - result->ts_result.retry = false; + result->hostname = nullptr; + result->port = 0; + result->retry = false; } return; @@ -352,7 +352,7 @@ ParentConsistentHash::numParents(ParentResult *result) const { uint32_t n = 0; - switch (result->ts_result.last_lookup) { + switch (result->last_lookup) { case PRIMARY: n = result->rec->num_parents; break; @@ -371,9 +371,9 @@ ParentConsistentHash::markParentUp(ParentResult *result) // Make sure that we are being called back with with a // result structure with a parent that is being retried - ink_release_assert(result->ts_result.retry == true); - ink_assert(result->ts_result.result == PARENT_SPECIFIED); - if (result->ts_result.result != PARENT_SPECIFIED) { + ink_release_assert(result->retry == true); + ink_assert(result->result == PARENT_SPECIFIED); + if (result->result != PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover @@ -383,8 +383,8 @@ ParentConsistentHash::markParentUp(ParentResult *result) return; } - ink_assert((result->ts_result.last_parent) < numParents(result)); - pRec = parents[result->ts_result.last_lookup] + result->ts_result.last_parent; + ink_assert((result->last_parent) < numParents(result)); + pRec = parents[result->last_lookup] + result->last_parent; ink_atomic_swap(&pRec->available, true); Debug("parent_select", "%s:%s(): marked %s:%d available.", __FILE__, __func__, pRec->hostname, pRec->port); diff --git a/proxy/ParentConsistentHash.h b/proxy/ParentConsistentHash.h index 4ce904353e6..3a8ee582789 100644 --- a/proxy/ParentConsistentHash.h +++ b/proxy/ParentConsistentHash.h @@ -55,7 +55,7 @@ class ParentConsistentHash : public ParentSelectionStrategy pRecord * getParents(ParentResult *result) override { - return parents[result->ts_result.last_lookup]; + return parents[result->last_lookup]; } uint64_t getPathHash(HttpRequestData *hrdata, ATSHash64 *h); void selectParent(bool firstCall, ParentResult *result, RequestData *rdata, unsigned int fail_threshold, diff --git a/proxy/ParentRoundRobin.cc b/proxy/ParentRoundRobin.cc index 1cf0ee92f2f..495bc2507ab 100644 --- a/proxy/ParentRoundRobin.cc +++ b/proxy/ParentRoundRobin.cc @@ -76,13 +76,13 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat ink_assert(result->rec->go_direct == true); // Could not find a parent if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; + result->hostname = nullptr; + result->port = 0; return; } else { switch (round_robin_type) { @@ -93,20 +93,20 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat // preserved for now anyway as ats_ip_hash returns the 32-bit address in // that case. if (rdata->get_client_ip() != nullptr) { - cur_index = result->ts_result.start_parent = ntohl(ats_ip_hash(rdata->get_client_ip())) % num_parents; + cur_index = result->start_parent = ntohl(ats_ip_hash(rdata->get_client_ip())) % num_parents; } else { cur_index = 0; } break; case P_STRICT_ROUND_ROBIN: - cur_index = result->ts_result.start_parent = + cur_index = result->start_parent = ink_atomic_increment(reinterpret_cast(&result->rec->rr_next), 1) % num_parents; break; case P_NO_ROUND_ROBIN: - cur_index = result->ts_result.start_parent = 0; + cur_index = result->start_parent = 0; break; case P_LATCHED_ROUND_ROBIN: - cur_index = result->ts_result.start_parent = latched_parent; + cur_index = result->start_parent = latched_parent; break; default: ink_release_assert(0); @@ -114,20 +114,20 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat } } else { // Move to next parent due to failure - latched_parent = cur_index = (result->ts_result.last_parent + 1) % num_parents; + latched_parent = cur_index = (result->last_parent + 1) % num_parents; // Check to see if we have wrapped around - if (static_cast(cur_index) == result->ts_result.start_parent) { + if (static_cast(cur_index) == result->start_parent) { // We've wrapped around so bypass if we can if (result->rec->go_direct == true) { // Could not find a parent if (result->rec->parent_is_proxy == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; + result->hostname = nullptr; + result->port = 0; return; } } @@ -145,7 +145,7 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat host_stat = TS_HOST_STATUS_UP; } } - Debug("parent_select", "cur_index: %d, result->ts_result.start_parent: %d", cur_index, result->ts_result.start_parent); + Debug("parent_select", "cur_index: %d, result->start_parent: %d", cur_index, result->start_parent); // DNS ParentOnly inhibits bypassing the parent so always return that t if ((parents[cur_index].failedAt == 0) || (parents[cur_index].failCount < static_cast(fail_threshold))) { if (host_stat == TS_HOST_STATUS_UP) { @@ -155,10 +155,10 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat parentUp = true; } } else { - if ((result->ts_result.wrap_around) || + if ((result->wrap_around) || ((parents[cur_index].failedAt + retry_time) < request_info->xact_start && host_stat == TS_HOST_STATUS_UP)) { Debug("parent_select", "Parent[%d].failedAt = %u, retry = %u,xact_start = %" PRId64 " but wrap = %d", cur_index, - (unsigned)parents[cur_index].failedAt, retry_time, (int64_t)request_info->xact_start, result->ts_result.wrap_around); + (unsigned)parents[cur_index].failedAt, retry_time, (int64_t)request_info->xact_start, result->wrap_around); // Reuse the parent parentUp = true; parentRetry = true; @@ -170,27 +170,27 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat if (parentUp == true && host_stat != TS_HOST_STATUS_DOWN) { Debug("parent_select", "status for %s: %d", parents[cur_index].hostname, host_stat); - result->ts_result.result = PARENT_SPECIFIED; - result->ts_result.hostname = parents[cur_index].hostname; - result->ts_result.port = parents[cur_index].port; - result->ts_result.last_parent = cur_index; - result->ts_result.retry = parentRetry; - ink_assert(result->ts_result.hostname != nullptr); - ink_assert(result->ts_result.port != 0); - Debug("parent_select", "Chosen parent = %s.%d", result->ts_result.hostname, result->ts_result.port); + result->result = PARENT_SPECIFIED; + result->hostname = parents[cur_index].hostname; + result->port = parents[cur_index].port; + result->last_parent = cur_index; + result->retry = parentRetry; + ink_assert(result->hostname != nullptr); + ink_assert(result->port != 0); + Debug("parent_select", "Chosen parent = %s.%d", result->hostname, result->port); return; } latched_parent = cur_index = (cur_index + 1) % num_parents; - } while (static_cast(cur_index) != result->ts_result.start_parent); + } while (static_cast(cur_index) != result->start_parent); if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; + result->hostname = nullptr; + result->port = 0; } uint32_t diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc index 34cc98e35ee..cd7945ca382 100644 --- a/proxy/ParentSelection.cc +++ b/proxy/ParentSelection.cc @@ -109,14 +109,14 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns // Check to see if the parent was set through the // api if (apiParentExists(rdata)) { - result->ts_result.result = PARENT_SPECIFIED; - result->ts_result.hostname = rdata->api_info->parent_proxy_name; - result->ts_result.port = rdata->api_info->parent_proxy_port; + result->result = PARENT_SPECIFIED; + result->hostname = rdata->api_info->parent_proxy_name; + result->port = rdata->api_info->parent_proxy_port; result->rec = extApiRecord; - result->ts_result.start_parent = 0; - result->ts_result.last_parent = 0; + result->start_parent = 0; + result->last_parent = 0; - Debug("parent_select", "Result for %s was API set parent %s:%d", rdata->get_host(), result->ts_result.hostname, result->ts_result.port); + Debug("parent_select", "Result for %s was API set parent %s:%d", rdata->get_host(), result->hostname, result->port); return; } @@ -133,7 +133,7 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns if (defaultPtr != nullptr) { rec = result->rec = defaultPtr; } else { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; Debug("parent_select", "Returning PARENT_DIRECT (no parents were found)"); return; } @@ -145,21 +145,21 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns const char *host = rdata->get_host(); - switch (result->ts_result.result) { + switch (result->result) { case PARENT_UNDEFINED: Debug("parent_select", "PARENT_UNDEFINED"); - Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->ts_result.result]); + Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->result]); break; case PARENT_FAIL: Debug("parent_select", "PARENT_FAIL"); break; case PARENT_DIRECT: Debug("parent_select", "PARENT_DIRECT"); - Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->ts_result.result]); + Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->result]); break; case PARENT_SPECIFIED: Debug("parent_select", "PARENT_SPECIFIED"); - Debug("parent_select", "Result for %s was parent %s:%d", host, result->ts_result.hostname, result->ts_result.port); + Debug("parent_select", "Result for %s was parent %s:%d", host, result->hostname, result->port); break; default: // Handled here: @@ -177,19 +177,19 @@ ParentConfigParams::nextParent(HttpRequestData *rdata, ParentResult *result, uns // Make sure that we are being called back with a // result structure with a parent - ink_assert(result->ts_result.result == PARENT_SPECIFIED); - if (result->ts_result.result != PARENT_SPECIFIED) { - result->ts_result.result = PARENT_FAIL; + ink_assert(result->result == PARENT_SPECIFIED); + if (result->result != PARENT_SPECIFIED) { + result->result = PARENT_FAIL; return; } // If we were set through the API we currently have not failover // so just return fail if (result->is_api_result()) { - Debug("parent_select", "Retry result for %s was %s", rdata->get_host(), ParentResultStr[result->ts_result.result]); - result->ts_result.result = PARENT_FAIL; + Debug("parent_select", "Retry result for %s was %s", rdata->get_host(), ParentResultStr[result->result]); + result->result = PARENT_FAIL; return; } - Debug("parent_select", "ParentConfigParams::nextParent(): result->r: %d, tablePtr: %p", result->ts_result.result, tablePtr); + Debug("parent_select", "ParentConfigParams::nextParent(): result->r: %d, tablePtr: %p", result->result, tablePtr); // Find the next parent in the array Debug("parent_select", "Calling selectParent() from nextParent"); @@ -197,21 +197,21 @@ ParentConfigParams::nextParent(HttpRequestData *rdata, ParentResult *result, uns const char *host = rdata->get_host(); - switch (result->ts_result.result) { + switch (result->result) { case PARENT_UNDEFINED: Debug("parent_select", "PARENT_UNDEFINED"); - Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->ts_result.result]); + Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); break; case PARENT_FAIL: Debug("parent_select", "PARENT_FAIL"); - Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->ts_result.result]); + Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); break; case PARENT_DIRECT: Debug("parent_select", "PARENT_DIRECT"); - Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->ts_result.result]); + Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); break; case PARENT_SPECIFIED: - Debug("parent_select", "Retry result for %s was parent %s:%d", host, result->ts_result.hostname, result->ts_result.port); + Debug("parent_select", "Retry result for %s was parent %s:%d", host, result->hostname, result->port); break; default: // Handled here: @@ -841,9 +841,9 @@ ParentRecord::Init(matcher_line *line_info) void ParentRecord::UpdateMatch(ParentResult *result, RequestData *rdata) { - if (this->CheckForMatch((HttpRequestData *)rdata, result->ts_result.line_number) == true) { + if (this->CheckForMatch((HttpRequestData *)rdata, result->line_number) == true) { result->rec = this; - result->ts_result.line_number = this->line_num; + result->line_number = this->line_num; Debug("parent_select", "Matched with %p parent node from line %d", this, this->line_num); } @@ -1842,7 +1842,7 @@ verify(ParentResult *r, TSParentResultType e, const char *h, int p) if (is_debug_tag_set("parent_select")) { show_result(r); } - return (r->ts_result.result != e) ? 0 : ((e != PARENT_SPECIFIED) ? 1 : (strcmp(r->ts_result.hostname, h) ? 0 : ((r->ts_result.port == p) ? 1 : 0))); + return (r->result != e) ? 0 : ((e != PARENT_SPECIFIED) ? 1 : (strcmp(r->hostname, h) ? 0 : ((r->port == p) ? 1 : 0))); } // br creates an HttpRequestData object @@ -1864,7 +1864,7 @@ br(HttpRequestData *h, const char *os_hostname, sockaddr const *dest_ip) void show_result(ParentResult *p) { - switch (p->ts_result.result) { + switch (p->result) { case PARENT_UNDEFINED: printf("result is PARENT_UNDEFINED\n"); break; @@ -1873,8 +1873,8 @@ show_result(ParentResult *p) break; case PARENT_SPECIFIED: printf("result is PARENT_SPECIFIED\n"); - printf("hostname is %s\n", p->ts_result.hostname); - printf("port is %d\n", p->ts_result.port); + printf("hostname is %s\n", p->hostname); + printf("port is %d\n", p->port); break; case PARENT_FAIL: printf("result is PARENT_FAIL\n"); @@ -1885,3 +1885,45 @@ show_result(ParentResult *p) break; } } + +void +ParentResult::copyFrom(TSParentResult *r) +{ + this->hostname = r->hostname; + this->port = r->port; + this->retry = r->retry; + this->result = r->result; + memcpy(this->chash_init, r->chash_init, TS_MAX_GROUP_RINGS*sizeof(bool)); + this->first_choice_status = r->first_choice_status; + this->line_number = r->line_number; + this->last_parent = r->last_parent; + this->start_parent = r->start_parent; + this->last_group = r->last_group; + this->wrap_around = r->wrap_around; + memcpy(this->mapWrapped, r->mapWrapped, 2*sizeof(bool)); + this->last_lookup = r->last_lookup; + for (int i = 0; i < TS_MAX_GROUP_RINGS; ++i) { + this->chashIter[i] = r->chashIter[i]; + } +} + +void +ParentResult::copyTo(TSParentResult *r) +{ + r->hostname = this->hostname; + r->port = this->port; + r->retry = this->retry; + r->result = this->result; + memcpy(r->chash_init, this->chash_init, TS_MAX_GROUP_RINGS*sizeof(bool)); + r->first_choice_status = this->first_choice_status; + r->line_number = this->line_number; + r->last_parent = this->last_parent; + r->start_parent = this->start_parent; + r->last_group = this->last_group; + r->wrap_around = this->wrap_around; + memcpy(r->mapWrapped, this->mapWrapped, 2*sizeof(bool)); + r->last_lookup = this->last_lookup; + for (int i = 0; i < TS_MAX_GROUP_RINGS; ++i) { + r->chashIter[i] = this->chashIter[i]; + } +} diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h index 95085cbe3ed..925b86cd1ca 100644 --- a/proxy/ParentSelection.h +++ b/proxy/ParentSelection.h @@ -166,18 +166,23 @@ class ParentRecord : public ControlBase ParentRecord *const extApiRecord = (ParentRecord *)0xeeeeffff; struct ParentResult { - TSParentResult ts_result; - ParentResult() { reset(); } + // For outside consumption + TSParentResultType result; + const char *hostname; + int port; + bool retry; + bool chash_init[TS_MAX_GROUP_RINGS] = {false}; + TSHostStatus first_choice_status = TSHostStatus::TS_HOST_STATUS_INIT; void reset() { ink_zero(*this); - ts_result.line_number = -1; - ts_result.result = PARENT_UNDEFINED; - ts_result.mapWrapped[0] = false; - ts_result.mapWrapped[1] = false; + line_number = -1; + result = PARENT_UNDEFINED; + mapWrapped[0] = false; + mapWrapped[1] = false; } bool @@ -194,7 +199,7 @@ struct ParentResult { // If we don't have a result, we either haven't done a parent // lookup yet (PARENT_UNDEFINED), or the lookup didn't match // anything (PARENT_DIRECT). - ink_assert(ts_result.result == PARENT_UNDEFINED || ts_result.result == PARENT_DIRECT); + ink_assert(result == PARENT_UNDEFINED || result == PARENT_DIRECT); return false; } @@ -262,7 +267,7 @@ struct ParentResult { return false; } else { // Caller should check for a valid result beforehand. - ink_assert(ts_result.result != PARENT_UNDEFINED); + ink_assert(result != PARENT_UNDEFINED); ink_assert(is_some()); return rec->bypass_ok(); } @@ -273,14 +278,26 @@ struct ParentResult { { printf("ParentResult - hostname: %s, port: %d, retry: %s, line_number: %d, last_parent: %d, start_parent: %d, wrap_around: %s, " "last_lookup: %d, result: %s\n", - ts_result.hostname, ts_result.port, (ts_result.retry) ? "true" : "false", ts_result.line_number, ts_result.last_parent, ts_result.start_parent, (ts_result.wrap_around) ? "true" : "false", - ts_result.last_lookup, ParentResultStr[ts_result.result]); + hostname, port, (retry) ? "true" : "false", line_number, last_parent, start_parent, (wrap_around) ? "true" : "false", + last_lookup, ParentResultStr[result]); } + void copyFrom(TSParentResult *r); + void copyTo(TSParentResult *r); + private: // Internal use only // Not to be modified by HTTP + int line_number; ParentRecord *rec; + uint32_t last_parent; + uint32_t start_parent; + uint32_t last_group; + bool wrap_around; + bool mapWrapped[2]; + // state for consistent hash. + int last_lookup; + ATSConsistentHashIter chashIter[TS_MAX_GROUP_RINGS]; friend class NextHopSelectionStrategy; friend class NextHopRoundRobin; diff --git a/proxy/ParentSelectionStrategy.cc b/proxy/ParentSelectionStrategy.cc index 3fa9d3d8e0f..cf067b41ea3 100644 --- a/proxy/ParentSelectionStrategy.cc +++ b/proxy/ParentSelectionStrategy.cc @@ -32,8 +32,8 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ // Make sure that we are being called back with with a // result structure with a parent - ink_assert(result->ts_result.result == PARENT_SPECIFIED); - if (result->ts_result.result != PARENT_SPECIFIED) { + ink_assert(result->result == PARENT_SPECIFIED); + if (result->result != PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover @@ -42,8 +42,8 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ return; } - ink_assert((result->ts_result.last_parent) < numParents(result)); - pRec = (parents + result->ts_result.last_parent); + ink_assert((result->last_parent) < numParents(result)); + pRec = (parents + result->last_parent); // If the parent has already been marked down, just increment // the failure count. If this is the first mark down on a @@ -53,7 +53,7 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ // handle this condition. If this was the result of a retry, we // must update move the failedAt timestamp to now so that we continue // negative cache the parent - if (pRec->failedAt == 0 || result->ts_result.retry == true) { + if (pRec->failedAt == 0 || result->retry == true) { // Reread the current time. We want this to be accurate since // it relates to how long the parent has been down. now = time(nullptr); @@ -63,11 +63,11 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ // If this is clean mark down and not a failed retry, we // must set the count to reflect this - if (result->ts_result.retry == false) { + if (result->retry == false) { new_fail_count = pRec->failCount = 1; } - Note("Parent %s marked as down %s:%d", (result->ts_result.retry) ? "retry" : "initially", pRec->hostname, pRec->port); + Note("Parent %s marked as down %s:%d", (result->retry) ? "retry" : "initially", pRec->hostname, pRec->port); } else { int old_count = 0; @@ -103,9 +103,9 @@ ParentSelectionStrategy::markParentUp(ParentResult *result) // Make sure that we are being called back with with a // result structure with a parent that is being retried - ink_release_assert(result->ts_result.retry == true); - ink_assert(result->ts_result.result == PARENT_SPECIFIED); - if (result->ts_result.result != PARENT_SPECIFIED) { + ink_release_assert(result->retry == true); + ink_assert(result->result == PARENT_SPECIFIED); + if (result->result != PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover @@ -115,8 +115,8 @@ ParentSelectionStrategy::markParentUp(ParentResult *result) return; } - ink_assert((int)(result->ts_result.last_parent) < num_parents); - pRec = parents + result->ts_result.last_parent; + ink_assert((int)(result->last_parent) < num_parents); + pRec = parents + result->last_parent; ink_atomic_swap(&pRec->available, true); ink_atomic_swap(&pRec->failedAt, static_cast(0)); diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index e4d5d6cbfea..6991b95c8ef 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -7411,7 +7411,7 @@ HttpSM::set_next_state() call_transact_and_set_next_state(nullptr); break; } else if (t_state.http_config_param->use_client_target_addr == 2 && !t_state.url_remap_success && - t_state.parent_result.ts_result.result != PARENT_SPECIFIED && t_state.client_info.is_transparent && + t_state.parent_result.result != PARENT_SPECIFIED && t_state.client_info.is_transparent && t_state.dns_info.os_addr_style == HttpTransact::DNSLookupInfo::OS_Addr::OS_ADDR_TRY_DEFAULT && ats_is_ip(addr = ua_txn->get_netvc()->get_local_addr())) { /* If the connection is client side transparent and the URL @@ -7440,14 +7440,14 @@ HttpSM::set_next_state() t_state.dns_info.os_addr_style = HttpTransact::DNSLookupInfo::OS_Addr::OS_ADDR_TRY_CLIENT; call_transact_and_set_next_state(nullptr); break; - } else if (t_state.parent_result.ts_result.result == PARENT_UNDEFINED && t_state.dns_info.lookup_success) { + } else if (t_state.parent_result.result == PARENT_UNDEFINED && t_state.dns_info.lookup_success) { // Already set, and we don't have a parent proxy to lookup ink_assert(ats_is_ip(t_state.host_db_info.ip())); SMDebug("dns", "[HttpTransact::HandleRequest] Skipping DNS lookup, provided by plugin"); call_transact_and_set_next_state(nullptr); break; } else if (t_state.dns_info.looking_up == HttpTransact::ORIGIN_SERVER && t_state.http_config_param->no_dns_forward_to_parent && - t_state.parent_result.ts_result.result != PARENT_UNDEFINED) { + t_state.parent_result.result != PARENT_UNDEFINED) { t_state.dns_info.lookup_success = true; call_transact_and_set_next_state(nullptr); break; diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index 7d812987c13..86c511ded37 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -196,7 +196,7 @@ markParentDown(HttpTransact::State *s) url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.ts_result.hostname, s->parent_result.ts_result.port, NH_MARK_DOWN); + return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, s->parent_result.port, NH_MARK_DOWN); } else if (s->parent_params) { return s->parent_params->markParentDown(&s->parent_result, s->txn_conf->parent_fail_threshold, s->txn_conf->parent_retry_time); } @@ -209,7 +209,7 @@ markParentUp(HttpTransact::State *s) { url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.ts_result.hostname, s->parent_result.ts_result.port, NH_MARK_UP); + return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, s->parent_result.port, NH_MARK_UP); } else if (s->parent_params) { return s->parent_params->markParentUp(&s->parent_result); } @@ -533,16 +533,16 @@ find_server_and_update_current_info(HttpTransact::State *s) // I just wanted to do this for cop heartbeats, someone else // wanted it for all requests to local_host. TxnDebug("http_trans", "request is from localhost, so bypass parent"); - s->parent_result.ts_result.result = PARENT_DIRECT; + s->parent_result.result = PARENT_DIRECT; } else if (s->method == HTTP_WKSIDX_CONNECT && s->http_config_param->disable_ssl_parenting) { - if (s->parent_result.ts_result.result == PARENT_SPECIFIED) { + if (s->parent_result.result == PARENT_SPECIFIED) { nextParent(s); } else { findParent(s); } if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) { TxnDebug("http_trans", "request not cacheable, so bypass parent"); - s->parent_result.ts_result.result = PARENT_DIRECT; + s->parent_result.result = PARENT_DIRECT; } } else if (s->txn_conf->uncacheable_requests_bypass_parent && s->http_config_param->no_dns_forward_to_parent == 0 && !HttpTransact::is_request_cache_lookupable(s)) { @@ -552,17 +552,17 @@ find_server_and_update_current_info(HttpTransact::State *s) // we are assuming both child and parent have similar configuration // with respect to whether a request is cacheable or not. // For example, the cache_urls_that_look_dynamic variable. - if (s->parent_result.ts_result.result == PARENT_SPECIFIED) { + if (s->parent_result.result == PARENT_SPECIFIED) { nextParent(s); } else { findParent(s); } if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) { TxnDebug("http_trans", "request not cacheable, so bypass parent"); - s->parent_result.ts_result.result = PARENT_DIRECT; + s->parent_result.result = PARENT_DIRECT; } } else { - switch (s->parent_result.ts_result.result) { + switch (s->parent_result.result) { case PARENT_UNDEFINED: findParent(s); break; @@ -573,9 +573,9 @@ find_server_and_update_current_info(HttpTransact::State *s) // We already have a parent that failed, if we are now told // to go the origin server, we can only obey this if we // dns'ed the origin server - if (s->parent_result.ts_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 0) { + if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 0) { ink_assert(!s->server_info.dst_addr.isValid()); - s->parent_result.ts_result.result = PARENT_FAIL; + s->parent_result.result = PARENT_FAIL; } break; case PARENT_FAIL: @@ -586,7 +586,7 @@ find_server_and_update_current_info(HttpTransact::State *s) // 3) the parent was not set from API if (s->http_config_param->no_dns_forward_to_parent == 0 && bypass_ok(s) && parent_is_proxy(s) && !s->parent_params->apiParentExists(&s->request_data)) { - s->parent_result.ts_result.result = PARENT_DIRECT; + s->parent_result.result = PARENT_DIRECT; } break; default: @@ -600,9 +600,9 @@ find_server_and_update_current_info(HttpTransact::State *s) } } - switch (s->parent_result.ts_result.result) { + switch (s->parent_result.result) { case PARENT_SPECIFIED: - s->parent_info.name = s->arena.str_store(s->parent_result.ts_result.hostname, strlen(s->parent_result.ts_result.hostname)); + s->parent_info.name = s->arena.str_store(s->parent_result.hostname, strlen(s->parent_result.hostname)); update_current_info(&s->current, &s->parent_info, HttpTransact::PARENT_PROXY, (s->current.attempts)++); update_dns_info(&s->dns_info, &s->current); ink_assert(s->dns_info.looking_up == HttpTransact::PARENT_PROXY); @@ -619,7 +619,7 @@ find_server_and_update_current_info(HttpTransact::State *s) // we're unable to go direct to the origin. if (s->http_config_param->no_dns_forward_to_parent) { Warning("no available parents and the config proxy.config.http.no_dns_just_forward_to_parent, prevents origin lookups."); - s->parent_result.ts_result.result = PARENT_FAIL; + s->parent_result.result = PARENT_FAIL; return HttpTransact::HOST_NONE; } /* fall through */ @@ -1731,7 +1731,7 @@ HttpTransact::PPDNSLookup(State *s) if (!s->current.server->dst_addr.isValid()) { if (s->current.request_to == PARENT_PROXY) { TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, PPDNSLookup); - } else if (s->parent_result.ts_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { + } else if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { // We ran out of parents but parent configuration allows us to go to Origin Server directly return CallOSDNSLookup(s); } else { @@ -1744,7 +1744,7 @@ HttpTransact::PPDNSLookup(State *s) } else { // lookup succeeded, open connection to p.p. ats_ip_copy(&s->parent_info.dst_addr, s->host_db_info.ip()); - s->parent_info.dst_addr.port() = htons(s->parent_result.ts_result.port); + s->parent_info.dst_addr.port() = htons(s->parent_result.port); get_ka_info_from_host_db(s, &s->parent_info, &s->client_info, &s->host_db_info); char addrbuf[INET6_ADDRSTRLEN]; @@ -2147,7 +2147,7 @@ HttpTransact::LookupSkipOpenServer(State *s) if (s->current.request_to == PARENT_PROXY) { TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, PPDNSLookup); - } else if (s->parent_result.ts_result.result == PARENT_FAIL) { + } else if (s->parent_result.result == PARENT_FAIL) { handle_parent_died(s); return; } @@ -2831,7 +2831,7 @@ HttpTransact::HandleCacheOpenReadHit(State *s) } // a parent lookup could come back as PARENT_FAIL if in parent.config, go_direct == false and // there are no available parents (all down). - else if (s->current.request_to == HOST_NONE && s->parent_result.ts_result.result == PARENT_FAIL) { + else if (s->current.request_to == HOST_NONE && s->parent_result.result == PARENT_FAIL) { if (is_server_negative_cached(s) && response_returnable == true && is_stale_cache_response_returnable(s) == true) { server_up = false; update_current_info(&s->current, nullptr, UNDEFINED_LOOKUP, 0); @@ -3273,14 +3273,14 @@ HttpTransact::HandleCacheOpenReadMiss(State *s) find_server_and_update_current_info(s); // a parent lookup could come back as PARENT_FAIL if in parent.config go_direct == false and // there are no available parents (all down). - if (s->parent_result.ts_result.result == PARENT_FAIL) { + if (s->parent_result.result == PARENT_FAIL) { handle_parent_died(s); return; } if (!s->current.server->dst_addr.isValid()) { - ink_release_assert(s->parent_result.ts_result.result == PARENT_DIRECT || s->current.request_to == PARENT_PROXY || + ink_release_assert(s->parent_result.result == PARENT_DIRECT || s->current.request_to == PARENT_PROXY || s->http_config_param->no_dns_forward_to_parent != 0); - if (s->parent_result.ts_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { + if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { return CallOSDNSLookup(s); } if (s->current.request_to == PARENT_PROXY) { @@ -3548,7 +3548,7 @@ HttpTransact::handle_response_from_parent(State *s) TxnDebug("http_trans", "[hrfp] connection alive"); s->current.server->connect_result = 0; SET_VIA_STRING(VIA_DETAIL_PP_CONNECT, VIA_DETAIL_PP_SUCCESS); - if (s->parent_result.ts_result.retry) { + if (s->parent_result.retry) { markParentUp(s); } handle_forward_server_connection_open(s); @@ -3585,7 +3585,7 @@ HttpTransact::handle_response_from_parent(State *s) if (s->current.state != OUTBOUND_CONGESTION) { markParentDown(s); } - s->parent_result.ts_result.result = PARENT_FAIL; + s->parent_result.result = PARENT_FAIL; handle_parent_died(s); return; } @@ -3623,7 +3623,7 @@ HttpTransact::handle_response_from_parent(State *s) if (s->current.state == CONNECTION_ERROR) { markParentDown(s); } - s->parent_result.ts_result.result = PARENT_FAIL; + s->parent_result.result = PARENT_FAIL; next_lookup = HOST_NONE; } break; @@ -7451,7 +7451,7 @@ HttpTransact::AuthenticationNeeded(const OverridableHttpConfigParams *p, HTTPHdr void HttpTransact::handle_parent_died(State *s) { - ink_assert(s->parent_result.ts_result.result == PARENT_FAIL); + ink_assert(s->parent_result.result == PARENT_FAIL); if (s->current.state == OUTBOUND_CONGESTION) { build_error_response(s, HTTP_STATUS_SERVICE_UNAVAILABLE, "Next Hop Congested", "congestion#retryAfter"); diff --git a/proxy/http/remap/NextHopConsistentHash.cc b/proxy/http/remap/NextHopConsistentHash.cc index d7b9c276c57..34cc4a6989a 100644 --- a/proxy/http/remap/NextHopConsistentHash.cc +++ b/proxy/http/remap/NextHopConsistentHash.cc @@ -234,36 +234,36 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_INIT; HostStatRec *hst = nullptr; - if (result->ts_result.line_number == -1 && result->ts_result.result == PARENT_UNDEFINED) { + if (result->line_number == -1 && result->result == PARENT_UNDEFINED) { firstcall = true; } if (firstcall) { - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] firstcall, line_number: %d, result: %s", sm_id, result->ts_result.line_number, - ParentResultStr[result->ts_result.result]); - result->ts_result.line_number = NextHopConsistentHash::LineNumberPlaceholder; + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] firstcall, line_number: %d, result: %s", sm_id, result->line_number, + ParentResultStr[result->result]); + result->line_number = NextHopConsistentHash::LineNumberPlaceholder; cur_ring = 0; for (uint32_t i = 0; i < groups; i++) { - result->ts_result.chash_init[i] = false; + result->chash_init[i] = false; wrap_around[i] = false; } } else { - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] not firstcall, line_number: %d, result: %s", sm_id, result->ts_result.line_number, - ParentResultStr[result->ts_result.result]); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] not firstcall, line_number: %d, result: %s", sm_id, result->line_number, + ParentResultStr[result->result]); switch (ring_mode) { case NH_ALTERNATE_RING: if (groups > 1) { - cur_ring = (result->ts_result.last_group + 1) % groups; + cur_ring = (result->last_group + 1) % groups; } else { - cur_ring = result->ts_result.last_group; + cur_ring = result->last_group; } break; case NH_EXHAUST_RING: default: if (!wrapped) { - cur_ring = result->ts_result.last_group; + cur_ring = result->last_group; } else if (groups > 1) { - cur_ring = (result->ts_result.last_group + 1) % groups; + cur_ring = (result->last_group + 1) % groups; } break; } @@ -274,8 +274,8 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) do { // search until we've selected a different parent if !firstcall std::shared_ptr r = rings[cur_ring]; - hostRec = chash_lookup(r, hash_key, &result->ts_result.chashIter[cur_ring], &wrapped, &hash, &result->ts_result.chash_init[cur_ring], - &result->ts_result.mapWrapped[cur_ring], sm_id); + hostRec = chash_lookup(r, hash_key, &result->chashIter[cur_ring], &wrapped, &hash, &result->chash_init[cur_ring], + &result->mapWrapped[cur_ring], sm_id); wrap_around[cur_ring] = wrapped; lookups++; // the 'available' flag is maintained in 'host_groups' and not the hash ring. @@ -283,13 +283,13 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) pRec = host_groups[hostRec->group_index][hostRec->host_index]; if (firstcall) { hst = (pRec) ? pStatus.getHostStatus(pRec->hostname.c_str()) : nullptr; - result->ts_result.first_choice_status = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; + result->first_choice_status = (hst) ? hst->status : TSHostStatus::TS_HOST_STATUS_UP; break; } } else { pRec = nullptr; } - } while (pRec && result->ts_result.hostname && strcmp(pRec->hostname.c_str(), result->ts_result.hostname) == 0); + } while (pRec && result->hostname && strcmp(pRec->hostname.c_str(), result->hostname) == 0); NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Initial parent lookups: %d", sm_id, lookups); @@ -314,10 +314,10 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) // check if the host is retryable. It's retryable if the retry window has elapsed if ((pRec->failedAt + retry_time) < static_cast(_now)) { nextHopRetry = true; - result->ts_result.last_parent = pRec->host_index; - result->ts_result.last_lookup = pRec->group_index; - result->ts_result.retry = nextHopRetry; - result->ts_result.result = PARENT_SPECIFIED; + result->last_parent = pRec->host_index; + result->last_lookup = pRec->group_index; + result->retry = nextHopRetry; + result->result = PARENT_SPECIFIED; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next hop %s is now retryable, marked it available.", sm_id, pRec->hostname.c_str()); break; } @@ -336,8 +336,8 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) break; } std::shared_ptr r = rings[cur_ring]; - hostRec = chash_lookup(r, hash_key, &result->ts_result.chashIter[cur_ring], &wrapped, &hash, &result->ts_result.chash_init[cur_ring], - &result->ts_result.mapWrapped[cur_ring], sm_id); + hostRec = chash_lookup(r, hash_key, &result->chashIter[cur_ring], &wrapped, &hash, &result->chash_init[cur_ring], + &result->mapWrapped[cur_ring], sm_id); wrap_around[cur_ring] = wrapped; lookups++; if (hostRec) { @@ -380,33 +380,33 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) // Validate and return the final result. // ---------------------------------------------------------------------------------------------------- - if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->ts_result.retry)) { - result->ts_result.result = PARENT_SPECIFIED; - result->ts_result.hostname = pRec->hostname.c_str(); - result->ts_result.last_parent = pRec->host_index; - result->ts_result.last_lookup = result->ts_result.last_group = cur_ring; + if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->retry)) { + result->result = PARENT_SPECIFIED; + result->hostname = pRec->hostname.c_str(); + result->last_parent = pRec->host_index; + result->last_lookup = result->last_group = cur_ring; switch (scheme) { case NH_SCHEME_NONE: case NH_SCHEME_HTTP: case NH_SCHEME_HTTPS: - result->ts_result.port = pRec->getPort(scheme); + result->port = pRec->getPort(scheme); break; } - result->ts_result.retry = nextHopRetry; - ink_assert(result->ts_result.hostname != nullptr); - ink_assert(result->ts_result.port != 0); - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->ts_result.result: %s Chosen parent: %s.%d", sm_id, ParentResultStr[result->ts_result.result], - result->ts_result.hostname, result->ts_result.port); + result->retry = nextHopRetry; + ink_assert(result->hostname != nullptr); + ink_assert(result->port != 0); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s Chosen parent: %s.%d", sm_id, ParentResultStr[result->result], + result->hostname, result->port); } else { if (go_direct == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; - result->ts_result.retry = false; - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->ts_result.result: %s set hostname null port 0 retry false", sm_id, ParentResultStr[result->ts_result.result]); + result->hostname = nullptr; + result->port = 0; + result->retry = false; + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, ParentResultStr[result->result]); } return; diff --git a/proxy/http/remap/NextHopHealthStatus.cc b/proxy/http/remap/NextHopHealthStatus.cc index 861d45327a6..45080352132 100644 --- a/proxy/http/remap/NextHopHealthStatus.cc +++ b/proxy/http/remap/NextHopHealthStatus.cc @@ -58,9 +58,9 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txn, const char *hostname, const int // make sure we're called back with a result structure for a parent // that is being retried. if (status == NH_MARK_UP) { - ink_assert(result.ts_result.retry == true); + ink_assert(result.retry == true); } - if (result.ts_result.result != PARENT_SPECIFIED) { + if (result.result != PARENT_SPECIFIED) { return; } @@ -88,19 +88,19 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txn, const char *hostname, const int break; // Mark the host down. case NH_MARK_DOWN: - if (h->failedAt == 0 || result.ts_result.retry == true) { + if (h->failedAt == 0 || result.retry == true) { { // lock guard std::lock_guard guard(h->_mutex); if (h->failedAt == 0) { h->failedAt = _now; - if (result.ts_result.retry == false) { + if (result.retry == false) { new_fail_count = h->failCount = 1; } - } else if (result.ts_result.retry == true) { + } else if (result.retry == true) { h->failedAt = _now; } } // end lock guard - NH_Note("[%" PRId64 "] NextHop %s marked as down %s", sm_id, (result.ts_result.retry) ? "retry" : "initially", h->hostname.c_str()); + NH_Note("[%" PRId64 "] NextHop %s marked as down %s", sm_id, (result.retry) ? "retry" : "initially", h->hostname.c_str()); } else { int old_count = 0; // if the last failure was outside the retry window, set the failcount to 1 and failedAt to now. diff --git a/proxy/http/remap/NextHopRoundRobin.cc b/proxy/http/remap/NextHopRoundRobin.cc index 46782249c71..d360dbef61b 100644 --- a/proxy/http/remap/NextHopRoundRobin.cc +++ b/proxy/http/remap/NextHopRoundRobin.cc @@ -52,7 +52,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) bool firstcall = true; bool parentUp = false; bool parentRetry = false; - bool wrapped = result->ts_result.wrap_around; + bool wrapped = result->wrap_around; std::vector wrap_around(groups, false); uint32_t cur_hst_index = 0; uint32_t cur_grp_index = 0; @@ -63,36 +63,36 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) HostStatus &pStatus = HostStatus::instance(); TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_UP; - if (result->ts_result.line_number != -1 && result->ts_result.result != PARENT_UNDEFINED) { + if (result->line_number != -1 && result->result != PARENT_UNDEFINED) { firstcall = false; } if (firstcall) { - result->ts_result.line_number = NextHopRoundRobin::LineNumberPlaceholder; + result->line_number = NextHopRoundRobin::LineNumberPlaceholder; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] first call , cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, cur_hst_index); switch (policy_type) { case NH_FIRST_LIVE: - result->ts_result.start_parent = cur_hst_index = 0; + result->start_parent = cur_hst_index = 0; cur_grp_index = 0; break; case NH_RR_STRICT: { std::lock_guard lock(_mutex); - cur_hst_index = result->ts_result.start_parent = this->hst_index; + cur_hst_index = result->start_parent = this->hst_index; cur_grp_index = 0; this->hst_index = (this->hst_index + 1) % hst_size; } break; case NH_RR_IP: cur_grp_index = 0; if (request_info.get_client_ip() != nullptr) { - cur_hst_index = result->ts_result.start_parent = ntohl(ats_ip_hash(request_info.get_client_ip())) % hst_size; + cur_hst_index = result->start_parent = ntohl(ats_ip_hash(request_info.get_client_ip())) % hst_size; } else { cur_hst_index = this->hst_index; } break; case NH_RR_LATCHED: cur_grp_index = 0; - cur_hst_index = result->ts_result.start_parent = latched_index; + cur_hst_index = result->start_parent = latched_index; break; default: ink_assert(0); @@ -104,20 +104,20 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next call, cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, cur_hst_index); // Move to next parent due to failure - latched_index = cur_hst_index = (result->ts_result.last_parent + 1) % hst_size; + latched_index = cur_hst_index = (result->last_parent + 1) % hst_size; cur_host = host_groups[cur_grp_index][cur_hst_index]; // Check to see if we have wrapped around - if (static_cast(cur_hst_index) == result->ts_result.start_parent) { + if (static_cast(cur_hst_index) == result->start_parent) { // We've wrapped around so bypass if we can if (go_direct == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; - result->ts_result.wrap_around = true; + result->hostname = nullptr; + result->port = 0; + result->wrap_around = true; return; } } @@ -154,7 +154,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) } else { // if not available, check to see if it can be retried. If so, set the retry flag and temporairly mark it as // available. _now == 0 ? _now = time(nullptr) : _now = now; - if (((result->ts_result.wrap_around) || (cur_host->failedAt + retry_time) < static_cast(_now)) && + if (((result->wrap_around) || (cur_host->failedAt + retry_time) < static_cast(_now)) && host_stat == TS_HOST_STATUS_UP) { // Reuse the parent parentUp = true; @@ -171,15 +171,15 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) // The selected host is available or retryable, return the search result. if (parentUp == true && host_stat != TS_HOST_STATUS_DOWN) { NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] status for %s: %s", sm_id, cur_host->hostname.c_str(), HostStatusNames[host_stat]); - result->ts_result.result = PARENT_SPECIFIED; - result->ts_result.hostname = cur_host->hostname.c_str(); - result->ts_result.port = cur_host->getPort(scheme); - result->ts_result.last_parent = cur_hst_index; - result->ts_result.last_group = cur_grp_index; - result->ts_result.retry = parentRetry; - ink_assert(result->ts_result.hostname != nullptr); - ink_assert(result->ts_result.port != 0); - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Chosen parent = %s.%d", sm_id, result->ts_result.hostname, result->ts_result.port); + result->result = PARENT_SPECIFIED; + result->hostname = cur_host->hostname.c_str(); + result->port = cur_host->getPort(scheme); + result->last_parent = cur_hst_index; + result->last_group = cur_grp_index; + result->retry = parentRetry; + ink_assert(result->hostname != nullptr); + ink_assert(result->port != 0); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] Chosen parent = %s.%d", sm_id, result->hostname, result->port); return; } @@ -187,7 +187,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) if (groups == 1) { latched_index = cur_hst_index = (cur_hst_index + 1) % hst_size; if (start_host == cur_hst_index) { - wrap_around[cur_grp_index] = wrapped = result->ts_result.wrap_around = true; + wrap_around[cur_grp_index] = wrapped = result->wrap_around = true; } } else { // search the fail over groups. if (ring_mode == NH_ALTERNATE_RING) { // use alternating ring mode. @@ -196,7 +196,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) if (cur_grp_index == start_group) { latched_index = cur_hst_index = (cur_hst_index + 1) % hst_size; if (cur_hst_index == start_host) { - wrapped = wrap_around[cur_grp_index] = result->ts_result.wrap_around = true; + wrapped = wrap_around[cur_grp_index] = result->wrap_around = true; } } } else { // use the exhaust ring mode. @@ -205,7 +205,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) wrap_around[cur_grp_index] = true; cur_grp_index = (cur_grp_index + 1) % groups; if (cur_grp_index == start_group) { - wrapped = wrap_around[cur_grp_index] = result->ts_result.wrap_around = true; + wrapped = wrap_around[cur_grp_index] = result->wrap_around = true; } else { start_host = cur_hst_index = 0; } @@ -220,11 +220,11 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) } while (!wrapped); if (go_direct == true) { - result->ts_result.result = PARENT_DIRECT; + result->result = PARENT_DIRECT; } else { - result->ts_result.result = PARENT_FAIL; + result->result = PARENT_FAIL; } - result->ts_result.hostname = nullptr; - result->ts_result.port = 0; + result->hostname = nullptr; + result->port = 0; } diff --git a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc index aec42253155..b7c696ae8b6 100644 --- a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc +++ b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc @@ -96,74 +96,74 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // mark down p1.foo.com. markNextHop looks at the 'result' // and uses the host index there mark down the host selected // from a - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // second request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // mark down p2.foo.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // third request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "s2.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "s2.bar.com") == 0); // mark down s2.bar.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fourth request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10004, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "s1.bar.com") == 0); // mark down s1.bar.com. - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fifth request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10005, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "q1.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "q1.bar.com") == 0); // mark down q1.bar.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // sixth request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10006, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "q2.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "q2.bar.com") == 0); // mark down q2.bar.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // seventh request - reusing the ParentResult from the last request // simulating a failure triggers a search for another parent, not firstcall. build_request(10007, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_DIRECT); - CHECK(result->ts_result.hostname == nullptr); + CHECK(result->result == TSParentResultType::PARENT_DIRECT); + CHECK(result->hostname == nullptr); // sleep and test that q2 is becomes retryable; time_t now = time(nullptr) + 5; @@ -172,8 +172,8 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", // simulating a failure triggers a search for another parent, not firstcall. build_request(10008, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp, now); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "q2.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "q2.bar.com") == 0); // free up request resources. br_destroy(sm); @@ -229,55 +229,55 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co build_request(20001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // mark down p1.foo.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // second request build_request(20002, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // mark down p2.foo.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // third request result->reset(); build_request(20003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "s2.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "s2.bar.com") == 0); // mark down s2.bar.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fourth request result->reset(); build_request(20004, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "s1.bar.com") == 0); // mark down s1.bar.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fifth request result->reset(); build_request(20005, &sm, nullptr, "rabbit.net/asset1", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "q1.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "q1.bar.com") == 0); // sixth request - wait and p1 should now become available time_t now = time(nullptr) + 5; result->reset(); build_request(20006, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp, now); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); } // free up request resources. br_destroy(sm); @@ -329,8 +329,8 @@ SCENARIO("Testing NextHop ignore_self_detect false", "[NextHopConsistentHash]") build_request(10001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_DIRECT); - CHECK(result->ts_result.hostname == nullptr); + CHECK(result->result == TSParentResultType::PARENT_DIRECT); + CHECK(result->hostname == nullptr); br_destroy(sm); } } @@ -380,9 +380,9 @@ SCENARIO("Testing NextHop ignore_self_detect true", "[NextHopConsistentHash]") build_request(10001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); - CHECK(result->ts_result.port == 8000); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "localhost") == 0); + CHECK(result->port == 8000); br_destroy(sm); } } @@ -432,27 +432,27 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); - CHECK(result->ts_result.port == 8000); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "localhost") == 0); + CHECK(result->port == 8000); - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); - CHECK(result->ts_result.port == 8002); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "localhost") == 0); + CHECK(result->port == 8002); - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); build_request(10003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "localhost") == 0); - CHECK(result->ts_result.port == 8004); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "localhost") == 0); + CHECK(result->port == 8004); br_destroy(sm); } } @@ -504,17 +504,17 @@ SCENARIO("Testing NextHopConsistentHash hash_string override", "[NextHopConsiste // We happen to know that 'foo.test' will be first if the hostname is the hash // and foo.test will be first for the hash 'first' and the bar.test hash 'second'. // So, if the hash_string override isn't getting applied, this will fail. - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "bar.test") == 0); - CHECK(result->ts_result.port == 80); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "bar.test") == 0); + CHECK(result->port == 80); - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "foo.test") == 0); - CHECK(result->ts_result.port == 80); + CHECK(strcmp(result->hostname, "foo.test") == 0); + CHECK(result->port == 80); br_destroy(sm); } } @@ -564,70 +564,70 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy build_request(30001, &sm, nullptr, "bunny.net/asset1", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "c2.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "c2.foo.com") == 0); // simulated failure, mark c2 down and retry request - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // second request build_request(30002, &sm, nullptr, "bunny.net.net/asset1", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "c3.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "c3.bar.com") == 0); // mark down c3.bar.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // third request build_request(30003, &sm, nullptr, "bunny.net/asset2", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "c6.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "c6.bar.com") == 0); // just mark it down and retry request - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fourth request build_request(30004, &sm, nullptr, "bunny.net/asset2", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "c1.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "c1.foo.com") == 0); // mark it down - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fifth request - new request build_request(30005, &sm, nullptr, "bunny.net/asset3", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "c4.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "c4.bar.com") == 0); // mark it down and retry - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // sixth request result->reset(); build_request(30006, &sm, nullptr, "bunny.net/asset3", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "c5.bar.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "c5.bar.com") == 0); // mark it down - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // seventh request - new request with all hosts down and go_direct is false. result->reset(); build_request(30007, &sm, nullptr, "bunny.net/asset4", nullptr); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_FAIL); - CHECK(result->ts_result.hostname == nullptr); + CHECK(result->result == TSParentResultType::PARENT_FAIL); + CHECK(result->hostname == nullptr); // eighth request - retry after waiting for the retry window to expire. time_t now = time(nullptr) + 5; result->reset(); build_request(30008, &sm, nullptr, "bunny.net/asset4", nullptr); strategy->findNextHop(txnp, now); - CHECK(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "c2.foo.com") == 0); + CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "c2.foo.com") == 0); } // free up request resources. br_destroy(sm); diff --git a/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc b/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc index ba5464fea56..772003442db 100644 --- a/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc +++ b/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc @@ -78,67 +78,67 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-strict'", "[NextHopR // first request. build_request(10001, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // second request. build_request(10002, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // third request. build_request(10003, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // did not reset result, kept it as last parent selected was p1.fo.com, mark it down and we should only select p2.foo.com - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fourth request, p1 is down should select p2. build_request(10004, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // fifth request, p1 is down should still select p2. build_request(10005, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // mark down p2. - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // fifth request, p1 and p2 are both down, should get s1.bar.com from failover ring. build_request(10006, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); + CHECK(strcmp(result->hostname, "s1.bar.com") == 0); // sixth request, p1 and p2 are still down, should get s1.bar.com from failover ring. build_request(10007, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "s1.bar.com") == 0); + CHECK(strcmp(result->hostname, "s1.bar.com") == 0); // mark down s1. - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // seventh request, p1, p2, s1 are down, should get s2.bar.com from failover ring. build_request(10008, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "s2.bar.com") == 0); + CHECK(strcmp(result->hostname, "s2.bar.com") == 0); // mark down s2. - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // eighth request, p1, p2, s1, s2 are down, should get PARENT_DIRECT as go_direct is true build_request(10009, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->ts_result.result == TSParentResultType::PARENT_DIRECT); + CHECK(result->result == TSParentResultType::PARENT_DIRECT); // check that nextHopExists() returns false when all parents are down. CHECK(strategy->nextHopExists(txnp) == false); @@ -150,15 +150,15 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-strict'", "[NextHopR build_request(10010, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp, now); - REQUIRE(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); + REQUIRE(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // tenth request, p1 should now be retried. build_request(10011, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp, now); - REQUIRE(result->ts_result.result == TSParentResultType::PARENT_SPECIFIED); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + REQUIRE(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); } br_destroy(sm); } @@ -206,22 +206,22 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'first-live'", "[NextHop // first request. build_request(10012, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // second request. build_request(10013, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // mark down p1. - strategy->markNextHop(txnp, result->ts_result.hostname, result->ts_result.port, NH_MARK_DOWN); + strategy->markNextHop(txnp, result->hostname, result->port, NH_MARK_DOWN); // third request. build_request(10014, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p2.foo.com") == 0); + CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // change the request time to trigger a retry. time_t now = (time(nullptr) + 5); @@ -230,7 +230,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'first-live'", "[NextHop build_request(10015, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp, now); - CHECK(strcmp(result->ts_result.hostname, "p1.foo.com") == 0); + CHECK(strcmp(result->hostname, "p1.foo.com") == 0); } br_destroy(sm); } @@ -290,7 +290,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound // memcpy(&rdata.client_ip, &sa1, sizeof(sa1)); build_request(10016, &sm, &sa1, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->hostname, "p4.foo.com") == 0); // call and test parentExists(), this call should not affect // findNextHop round robin strict results. @@ -301,7 +301,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound build_request(10017, &sm, &sa2, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->hostname, "p3.foo.com") == 0); // call and test parentExists(), this call should not affect // findNextHop() round robin strict results @@ -311,7 +311,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound build_request(10018, &sm, &sa2, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->hostname, "p3.foo.com") == 0); // call and test parentExists(), this call should not affect // findNextHop() round robin strict results. @@ -321,7 +321,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-ip'", "[NextHopRound // being selected. build_request(10019, &sm, &sa2, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->hostname, "p4.foo.com") == 0); } } br_destroy(sm); @@ -369,29 +369,29 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'latched'", "[NextHopRou // first request should select p3 build_request(10020, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->hostname, "p3.foo.com") == 0); // second request should select p3 build_request(10021, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->hostname, "p3.foo.com") == 0); // third request, use previous result to simulate a failure, we should now select p4. build_request(10022, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->hostname, "p4.foo.com") == 0); // fourth request we should be latched on p4 build_request(10023, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p4.foo.com") == 0); + CHECK(strcmp(result->hostname, "p4.foo.com") == 0); // fifth request, use previous result to simulate a failure, we should now select p3. build_request(10024, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(strcmp(result->ts_result.hostname, "p3.foo.com") == 0); + CHECK(strcmp(result->hostname, "p3.foo.com") == 0); } br_destroy(sm); } diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 467d3acdb7d..f97988e03e2 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -9938,14 +9938,23 @@ TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int do HostStatus::instance().setHostStatus(hostname, status, down_time, reason); } -TSParentResult* -TSHttpTxnParentResultGet(TSHttpTxn txnp) +void +TSHttpTxnParentResultGet(TSHttpTxn txnp, TSParentResult* result) { HttpSM *sm = reinterpret_cast(txnp); - ParentResult *result = &sm->t_state.parent_result; - return &result->ts_result; + ParentResult *sm_result = &sm->t_state.parent_result; + sm_result->copyTo(result); } +void +TSHttpTxnParentResultSet(TSHttpTxn txnp, TSParentResult* result) +{ + HttpSM *sm = reinterpret_cast(txnp); + ParentResult *sm_result = &sm->t_state.parent_result; + sm_result->copyFrom(result); +} + + namespace { // Function that contains the common logic for TSRemapFrom/ToUrlGet(). From 8441e6b156a19662dc8e1b2de21fcfde3adaf89a Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Mon, 10 Aug 2020 11:01:41 -0600 Subject: [PATCH 03/15] clang-format --- include/ts/nexthop.h | 14 +++---- include/ts/parentresult.h | 2 +- include/ts/ts.h | 12 +++--- .../consistenthash.cc | 31 +++++++------- .../consistenthash.h | 1 + .../consistenthash_config.cc | 15 ++++--- .../consistenthash_config.h | 4 +- .../healthstatus.cc | 10 ++--- .../plugin_consistenthash.cc | 4 +- .../strategy.cc | 16 ++++---- .../strategy.h | 13 +++--- .../nexthop_strategy_consistenthash/util.h | 15 +++---- proxy/ParentSelection.cc | 40 +++++++++---------- proxy/ParentSelection.h | 2 +- proxy/http/HttpTransact.cc | 6 ++- proxy/http/remap/NextHopConsistentHash.cc | 7 ++-- proxy/http/remap/NextHopConsistentHash.h | 2 +- proxy/http/remap/NextHopRoundRobin.cc | 9 ++--- proxy/http/remap/NextHopRoundRobin.h | 4 +- proxy/http/remap/NextHopSelectionStrategy.cc | 11 ++--- proxy/http/remap/NextHopSelectionStrategy.h | 12 +++--- proxy/http/remap/NextHopStrategyFactory.cc | 3 +- proxy/http/remap/NextHopStrategyFactory.h | 2 +- proxy/http/remap/PluginDso.cc | 2 +- proxy/http/remap/PluginFactory.cc | 4 +- proxy/http/remap/RemapConfig.cc | 2 +- proxy/http/remap/RemapPluginInfo.cc | 4 +- proxy/http/remap/RemapPluginInfo.h | 1 + .../unit-tests/test_NextHopConsistentHash.cc | 14 +++---- src/traffic_server/InkAPI.cc | 15 ++++--- 30 files changed, 144 insertions(+), 133 deletions(-) diff --git a/include/ts/nexthop.h b/include/ts/nexthop.h index f1a2d6eb0a4..66c5c49c80d 100644 --- a/include/ts/nexthop.h +++ b/include/ts/nexthop.h @@ -35,15 +35,15 @@ enum NHCmd { NH_MARK_UP, NH_MARK_DOWN }; class TSNextHopSelectionStrategy { public: - TSNextHopSelectionStrategy() {}; - virtual ~TSNextHopSelectionStrategy() {}; + TSNextHopSelectionStrategy(){}; + virtual ~TSNextHopSelectionStrategy(){}; - virtual void findNextHop(TSHttpTxn txnp, time_t now = 0) = 0; + virtual void findNextHop(TSHttpTxn txnp, time_t now = 0) = 0; virtual void markNextHop(TSHttpTxn txnp, const char *hostname, const int port, const NHCmd status, const time_t now = 0) = 0; - virtual bool nextHopExists(TSHttpTxn txnp) = 0; - virtual bool responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) = 0; - virtual bool onFailureMarkParentDown(TSHttpStatus response_code) = 0; + virtual bool nextHopExists(TSHttpTxn txnp) = 0; + virtual bool responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) = 0; + virtual bool onFailureMarkParentDown(TSHttpStatus response_code) = 0; - virtual bool goDirect() = 0; + virtual bool goDirect() = 0; virtual bool parentIsProxy() = 0; }; diff --git a/include/ts/parentresult.h b/include/ts/parentresult.h index a5611147557..20b46d678f9 100644 --- a/include/ts/parentresult.h +++ b/include/ts/parentresult.h @@ -36,7 +36,7 @@ struct TSParentResult { bool retry; TSParentResultType result; bool chash_init[TS_MAX_GROUP_RINGS] = {false}; - TSHostStatus first_choice_status = TSHostStatus::TS_HOST_STATUS_INIT; + TSHostStatus first_choice_status = TSHostStatus::TS_HOST_STATUS_INIT; int line_number; uint32_t last_parent; uint32_t start_parent; diff --git a/include/ts/ts.h b/include/ts/ts.h index 908eafa1557..4c9dae436ee 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -2613,7 +2613,7 @@ tsapi TSReturnCode TSHttpTxnClientStreamPriorityGet(TSHttpTxn txnp, TSHttpPriori /* * Returns whether hostname is this machine, as used for parent and remap self-detection. */ -bool TSHostnameIsSelf(const char* hostname); +bool TSHostnameIsSelf(const char *hostname); /* * Gets the status of hostname in the outparam status, and the status reason in the outparam reason. @@ -2621,7 +2621,7 @@ bool TSHostnameIsSelf(const char* hostname); * If either outparam is null, it will not be set and no error will be returned. * Returns whether the hostname was a parent and existed in the HostStatus. */ -bool TSHostStatusGet(const char *hostname, TSHostStatus* status, unsigned int *reason); +bool TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason); /* * Sets the status of hostname in status, down_time, and reason. @@ -2634,12 +2634,12 @@ struct TSParentResult; /* * Gets the Transaction Parent Result pointer. */ -void TSHttpTxnParentResultGet(TSHttpTxn txnp, struct TSParentResult* result); +void TSHttpTxnParentResultGet(TSHttpTxn txnp, struct TSParentResult *result); /* -* Sets the Transaction Parent Result pointer. -*/ -void TSHttpTxnParentResultSet(TSHttpTxn txnp, struct TSParentResult* result); + * Sets the Transaction Parent Result pointer. + */ +void TSHttpTxnParentResultSet(TSHttpTxn txnp, struct TSParentResult *result); #ifdef __cplusplus } diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index 6e35cadb282..a98d5bf64a7 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -72,9 +72,7 @@ chash_lookup(std::shared_ptr ring, uint64_t hash_key, ATSCons return host_rec; } -NextHopConsistentHash::NextHopConsistentHash(const std::string_view name) - : NextHopSelectionStrategy(name) -{} +NextHopConsistentHash::NextHopConsistentHash(const std::string_view name) : NextHopSelectionStrategy(name) {} NextHopConsistentHash::~NextHopConsistentHash() { @@ -146,7 +144,7 @@ NextHopConsistentHash::Init(const YAML::Node &n) uint64_t NextHopConsistentHash::getHashKey(uint64_t sm_id, TSMBuffer reqp, TSMLoc url, TSMLoc parent_selection_url, ATSHash64 *h) { - int len = 0; + int len = 0; const char *url_string_ref = nullptr; // calculate a hash using the selected config. @@ -224,7 +222,9 @@ NextHopConsistentHash::getHashKey(uint64_t sm_id, TSMBuffer reqp, TSMLoc url, TS return h->get(); } -static void setParentResultErr(TSHttpTxn txnp, TSParentResult *result) { +static void +setParentResultErr(TSHttpTxn txnp, TSParentResult *result) +{ result->hostname = nullptr; result->port = 0; result->retry = false; @@ -240,7 +240,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSParentResult *result = &result_obj; TSHttpTxnParentResultGet(txnp, result); - int64_t sm_id = TSHttpTxnIdGet(txnp); + int64_t sm_id = TSHttpTxnIdGet(txnp); TSMBuffer reqp; // TODO verify doesn't need freed @@ -281,10 +281,10 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) return; } - time_t _now = now; - bool firstcall = false; - bool nextHopRetry = false; - bool wrapped = false; + time_t _now = now; + bool firstcall = false; + bool nextHopRetry = false; + bool wrapped = false; std::vector wrap_around(groups, false); uint32_t cur_ring = 0; // there is a hash ring for each host group uint64_t hash_key = 0; @@ -343,7 +343,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) pRec = host_groups[hostRec->group_index][hostRec->host_index]; if (firstcall) { TSHostStatus hostStatus; - const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, nullptr) : false; + const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, nullptr) : false; result->first_choice_status = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; break; } @@ -361,7 +361,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus hostStatus; unsigned int hostReasons; const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) : false; - host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; + host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble if ((pRec && ignore_self_detect) && (hostExists && hostStatus == TS_HOST_STATUS_DOWN)) { @@ -404,12 +404,12 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) wrap_around[cur_ring] = wrapped; lookups++; if (hostRec) { - pRec = host_groups[hostRec->group_index][hostRec->host_index]; + pRec = host_groups[hostRec->group_index][hostRec->host_index]; TSHostStatus hostStatus; unsigned int hostReasons; const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) : false; - host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; + host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble @@ -475,7 +475,8 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) result->hostname = nullptr; result->port = 0; result->retry = false; - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, ParentResultStr[result->result]); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, + ParentResultStr[result->result]); } TSHttpTxnParentResultSet(txnp, result); diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h index 62c9389687e..668b0b22204 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.h @@ -35,6 +35,7 @@ class NextHopConsistentHash : public NextHopSelectionStrategy { std::vector> rings; uint64_t getHashKey(uint64_t sm_id, TSMBuffer reqp, TSMLoc url, TSMLoc parent_selection_url, ATSHash64 *h); + public: const uint32_t LineNumberPlaceholder = 99999; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc index 8b09d8bb553..89808032538 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc @@ -47,7 +47,8 @@ void loadConfigFile(const std::string fileName, std::stringstream &doc, std::uno // createStrategy creates and initializes a Consistent Hash strategy from the given YAML node. // Caller takes ownership of the returned pointer, and must call delete on it. -TSNextHopSelectionStrategy* createStrategy(const std::string &name, const YAML::Node &node) +TSNextHopSelectionStrategy * +createStrategy(const std::string &name, const YAML::Node &node) { NextHopConsistentHash *st = new NextHopConsistentHash(name); if (!st->Init(node)) { @@ -58,7 +59,8 @@ TSNextHopSelectionStrategy* createStrategy(const std::string &name, const YAML:: // createStrategyFromFile creates a Consistent Hash strategy from the given config file. // Caller takes ownership of the returned pointer, and must call delete on it. -TSNextHopSelectionStrategy* createStrategyFromFile(const char *file, const char *strategyName) +TSNextHopSelectionStrategy * +createStrategyFromFile(const char *file, const char *strategyName) { NH_Debug(NH_DEBUG_TAG, "plugin createStrategyFromFile file '%s' strategy '%s'", file, strategyName); @@ -80,7 +82,7 @@ TSNextHopSelectionStrategy* createStrategyFromFile(const char *file, const char config = YAML::Load(doc); if (config.IsNull()) { NH_Note("No NextHop strategy configs were loaded."); - return nullptr; + return nullptr; } strategies = config["strategies"]; @@ -95,14 +97,15 @@ TSNextHopSelectionStrategy* createStrategyFromFile(const char *file, const char if (name != strategyName) { continue; } - auto policy = strategy["policy"]; + auto policy = strategy["policy"]; if (!policy) { NH_Error("No policy is defined for the strategy named '%s', this strategy will be ignored.", name.c_str()); continue; } - auto policy_value = policy.Scalar(); + auto policy_value = policy.Scalar(); if (policy_value != consistent_hash) { - NH_Error("Strategy named '%s' has unsupported policy '%s', this strategy will be ignored.", strategyName, policy_value.c_str()); + NH_Error("Strategy named '%s' has unsupported policy '%s', this strategy will be ignored.", strategyName, + policy_value.c_str()); return nullptr; } return createStrategy(name, strategy); diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h index caff3e14002..b4e413ac921 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h @@ -22,5 +22,5 @@ #include #include "ts/nexthop.h" -TSNextHopSelectionStrategy* createStrategyFromFile(const char *file, const char *strategyName); -TSNextHopSelectionStrategy* createStrategy(const std::string &name, const YAML::Node &node); +TSNextHopSelectionStrategy *createStrategyFromFile(const char *file, const char *strategyName); +TSNextHopSelectionStrategy *createStrategy(const std::string &name, const YAML::Node &node); diff --git a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc index 85c2f93107d..8e6a1ce1ebd 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc @@ -48,7 +48,7 @@ NextHopHealthStatus::insert(std::vector> &hosts) { for (uint32_t ii = 0; ii < hosts.size(); ii++) { std::shared_ptr h = hosts[ii]; - for(auto protocol = h->protocols.begin(); protocol != h->protocols.end(); ++protocol) { + for (auto protocol = h->protocols.begin(); protocol != h->protocols.end(); ++protocol) { const std::string host_port = h->getHostPort((*protocol)->port); host_map.emplace(std::make_pair(host_port, h)); NH_Debug(NH_DEBUG_TAG, "inserting %s into host_map", host_port.c_str()); @@ -63,17 +63,17 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txnp, const char *hostname, const int TSParentResult result_obj; TSParentResult *result = &result_obj; TSHttpTxnParentResultGet(txnp, result); - const int64_t sm_id = TSHttpTxnIdGet(txnp); + const int64_t sm_id = TSHttpTxnIdGet(txnp); int64_t fail_threshold; // = sm->t_state.txn_conf->parent_fail_threshold; if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_HTTP_PARENT_PROXY_FAIL_THRESHOLD, &fail_threshold) != TS_SUCCESS) { - NH_Error("markNextHop failed to get parent_fail_threshold, cannot mark next hop"); + NH_Error("markNextHop failed to get parent_fail_threshold, cannot mark next hop"); return; } int64_t retry_time; // = sm->t_state.txn_conf->parent_retry_time; if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_HTTP_PARENT_PROXY_RETRY_TIME, &retry_time) != TS_SUCCESS) { - NH_Error("markNextHop failed to get parent_retry_time, cannot mark next hop"); + NH_Error("markNextHop failed to get parent_retry_time, cannot mark next hop"); return; } @@ -89,7 +89,7 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txnp, const char *hostname, const int } const std::string host_port = HostRecord::makeHostPort(hostname, port); - auto iter = host_map.find(host_port); + auto iter = host_map.find(host_port); if (iter == host_map.end()) { NH_Debug(NH_DEBUG_TAG, "[%" PRId64 "] no host named %s found in host_map", sm_id, host_port.c_str()); return; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc index c87cc18d98e..23e1765e269 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc @@ -117,11 +117,11 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char *errbuff, int errbuff NH_Error("too many arguments, %d, only expected config file argument. Ignoring the rest!", argc); } - const char* config_file_path = argv[2]; + const char *config_file_path = argv[2]; NH_Debug(NH_DEBUG_TAG, "%s TSRemapInitStrategy called with path '%s'", PLUGIN_NAME, config_file_path); - TSNextHopSelectionStrategy* strategy = createStrategyFromFile(config_file_path, PLUGIN_NAME); + TSNextHopSelectionStrategy *strategy = createStrategyFromFile(config_file_path, PLUGIN_NAME); if (strategy == nullptr) { NH_Debug(NH_DEBUG_TAG, "%s failed to create strategy.", PLUGIN_NAME); *ih = nullptr; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc index d5890911621..740cd2c8b2a 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc @@ -163,7 +163,7 @@ NextHopSelectionStrategy::Init(const YAML::Node &n) if (groups_node.Type() != YAML::NodeType::Sequence) { throw std::invalid_argument("Invalid groups definition, expected a sequence, '" + strategy_name + "' cannot be loaded."); } else { - uint32_t grp_size = groups_node.size(); + uint32_t grp_size = groups_node.size(); if (grp_size > TS_MAX_GROUP_RINGS) { NH_Note("the groups list exceeds the maximum of %d for the strategy '%s'. Only the first %d groups will be configured.", TS_MAX_GROUP_RINGS, strategy_name.c_str(), TS_MAX_GROUP_RINGS); @@ -189,7 +189,8 @@ NextHopSelectionStrategy::Init(const YAML::Node &n) host_rec->group_index = grp; host_rec->host_index = hst; if (TSHostnameIsSelf(host_rec->hostname.c_str())) { - TSHostStatusSet(host_rec->hostname.c_str(), TSHostStatus::TS_HOST_STATUS_DOWN, 0, (unsigned int)TS_HOST_STATUS_SELF_DETECT); + TSHostStatusSet(host_rec->hostname.c_str(), TSHostStatus::TS_HOST_STATUS_DOWN, 0, + (unsigned int)TS_HOST_STATUS_SELF_DETECT); } hosts_inner.push_back(std::move(host_rec)); num_parents++; @@ -235,14 +236,15 @@ NextHopSelectionStrategy::nextHopExists(TSHttpTxn txnp) } bool -NextHopSelectionStrategy::responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) { - return this->resp_codes.contains(response_code) && - current_retry_attempts < this->max_simple_retries && - current_retry_attempts < this->num_parents; +NextHopSelectionStrategy::responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) +{ + return this->resp_codes.contains(response_code) && current_retry_attempts < this->max_simple_retries && + current_retry_attempts < this->num_parents; } bool -NextHopSelectionStrategy::onFailureMarkParentDown(TSHttpStatus response_code) { +NextHopSelectionStrategy::onFailureMarkParentDown(TSHttpStatus response_code) +{ return static_cast(response_code) >= 500 && static_cast(response_code) <= 599; } diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.h b/plugins/experimental/nexthop_strategy_consistenthash/strategy.h index fef6095909b..5a2e251e432 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/strategy.h +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.h @@ -186,7 +186,7 @@ struct HostRecord : ATSConsistentHashNode { } static std::string - makeHostPort(const std::string& hostname, const int port) + makeHostPort(const std::string &hostname, const int port) { return hostname + ":" + std::to_string(port); } @@ -213,13 +213,14 @@ class NextHopSelectionStrategy : public TSNextHopSelectionStrategy virtual bool onFailureMarkParentDown(TSHttpStatus response_code); virtual bool goDirect(); virtual bool parentIsProxy(); + protected: std::string strategy_name; - bool go_direct = true; - bool parent_is_proxy = true; - bool ignore_self_detect = false; - NHSchemeType scheme = NH_SCHEME_NONE; - NHRingMode ring_mode = NH_ALTERNATE_RING; + bool go_direct = true; + bool parent_is_proxy = true; + bool ignore_self_detect = false; + NHSchemeType scheme = NH_SCHEME_NONE; + NHRingMode ring_mode = NH_ALTERNATE_RING; ResponseCodes resp_codes; HealthChecks health_checks; NextHopHealthStatus passive_health; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/util.h b/plugins/experimental/nexthop_strategy_consistenthash/util.h index 473ef975874..fa050b009bc 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/util.h +++ b/plugins/experimental/nexthop_strategy_consistenthash/util.h @@ -24,12 +24,14 @@ // The parent may be TS_NULL_MLOC. // If mloc is set to TS_NULL_MLOC or never allocated, it will not be freed. struct ScopedFreeMLoc { - ScopedFreeMLoc(TSMBuffer *_buf, TSMLoc _parent, TSMLoc *_mloc) : mloc(_mloc), parent(_parent), buf(_buf) {}; - ~ScopedFreeMLoc(){ + ScopedFreeMLoc(TSMBuffer *_buf, TSMLoc _parent, TSMLoc *_mloc) : mloc(_mloc), parent(_parent), buf(_buf){}; + ~ScopedFreeMLoc() + { if (*mloc != TS_NULL_MLOC) { TSHandleMLocRelease(*buf, parent, *mloc); } }; + private: TSMLoc *mloc; TSMLoc parent; @@ -39,17 +41,16 @@ struct ScopedFreeMLoc { // StrVal is a string as returned by TSUrlStringGet and other TS API functions. // Zeroes on initialization. struct StrVal { - StrVal() : ptr(nullptr), len(0) {}; + StrVal() : ptr(nullptr), len(0){}; char *ptr; int len; }; // ScopedFreeStrVal frees the ptr in the given Strval when it goes out of scope. struct ScopedFreeStrVal { - ScopedFreeStrVal(StrVal *_strval) : strval(_strval) {}; - ~ScopedFreeStrVal(){ - TSfree(strval->ptr); - }; + ScopedFreeStrVal(StrVal *_strval) : strval(_strval){}; + ~ScopedFreeStrVal() { TSfree(strval->ptr); }; + private: StrVal *strval; }; diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc index cd7945ca382..c18531777d7 100644 --- a/proxy/ParentSelection.cc +++ b/proxy/ParentSelection.cc @@ -1890,17 +1890,17 @@ void ParentResult::copyFrom(TSParentResult *r) { this->hostname = r->hostname; - this->port = r->port; - this->retry = r->retry; - this->result = r->result; - memcpy(this->chash_init, r->chash_init, TS_MAX_GROUP_RINGS*sizeof(bool)); + this->port = r->port; + this->retry = r->retry; + this->result = r->result; + memcpy(this->chash_init, r->chash_init, TS_MAX_GROUP_RINGS * sizeof(bool)); this->first_choice_status = r->first_choice_status; - this->line_number = r->line_number; - this->last_parent = r->last_parent; - this->start_parent = r->start_parent; - this->last_group = r->last_group; - this->wrap_around = r->wrap_around; - memcpy(this->mapWrapped, r->mapWrapped, 2*sizeof(bool)); + this->line_number = r->line_number; + this->last_parent = r->last_parent; + this->start_parent = r->start_parent; + this->last_group = r->last_group; + this->wrap_around = r->wrap_around; + memcpy(this->mapWrapped, r->mapWrapped, 2 * sizeof(bool)); this->last_lookup = r->last_lookup; for (int i = 0; i < TS_MAX_GROUP_RINGS; ++i) { this->chashIter[i] = r->chashIter[i]; @@ -1911,17 +1911,17 @@ void ParentResult::copyTo(TSParentResult *r) { r->hostname = this->hostname; - r->port = this->port; - r->retry = this->retry; - r->result = this->result; - memcpy(r->chash_init, this->chash_init, TS_MAX_GROUP_RINGS*sizeof(bool)); + r->port = this->port; + r->retry = this->retry; + r->result = this->result; + memcpy(r->chash_init, this->chash_init, TS_MAX_GROUP_RINGS * sizeof(bool)); r->first_choice_status = this->first_choice_status; - r->line_number = this->line_number; - r->last_parent = this->last_parent; - r->start_parent = this->start_parent; - r->last_group = this->last_group; - r->wrap_around = this->wrap_around; - memcpy(r->mapWrapped, this->mapWrapped, 2*sizeof(bool)); + r->line_number = this->line_number; + r->last_parent = this->last_parent; + r->start_parent = this->start_parent; + r->last_group = this->last_group; + r->wrap_around = this->wrap_around; + memcpy(r->mapWrapped, this->mapWrapped, 2 * sizeof(bool)); r->last_lookup = this->last_lookup; for (int i = 0; i < TS_MAX_GROUP_RINGS; ++i) { r->chashIter[i] = this->chashIter[i]; diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h index 925b86cd1ca..75b1d337739 100644 --- a/proxy/ParentSelection.h +++ b/proxy/ParentSelection.h @@ -173,7 +173,7 @@ struct ParentResult { int port; bool retry; bool chash_init[TS_MAX_GROUP_RINGS] = {false}; - TSHostStatus first_choice_status = TSHostStatus::TS_HOST_STATUS_INIT; + TSHostStatus first_choice_status = TSHostStatus::TS_HOST_STATUS_INIT; void reset() diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index 86c511ded37..2fa9dc130ae 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -196,7 +196,8 @@ markParentDown(HttpTransact::State *s) url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, s->parent_result.port, NH_MARK_DOWN); + return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, + s->parent_result.port, NH_MARK_DOWN); } else if (s->parent_params) { return s->parent_params->markParentDown(&s->parent_result, s->txn_conf->parent_fail_threshold, s->txn_conf->parent_retry_time); } @@ -209,7 +210,8 @@ markParentUp(HttpTransact::State *s) { url_mapping *mp = s->url_map.getMapping(); if (mp && mp->strategy) { - return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, s->parent_result.port, NH_MARK_UP); + return mp->strategy->markNextHop(reinterpret_cast(s->state_machine), s->parent_result.hostname, + s->parent_result.port, NH_MARK_UP); } else if (s->parent_params) { return s->parent_params->markParentUp(&s->parent_result); } diff --git a/proxy/http/remap/NextHopConsistentHash.cc b/proxy/http/remap/NextHopConsistentHash.cc index 34cc4a6989a..dc032c8728e 100644 --- a/proxy/http/remap/NextHopConsistentHash.cc +++ b/proxy/http/remap/NextHopConsistentHash.cc @@ -56,9 +56,7 @@ chash_lookup(const std::shared_ptr &ring, uint64_t hash_key, return host_rec; } -NextHopConsistentHash::NextHopConsistentHash(const std::string_view name) - : NextHopSelectionStrategy(name) -{} +NextHopConsistentHash::NextHopConsistentHash(const std::string_view name) : NextHopSelectionStrategy(name) {} NextHopConsistentHash::~NextHopConsistentHash() { @@ -406,7 +404,8 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) result->hostname = nullptr; result->port = 0; result->retry = false; - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, ParentResultStr[result->result]); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] result->result: %s set hostname null port 0 retry false", sm_id, + ParentResultStr[result->result]); } return; diff --git a/proxy/http/remap/NextHopConsistentHash.h b/proxy/http/remap/NextHopConsistentHash.h index d71854a2854..74e37f9d30d 100644 --- a/proxy/http/remap/NextHopConsistentHash.h +++ b/proxy/http/remap/NextHopConsistentHash.h @@ -48,7 +48,7 @@ class NextHopConsistentHash : public NextHopSelectionStrategy ~NextHopConsistentHash(); bool Init(const YAML::Node &n); void findNextHop(TSHttpTxn txnp, time_t now = 0) override; -//private: + // private: std::vector> rings; uint64_t getHashKey(uint64_t sm_id, HttpRequestData *hrdata, ATSHash64 *h); }; diff --git a/proxy/http/remap/NextHopRoundRobin.cc b/proxy/http/remap/NextHopRoundRobin.cc index d360dbef61b..e84880d1e6d 100644 --- a/proxy/http/remap/NextHopRoundRobin.cc +++ b/proxy/http/remap/NextHopRoundRobin.cc @@ -28,8 +28,7 @@ #include "NextHopRoundRobin.h" NextHopRoundRobin::NextHopRoundRobin(const std::string_view &name, const NHPolicyType &policy) - : NextHopSelectionStrategy(name) - , policy_type(policy) + : NextHopSelectionStrategy(name), policy_type(policy) { NH_Debug(NH_DEBUG_TAG, "Using a selection strategy of type %s", policy_strings[policy]); } @@ -69,8 +68,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) if (firstcall) { result->line_number = NextHopRoundRobin::LineNumberPlaceholder; - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] first call , cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, - cur_hst_index); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] first call , cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, cur_hst_index); switch (policy_type) { case NH_FIRST_LIVE: result->start_parent = cur_hst_index = 0; @@ -101,8 +99,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) cur_host = host_groups[cur_grp_index][cur_hst_index]; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] first call, cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, cur_hst_index); } else { - NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next call, cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, - cur_hst_index); + NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next call, cur_grp_index: %d, cur_hst_index: %d", sm_id, cur_grp_index, cur_hst_index); // Move to next parent due to failure latched_index = cur_hst_index = (result->last_parent + 1) % hst_size; cur_host = host_groups[cur_grp_index][cur_hst_index]; diff --git a/proxy/http/remap/NextHopRoundRobin.h b/proxy/http/remap/NextHopRoundRobin.h index 0caa5fe6774..e3bfffaa317 100644 --- a/proxy/http/remap/NextHopRoundRobin.h +++ b/proxy/http/remap/NextHopRoundRobin.h @@ -40,8 +40,8 @@ class NextHopRoundRobin : public NextHopSelectionStrategy return NextHopSelectionStrategy::Init(n); } void findNextHop(TSHttpTxn txnp, time_t now = 0) override; -//private: + // private: std::mutex _mutex; - uint32_t latched_index = 0; + uint32_t latched_index = 0; NHPolicyType policy_type = NH_UNDEFINED; }; diff --git a/proxy/http/remap/NextHopSelectionStrategy.cc b/proxy/http/remap/NextHopSelectionStrategy.cc index 0b75d193124..e19f42d7258 100644 --- a/proxy/http/remap/NextHopSelectionStrategy.cc +++ b/proxy/http/remap/NextHopSelectionStrategy.cc @@ -214,14 +214,15 @@ NextHopSelectionStrategy::nextHopExists(TSHttpTxn txnp) } bool -NextHopSelectionStrategy::responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) { - return this->resp_codes.contains(static_cast(response_code)) && - current_retry_attempts < this->max_simple_retries && - current_retry_attempts < this->num_parents; +NextHopSelectionStrategy::responseIsRetryable(unsigned int current_retry_attempts, TSHttpStatus response_code) +{ + return this->resp_codes.contains(static_cast(response_code)) && current_retry_attempts < this->max_simple_retries && + current_retry_attempts < this->num_parents; } bool -NextHopSelectionStrategy::onFailureMarkParentDown(TSHttpStatus response_code) { +NextHopSelectionStrategy::onFailureMarkParentDown(TSHttpStatus response_code) +{ return static_cast(response_code) >= 500 && static_cast(response_code) <= 599; } diff --git a/proxy/http/remap/NextHopSelectionStrategy.h b/proxy/http/remap/NextHopSelectionStrategy.h index 39ece2f6dfb..653e05f6484 100644 --- a/proxy/http/remap/NextHopSelectionStrategy.h +++ b/proxy/http/remap/NextHopSelectionStrategy.h @@ -226,13 +226,13 @@ class NextHopSelectionStrategy : public TSNextHopSelectionStrategy virtual bool onFailureMarkParentDown(TSHttpStatus response_code); virtual bool goDirect(); virtual bool parentIsProxy(); -// protected: + // protected: std::string strategy_name; - bool go_direct = true; - bool parent_is_proxy = true; - bool ignore_self_detect = false; - NHSchemeType scheme = NH_SCHEME_NONE; - NHRingMode ring_mode = NH_ALTERNATE_RING; + bool go_direct = true; + bool parent_is_proxy = true; + bool ignore_self_detect = false; + NHSchemeType scheme = NH_SCHEME_NONE; + NHRingMode ring_mode = NH_ALTERNATE_RING; ResponseCodes resp_codes; HealthChecks health_checks; NextHopHealthStatus passive_health; diff --git a/proxy/http/remap/NextHopStrategyFactory.cc b/proxy/http/remap/NextHopStrategyFactory.cc index 202c3f0c50c..1cdfd5443bb 100644 --- a/proxy/http/remap/NextHopStrategyFactory.cc +++ b/proxy/http/remap/NextHopStrategyFactory.cc @@ -166,7 +166,8 @@ NextHopStrategyFactory::strategyInstance(const char *name) * Designed for plugins which want to dynamically add strategies. */ bool -NextHopStrategyFactory::addStrategy(const std::string &name, std::shared_ptr strategy) { +NextHopStrategyFactory::addStrategy(const std::string &name, std::shared_ptr strategy) +{ if (_strategies.find(name) != _strategies.end()) { NH_Error("failed to add strategy '%s' because a strategy with that name already exists", name.c_str()); return false; diff --git a/proxy/http/remap/NextHopStrategyFactory.h b/proxy/http/remap/NextHopStrategyFactory.h index 6865d529b8f..16e015f8ad1 100644 --- a/proxy/http/remap/NextHopStrategyFactory.h +++ b/proxy/http/remap/NextHopStrategyFactory.h @@ -43,7 +43,7 @@ class NextHopStrategyFactory NextHopStrategyFactory(const char *file); ~NextHopStrategyFactory(); std::shared_ptr strategyInstance(const char *name); - bool addStrategy(const std::string& name, std::shared_ptr strategy); + bool addStrategy(const std::string &name, std::shared_ptr strategy); bool strategies_loaded; diff --git a/proxy/http/remap/PluginDso.cc b/proxy/http/remap/PluginDso.cc index 95490a14447..d002a09852f 100644 --- a/proxy/http/remap/PluginDso.cc +++ b/proxy/http/remap/PluginDso.cc @@ -287,7 +287,7 @@ PluginDso::instanceCount() fs::path PluginDso::configPath() const { - return _configPath; + return _configPath; } bool diff --git a/proxy/http/remap/PluginFactory.cc b/proxy/http/remap/PluginFactory.cc index 056134f6987..c86e3ca2760 100644 --- a/proxy/http/remap/PluginFactory.cc +++ b/proxy/http/remap/PluginFactory.cc @@ -82,7 +82,9 @@ RemapPluginInst::getStrategy() return _plugin.initStrategy(this->_instance); } -std::string RemapPluginInst::name() const { +std::string +RemapPluginInst::name() const +{ return _plugin.configPath().string(); } diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc index 1acbcfdae9f..39495bbe24b 100644 --- a/proxy/http/remap/RemapConfig.cc +++ b/proxy/http/remap/RemapConfig.cc @@ -1310,7 +1310,7 @@ remap_parse_config_bti(const char *path, BUILD_TABLE_INFO *bti) continue; // TODO error? } std::shared_ptr strategy = pluginInst->getStrategy(); - const std::string pluginName = pluginInst->name(); + const std::string pluginName = pluginInst->name(); if (strategy != nullptr) { Debug("remap_plugin", "Remap plugin got strategy '%s'", pluginName.c_str()); bti->rewrite->strategyFactory->addStrategy(pluginName, strategy); // will log an error if the name already exists diff --git a/proxy/http/remap/RemapPluginInfo.cc b/proxy/http/remap/RemapPluginInfo.cc index 91cfd990a6e..e30f289ef2e 100644 --- a/proxy/http/remap/RemapPluginInfo.cc +++ b/proxy/http/remap/RemapPluginInfo.cc @@ -274,7 +274,8 @@ RemapPluginInfo::indicatePostReload(TSRemapReloadStatus reloadStatus) } /* Initialize strategy (optional). */ -std::shared_ptr RemapPluginInfo::initStrategy(void *ih) +std::shared_ptr +RemapPluginInfo::initStrategy(void *ih) { if (!init_strategy_cb) { PluginDebug(_tag, "plugin '%s' has no init_strategy_cb, returning nullptr", _configPath.c_str()); @@ -297,7 +298,6 @@ std::shared_ptr RemapPluginInfo::initStrategy(void * return std::shared_ptr(strategy_raw); } - inline void RemapPluginInfo::setPluginContext() { diff --git a/proxy/http/remap/RemapPluginInfo.h b/proxy/http/remap/RemapPluginInfo.h index d7faa95ccf0..1a774e736ad 100644 --- a/proxy/http/remap/RemapPluginInfo.h +++ b/proxy/http/remap/RemapPluginInfo.h @@ -109,6 +109,7 @@ class RemapPluginInfo : public PluginDso /* Used by strategies on initialization, to add plugin-defined strategies for use by remaps */ std::shared_ptr initStrategy(void *ih); + protected: /* Utility to be used only with unit testing */ std::string missingRequiredSymbolError(const std::string &pluginName, const char *required, const char *requiring = nullptr); diff --git a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc index b7c696ae8b6..7a07e564cd1 100644 --- a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc +++ b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc @@ -53,7 +53,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", // load the configuration strtegies. std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); - strategy = nhf.strategyInstance("consistent-hash-1"); + strategy = nhf.strategyInstance("consistent-hash-1"); NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); @@ -194,7 +194,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co { std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); - strategy = nhf.strategyInstance("consistent-hash-1"); + strategy = nhf.strategyInstance("consistent-hash-1"); NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); @@ -298,7 +298,7 @@ SCENARIO("Testing NextHop ignore_self_detect false", "[NextHopConsistentHash]") // load the configuration strtegies. std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); - strategy = nhf.strategyInstance("ignore-self-detect-false"); + strategy = nhf.strategyInstance("ignore-self-detect-false"); NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); @@ -350,7 +350,7 @@ SCENARIO("Testing NextHop ignore_self_detect true", "[NextHopConsistentHash]") // load the configuration strtegies. std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); - strategy = nhf.strategyInstance("ignore-self-detect-true"); + strategy = nhf.strategyInstance("ignore-self-detect-true"); NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); @@ -402,7 +402,7 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne // load the configuration strtegies. std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); - strategy = nhf.strategyInstance("same-host-different-port"); + strategy = nhf.strategyInstance("same-host-different-port"); NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); @@ -472,7 +472,7 @@ SCENARIO("Testing NextHopConsistentHash hash_string override", "[NextHopConsiste // load the configuration strtegies. std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); - strategy = nhf.strategyInstance("hash-string-override"); + strategy = nhf.strategyInstance("hash-string-override"); NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); @@ -533,7 +533,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy { std::shared_ptr strategy; NextHopStrategyFactory nhf(TS_SRC_DIR "unit-tests/consistent-hash-tests.yaml"); - strategy = nhf.strategyInstance("consistent-hash-2"); + strategy = nhf.strategyInstance("consistent-hash-2"); NextHopConsistentHash *ptr = static_cast(strategy.get()); REQUIRE(ptr != nullptr); diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index f97988e03e2..ee99a019613 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -9911,16 +9911,16 @@ TSHttpTxnRedoCacheLookup(TSHttpTxn txnp, const char *url, int length) } bool -TSHostnameIsSelf(const char* hostname) +TSHostnameIsSelf(const char *hostname) { return Machine::instance()->is_self(hostname); } bool -TSHostStatusGet(const char *hostname, TSHostStatus* status, unsigned int *reason) +TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason) { HostStatRec *hst = HostStatus::instance().getHostStatus(hostname); - if (hst == nullptr) { + if (hst == nullptr) { return false; } if (status != nullptr) { @@ -9939,22 +9939,21 @@ TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int do } void -TSHttpTxnParentResultGet(TSHttpTxn txnp, TSParentResult* result) +TSHttpTxnParentResultGet(TSHttpTxn txnp, TSParentResult *result) { - HttpSM *sm = reinterpret_cast(txnp); + HttpSM *sm = reinterpret_cast(txnp); ParentResult *sm_result = &sm->t_state.parent_result; sm_result->copyTo(result); } void -TSHttpTxnParentResultSet(TSHttpTxn txnp, TSParentResult* result) +TSHttpTxnParentResultSet(TSHttpTxn txnp, TSParentResult *result) { - HttpSM *sm = reinterpret_cast(txnp); + HttpSM *sm = reinterpret_cast(txnp); ParentResult *sm_result = &sm->t_state.parent_result; sm_result->copyFrom(result); } - namespace { // Function that contains the common logic for TSRemapFrom/ToUrlGet(). From a247d1be19ecf1866068978097e147a526e97d7a Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Wed, 12 Aug 2020 15:43:27 -0600 Subject: [PATCH 04/15] Change enums to TS prefix, typedef --- include/ts/apidefs.h.in | 14 +- include/ts/ts.h | 16 +- include/{ts => tscpp}/nexthop.h | 0 include/{ts => tscpp}/parentresult.h | 0 iocore/net/Socks.cc | 10 +- .../consistenthash.cc | 16 +- .../healthstatus.cc | 2 +- .../strategy.cc | 2 +- proxy/ParentConsistentHash.cc | 16 +- proxy/ParentRoundRobin.cc | 14 +- proxy/ParentSelection.cc | 210 +++++++++--------- proxy/ParentSelection.h | 6 +- proxy/ParentSelectionStrategy.cc | 8 +- proxy/http/HttpSM.cc | 6 +- proxy/http/HttpTransact.cc | 54 ++--- proxy/http/remap/NextHopConsistentHash.cc | 10 +- proxy/http/remap/NextHopHealthStatus.cc | 2 +- proxy/http/remap/NextHopRoundRobin.cc | 12 +- src/traffic_server/InkAPI.cc | 14 +- 19 files changed, 208 insertions(+), 204 deletions(-) rename include/{ts => tscpp}/nexthop.h (100%) rename include/{ts => tscpp}/parentresult.h (100%) diff --git a/include/ts/apidefs.h.in b/include/ts/apidefs.h.in index 3b35b7edceb..a933e8838e4 100644 --- a/include/ts/apidefs.h.in +++ b/include/ts/apidefs.h.in @@ -1336,13 +1336,13 @@ typedef enum { // size as well, group size is one to one with the number of rings #define TS_MAX_GROUP_RINGS 5 -enum TSParentResultType { - PARENT_UNDEFINED, - PARENT_DIRECT, - PARENT_SPECIFIED, - PARENT_AGENT, - PARENT_FAIL, -}; +typedef enum { + TS_PARENT_UNDEFINED, + TS_PARENT_DIRECT, + TS_PARENT_SPECIFIED, + TS_PARENT_AGENT, + TS_PARENT_FAIL, +} TSParentResultType; /* -------------------------------------------------------------------------- Interface for the UUID APIs. https://www.ietf.org/rfc/rfc4122.txt. */ diff --git a/include/ts/ts.h b/include/ts/ts.h index 4c9dae436ee..bf3dd5ed21a 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -29,7 +29,6 @@ #pragma once -#include #include #ifdef __cplusplus @@ -2611,35 +2610,36 @@ tsapi TSReturnCode TSHttpTxnClientStreamIdGet(TSHttpTxn txnp, uint64_t *stream_i tsapi TSReturnCode TSHttpTxnClientStreamPriorityGet(TSHttpTxn txnp, TSHttpPriority *priority); /* - * Returns whether hostname is this machine, as used for parent and remap self-detection. + * Returns TS_SUCCESS if hostname is this machine, as used for parent and remap self-detection. + * Returns TS_ERROR if hostname is not this machine. */ -bool TSHostnameIsSelf(const char *hostname); +tsapi TSReturnCode TSHostnameIsSelf(const char *hostname); /* * Gets the status of hostname in the outparam status, and the status reason in the outparam reason. * The reason is a logical-and combination of the reasons in TSHostStatusReason. * If either outparam is null, it will not be set and no error will be returned. - * Returns whether the hostname was a parent and existed in the HostStatus. + * Returns TS_SUCCESS if the hostname was a parent and existed in the HostStatus, else TS_ERROR. */ -bool TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason); +tsapi TSReturnCode TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason); /* * Sets the status of hostname in status, down_time, and reason. * The reason is a logical-and combination of the reasons in TSHostStatusReason. */ -void TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int down_time, const unsigned int reason); +tsapi void TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int down_time, const unsigned int reason); struct TSParentResult; /* * Gets the Transaction Parent Result pointer. */ -void TSHttpTxnParentResultGet(TSHttpTxn txnp, struct TSParentResult *result); +tsapi void TSHttpTxnParentResultGet(TSHttpTxn txnp, struct TSParentResult *result); /* * Sets the Transaction Parent Result pointer. */ -void TSHttpTxnParentResultSet(TSHttpTxn txnp, struct TSParentResult *result); +tsapi void TSHttpTxnParentResultSet(TSHttpTxn txnp, struct TSParentResult *result); #ifdef __cplusplus } diff --git a/include/ts/nexthop.h b/include/tscpp/nexthop.h similarity index 100% rename from include/ts/nexthop.h rename to include/tscpp/nexthop.h diff --git a/include/ts/parentresult.h b/include/tscpp/parentresult.h similarity index 100% rename from include/ts/parentresult.h rename to include/tscpp/parentresult.h diff --git a/iocore/net/Socks.cc b/iocore/net/Socks.cc index dbc2a02835a..12bda59f049 100644 --- a/iocore/net/Socks.cc +++ b/iocore/net/Socks.cc @@ -90,7 +90,7 @@ SocksEntry::findServer() #ifdef SOCKS_WITH_TS if (nattempts == 1) { - ink_assert(server_result.result == PARENT_UNDEFINED); + ink_assert(server_result.result == TS_PARENT_UNDEFINED); server_params->findParent(&req_data, &server_result, fail_threshold, retry_time); } else { socks_conf_struct *conf = netProcessor.socks_conf_stuff; @@ -101,14 +101,14 @@ SocksEntry::findServer() server_params->markParentDown(&server_result, fail_threshold, retry_time); if (nattempts > conf->connection_attempts) { - server_result.result = PARENT_FAIL; + server_result.result = TS_PARENT_FAIL; } else { server_params->nextParent(&req_data, &server_result, fail_threshold, retry_time); } } switch (server_result.result) { - case PARENT_SPECIFIED: + case TS_PARENT_SPECIFIED: // Original was inet_addr, but should hostnames work? // ats_ip_pton only supports numeric (because other clients // explicitly want to avoid hostname lookups). @@ -122,8 +122,8 @@ SocksEntry::findServer() default: ink_assert(!"Unexpected event"); // fallthrough - case PARENT_DIRECT: - case PARENT_FAIL: + case TS_PARENT_DIRECT: + case TS_PARENT_FAIL: memset(&server_addr, 0, sizeof(server_addr)); } #else diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index a98d5bf64a7..1ecd152c6ae 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -294,7 +294,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) std::shared_ptr pRec = nullptr; TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_INIT; - if (result->line_number == -1 && result->result == PARENT_UNDEFINED) { + if (result->line_number == -1 && result->result == TS_PARENT_UNDEFINED) { firstcall = true; } @@ -343,7 +343,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) pRec = host_groups[hostRec->group_index][hostRec->host_index]; if (firstcall) { TSHostStatus hostStatus; - const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, nullptr) : false; + const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, nullptr) == TS_SUCCESS) : false; result->first_choice_status = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; break; } @@ -360,7 +360,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus hostStatus; unsigned int hostReasons; - const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) : false; + const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble @@ -380,7 +380,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) result->last_parent = pRec->host_index; result->last_lookup = pRec->group_index; result->retry = nextHopRetry; - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next hop %s is now retryable, marked it available.", sm_id, pRec->hostname.c_str()); break; } @@ -408,7 +408,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus hostStatus; unsigned int hostReasons; - const bool hostExists = pRec ? TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) : false; + const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason @@ -448,7 +448,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) // ---------------------------------------------------------------------------------------------------- if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->retry)) { - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; result->hostname = pRec->hostname.c_str(); result->last_parent = pRec->host_index; result->last_lookup = result->last_group = cur_ring; @@ -468,9 +468,9 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) result->hostname, result->port); } else { if (go_direct == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; result->port = 0; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc index 8e6a1ce1ebd..4167bf0aa1d 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc @@ -84,7 +84,7 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txnp, const char *hostname, const int if (status == NH_MARK_UP) { ink_assert(result->retry == true); } - if (result->result != PARENT_SPECIFIED) { + if (result->result != TS_PARENT_SPECIFIED) { return; } diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc index 740cd2c8b2a..c8170c2999f 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc @@ -188,7 +188,7 @@ NextHopSelectionStrategy::Init(const YAML::Node &n) std::shared_ptr host_rec = std::make_shared(hosts_list[hst].as()); host_rec->group_index = grp; host_rec->host_index = hst; - if (TSHostnameIsSelf(host_rec->hostname.c_str())) { + if (TSHostnameIsSelf(host_rec->hostname.c_str()) == TS_SUCCESS) { TSHostStatusSet(host_rec->hostname.c_str(), TSHostStatus::TS_HOST_STATUS_DOWN, 0, (unsigned int)TS_HOST_STATUS_SELF_DETECT); } diff --git a/proxy/ParentConsistentHash.cc b/proxy/ParentConsistentHash.cc index ab9d11d62c3..580f9067d78 100644 --- a/proxy/ParentConsistentHash.cc +++ b/proxy/ParentConsistentHash.cc @@ -150,9 +150,9 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques // Should only get into this state if we are supposed to go direct. if (parents[PRIMARY] == nullptr && parents[SECONDARY] == nullptr) { if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; result->port = 0; @@ -237,7 +237,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques result->last_parent = pRec->idx; result->last_lookup = last_lookup; result->retry = parentRetry; - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; Debug("parent_select", "Down parent %s is now retryable, marked it available.", pRec->hostname); break; } @@ -324,7 +324,7 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques } } if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->retry)) { - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; result->hostname = pRec->hostname; result->port = pRec->port; result->last_parent = pRec->idx; @@ -335,9 +335,9 @@ ParentConsistentHash::selectParent(bool first_call, ParentResult *result, Reques Debug("parent_select", "Chosen parent: %s.%d", result->hostname, result->port); } else { if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; result->port = 0; @@ -372,8 +372,8 @@ ParentConsistentHash::markParentUp(ParentResult *result) // Make sure that we are being called back with with a // result structure with a parent that is being retried ink_release_assert(result->retry == true); - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { + ink_assert(result->result == TS_PARENT_SPECIFIED); + if (result->result != TS_PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover diff --git a/proxy/ParentRoundRobin.cc b/proxy/ParentRoundRobin.cc index 495bc2507ab..731f644443b 100644 --- a/proxy/ParentRoundRobin.cc +++ b/proxy/ParentRoundRobin.cc @@ -76,9 +76,9 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat ink_assert(result->rec->go_direct == true); // Could not find a parent if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; @@ -122,9 +122,9 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat if (result->rec->go_direct == true) { // Could not find a parent if (result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; result->port = 0; @@ -170,7 +170,7 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat if (parentUp == true && host_stat != TS_HOST_STATUS_DOWN) { Debug("parent_select", "status for %s: %d", parents[cur_index].hostname, host_stat); - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; result->hostname = parents[cur_index].hostname; result->port = parents[cur_index].port; result->last_parent = cur_index; @@ -184,9 +184,9 @@ ParentRoundRobin::selectParent(bool first_call, ParentResult *result, RequestDat } while (static_cast(cur_index) != result->start_parent); if (result->rec->go_direct == true && result->rec->parent_is_proxy == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc index c18531777d7..124e5b46476 100644 --- a/proxy/ParentSelection.cc +++ b/proxy/ParentSelection.cc @@ -109,7 +109,7 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns // Check to see if the parent was set through the // api if (apiParentExists(rdata)) { - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; result->hostname = rdata->api_info->parent_proxy_name; result->port = rdata->api_info->parent_proxy_port; result->rec = extApiRecord; @@ -133,8 +133,8 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns if (defaultPtr != nullptr) { rec = result->rec = defaultPtr; } else { - result->result = PARENT_DIRECT; - Debug("parent_select", "Returning PARENT_DIRECT (no parents were found)"); + result->result = TS_PARENT_DIRECT; + Debug("parent_select", "Returning TS_PARENT_DIRECT (no parents were found)"); return; } } @@ -146,19 +146,19 @@ ParentConfigParams::findParent(HttpRequestData *rdata, ParentResult *result, uns const char *host = rdata->get_host(); switch (result->result) { - case PARENT_UNDEFINED: - Debug("parent_select", "PARENT_UNDEFINED"); + case TS_PARENT_UNDEFINED: + Debug("parent_select", "TS_PARENT_UNDEFINED"); Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->result]); break; - case PARENT_FAIL: + case TS_PARENT_FAIL: Debug("parent_select", "PARENT_FAIL"); break; - case PARENT_DIRECT: + case TS_PARENT_DIRECT: Debug("parent_select", "PARENT_DIRECT"); Debug("parent_select", "Result for %s was %s", host, ParentResultStr[result->result]); break; - case PARENT_SPECIFIED: - Debug("parent_select", "PARENT_SPECIFIED"); + case TS_PARENT_SPECIFIED: + Debug("parent_select", "TS_PARENT_SPECIFIED"); Debug("parent_select", "Result for %s was parent %s:%d", host, result->hostname, result->port); break; default: @@ -177,16 +177,16 @@ ParentConfigParams::nextParent(HttpRequestData *rdata, ParentResult *result, uns // Make sure that we are being called back with a // result structure with a parent - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { - result->result = PARENT_FAIL; + ink_assert(result->result == TS_PARENT_SPECIFIED); + if (result->result != TS_PARENT_SPECIFIED) { + result->result = TS_PARENT_FAIL; return; } // If we were set through the API we currently have not failover // so just return fail if (result->is_api_result()) { Debug("parent_select", "Retry result for %s was %s", rdata->get_host(), ParentResultStr[result->result]); - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; return; } Debug("parent_select", "ParentConfigParams::nextParent(): result->r: %d, tablePtr: %p", result->result, tablePtr); @@ -198,19 +198,19 @@ ParentConfigParams::nextParent(HttpRequestData *rdata, ParentResult *result, uns const char *host = rdata->get_host(); switch (result->result) { - case PARENT_UNDEFINED: - Debug("parent_select", "PARENT_UNDEFINED"); + case TS_PARENT_UNDEFINED: + Debug("parent_select", "TS_PARENT_UNDEFINED"); Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); break; - case PARENT_FAIL: + case TS_PARENT_FAIL: Debug("parent_select", "PARENT_FAIL"); Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); break; - case PARENT_DIRECT: + case TS_PARENT_DIRECT: Debug("parent_select", "PARENT_DIRECT"); Debug("parent_select", "Retry result for %s was %s", host, ParentResultStr[result->result]); break; - case PARENT_SPECIFIED: + case TS_PARENT_SPECIFIED: Debug("parent_select", "Retry result for %s was parent %s:%d", host, result->hostname, result->port); break; default: @@ -814,7 +814,7 @@ ParentRecord::Init(matcher_line *line_info) // is not set in parent.config. Therefore ParentRoundRobin is the default // strategy. If setting go_direct to true, there should be no parent list // in parent.config and ParentRoundRobin::lookup will set parent_result->r - // to PARENT_DIRECT. + // to TS_PARENT_DIRECT. case P_NO_ROUND_ROBIN: case P_STRICT_ROUND_ROBIN: case P_HASH_ROUND_ROBIN: @@ -1122,9 +1122,9 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "fruit_basket.net"); FP; - red += verify(result, PARENT_SPECIFIED, "red", 37412); - orange += verify(result, PARENT_SPECIFIED, "orange", 37412); - yellow += verify(result, PARENT_SPECIFIED, "yellow", 37412); + red += verify(result, TS_PARENT_SPECIFIED, "red", 37412); + orange += verify(result, TS_PARENT_SPECIFIED, "orange", 37412); + yellow += verify(result, TS_PARENT_SPECIFIED, "yellow", 37412); } RE(((red == 7) && (orange == 7) && (yellow == 7)), 1); // Test 2 @@ -1137,10 +1137,10 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "fruit_basket.net"); FP; - g += verify(result, PARENT_SPECIFIED, "green", 4325); - b += verify(result, PARENT_SPECIFIED, "blue", 4325); - i += verify(result, PARENT_SPECIFIED, "indigo", 4325); - v += verify(result, PARENT_SPECIFIED, "violet", 4325); + g += verify(result, TS_PARENT_SPECIFIED, "green", 4325); + b += verify(result, TS_PARENT_SPECIFIED, "blue", 4325); + i += verify(result, TS_PARENT_SPECIFIED, "indigo", 4325); + v += verify(result, TS_PARENT_SPECIFIED, "violet", 4325); } RE((((g == 17) && !b && !i && !v) || (!g && (b == 17) && !i && !v) || (!g && !b && (i == 17) && !v) || (!g && !b && !i && (v == 17))), @@ -1174,19 +1174,19 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "numeric_host", &ip.sa); FP; - RE(verify(result, PARENT_SPECIFIED, "cat", 37) + verify(result, PARENT_SPECIFIED, "dog", 24), 3); + RE(verify(result, TS_PARENT_SPECIFIED, "cat", 37) + verify(result, TS_PARENT_SPECIFIED, "dog", 24), 3); ats_ip_pton(TEST_IP6_ADDR, &ip.sa); ST(4); REINIT; br(request, "numeric_host", &ip.sa); FP; - RE(verify(result, PARENT_SPECIFIED, "zwoop", 37) + verify(result, PARENT_SPECIFIED, "jMCg", 24), 4); + RE(verify(result, TS_PARENT_SPECIFIED, "zwoop", 37) + verify(result, TS_PARENT_SPECIFIED, "jMCg", 24), 4); // Test 5 ST(5); REINIT; br(request, "www.pilot.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "pilot_net", 80), 5); + RE(verify(result, TS_PARENT_SPECIFIED, "pilot_net", 80), 5); // Test 6 ST(6); REINIT; @@ -1194,21 +1194,21 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, const char *snoopy_dog = "http://www.snoopy.com/"; request->hdr->url_set(snoopy_dog, strlen(snoopy_dog)); FP; - RE(verify(result, PARENT_SPECIFIED, "odie", 80) + verify(result, PARENT_SPECIFIED, "garfield", 80), 5); + RE(verify(result, TS_PARENT_SPECIFIED, "odie", 80) + verify(result, TS_PARENT_SPECIFIED, "garfield", 80), 5); // Test 7 ST(7); REINIT; br(request, "a.rabbit.i.am"); FP; - RE(verify(result, PARENT_SPECIFIED, "amy", 80) + verify(result, PARENT_SPECIFIED, "katie", 80) + - verify(result, PARENT_SPECIFIED, "carissa", 771), + RE(verify(result, TS_PARENT_SPECIFIED, "amy", 80) + verify(result, TS_PARENT_SPECIFIED, "katie", 80) + + verify(result, TS_PARENT_SPECIFIED, "carissa", 771), 6); // Test 6+ BUGBUG needs to be fixed // ST(7); REINIT; // br(request, "www.microsoft.net"); - // FP; RE( verify(result,PARENT_SPECIFIED,"zoo.net",341) + - // verify(result,PARENT_SPECIFIED,"zoo.net",347) + - // verify(result,PARENT_SPECIFIED,"zoo.edu",111) ,7); + // FP; RE( verify(result,TS_PARENT_SPECIFIED,"zoo.net",341) + + // verify(result,TS_PARENT_SPECIFIED,"zoo.net",347) + + // verify(result,TS_PARENT_SPECIFIED,"zoo.edu",111) ,7); // Test 6++ BUGBUG needs to be fixed // ST(7); REINIT; // br(request, "snow.imac.net:2020"); @@ -1224,7 +1224,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, // request->hdr->url_set(u); // ink_assert(request->hdr->url_get()->port_get() == 819); // printf("url: %s\n",request->hdr->url_get()->string_get(0)); - // FP; RE(verify(result,PARENT_SPECIFIED,"genie",80),8); + // FP; RE(verify(result,TS_PARENT_SPECIFIED,"genie",80),8); // Test 7 - N Parent Table tbl[0] = '\0'; T("dest_domain=rabbit.net parent=fuzzy:80,fluffy:80,furry:80,frisky:80 round_robin=strict go_direct=true\n"); @@ -1234,7 +1234,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 7); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 7); params->markParentDown(result, fail_threshold, retry_time); // Test 9 @@ -1242,44 +1242,44 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 8); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 8); // Test 10 ST(10); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 9); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 9); // Test 11 ST(11); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 10); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 10); // restart the loop // Test 12 ST(12); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 11); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 11); // Test 13 ST(13); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 12); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 12); // Test 14 ST(14); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 13); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 13); // Test 15 ST(15); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 14); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 14); params->markParentDown(result, fail_threshold, retry_time); // restart the loop @@ -1289,44 +1289,44 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 15); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 15); // Test 17 ST(17); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 16); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 16); // Test 18 ST(18); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 17); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 17); // Test 19 ST(19); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 18); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 18); // restart the loop // Test 20 ST(20); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 19); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 19); // Test 21 ST(21); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 20); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 20); // Test 22 ST(22); REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 21); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 21); params->markParentDown(result, fail_threshold, retry_time); // Test 23 - 32 @@ -1335,7 +1335,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), i); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), i); } params->markParentDown(result, 1, 5); // now they're all down @@ -1346,7 +1346,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_DIRECT, nullptr, 0), i); + RE(verify(result, TS_PARENT_DIRECT, nullptr, 0), i); } // sleep(5); // parents should come back up; they don't @@ -1364,16 +1364,16 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, sleep(1); switch (i % 4) { case 0: - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), i); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), i); break; case 1: - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), i); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), i); break; case 2: - RE(verify(result, PARENT_SPECIFIED, "furry", 80), i); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), i); break; case 3: - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), i); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), i); break; default: ink_assert(0); @@ -1390,7 +1390,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 173); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 173); params->markParentDown(result, fail_threshold, retry_time); // fuzzy is down. // Test 174 @@ -1399,7 +1399,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 174); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 174); params->markParentDown(result, fail_threshold, retry_time); // frisky is down. @@ -1409,7 +1409,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 175); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 175); params->markParentDown(result, fail_threshold, retry_time); // frisky is down. @@ -1419,7 +1419,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 176); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 176); params->markParentDown(result, fail_threshold, retry_time); // all are down now. @@ -1429,7 +1429,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_FAIL, nullptr, 80), 177); + RE(verify(result, TS_PARENT_FAIL, nullptr, 80), 177); // Test 178 tbl[0] = '\0'; @@ -1441,7 +1441,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 178); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 178); params->markParentDown(result, fail_threshold, retry_time); // fuzzy is down @@ -1451,7 +1451,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 179); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 179); params->markParentDown(result, fail_threshold, retry_time); // fluffy is down @@ -1461,7 +1461,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 180); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 180); params->markParentDown(result, fail_threshold, retry_time); // furry is down @@ -1471,7 +1471,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 181); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 181); params->markParentDown(result, fail_threshold, retry_time); // frisky is down and we should be back on fuzzy. @@ -1481,7 +1481,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_FAIL, nullptr, 80), 182); + RE(verify(result, TS_PARENT_FAIL, nullptr, 80), 182); // wait long enough so that fuzzy is retryable. sleep(params->policy.ParentRetryTime - 2); @@ -1492,7 +1492,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 183); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 183); // Test 184 // mark fuzzy down with HostStatus API. @@ -1503,7 +1503,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 184); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 184); // Test 185 // mark fluffy down and expect furry to be chosen @@ -1514,7 +1514,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 185); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 185); // Test 186 // mark furry and frisky down, fuzzy up and expect fuzzy to be chosen @@ -1527,7 +1527,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 186); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 186); // Test 187 // test the HostStatus API with ParentConsistent Hash. @@ -1547,7 +1547,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 187); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 187); // Test 188 // mark fuzzy down and expect fluffy. @@ -1558,7 +1558,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 188); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 188); // Test 189 // mark fuzzy back up and expect fuzzy. @@ -1569,7 +1569,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 189); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 189); // Test 190 // mark fuzzy back down and set the host status down @@ -1585,7 +1585,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 190); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 190); // now set the host status on fuzzy to up and it should now // be retried. @@ -1594,7 +1594,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 191); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 191); // Test 192 tbl[0] = '\0'; @@ -1611,7 +1611,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 192); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 192); // Test 193 // mark fuzzy down and wait for it to become retryable @@ -1624,7 +1624,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 193); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 193); // Test 194 // set the host status for fuzzy back up and since its @@ -1634,7 +1634,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.rabbit.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 194); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 194); // Test 195 // secondary_mode=1 (default) is covered by tests cases 173-177 above @@ -1649,7 +1649,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 195); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 195); params->markParentDown(result, fail_threshold, retry_time); // fuzzy is down. // Test 196 @@ -1658,7 +1658,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 196); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 196); params->markParentDown(result, fail_threshold, retry_time); // fluffy is down. @@ -1668,7 +1668,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 197); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 197); params->markParentDown(result, fail_threshold, retry_time); // frisky is down. @@ -1678,7 +1678,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 198); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 198); params->markParentDown(result, fail_threshold, retry_time); // all are down now. @@ -1688,7 +1688,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_FAIL, nullptr, 80), 199); + RE(verify(result, TS_PARENT_FAIL, nullptr, 80), 199); // Test 200 // secondary_mode=3 is tested here first-choice NOT marked down @@ -1702,7 +1702,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fuzzy", 80), 200); + RE(verify(result, TS_PARENT_SPECIFIED, "fuzzy", 80), 200); params->markParentDown(result, fail_threshold, retry_time); // fuzzy is down. // Test 201 @@ -1711,7 +1711,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 201); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 201); params->markParentDown(result, fail_threshold, retry_time); // fluffy is down. @@ -1721,7 +1721,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 202); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 202); params->markParentDown(result, fail_threshold, retry_time); // frisky is down. @@ -1731,7 +1731,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 203); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 203); params->markParentDown(result, fail_threshold, retry_time); // all are down now. @@ -1741,7 +1741,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_FAIL, nullptr, 80), 204); + RE(verify(result, TS_PARENT_FAIL, nullptr, 80), 204); // Test 205 // secondary_mode=3 is tested here first-choice marked down @@ -1756,7 +1756,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "frisky", 80), 205); + RE(verify(result, TS_PARENT_SPECIFIED, "frisky", 80), 205); params->markParentDown(result, fail_threshold, retry_time); // frisky is down. // Test 206 @@ -1765,7 +1765,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "furry", 80), 206); + RE(verify(result, TS_PARENT_SPECIFIED, "furry", 80), 206); params->markParentDown(result, fail_threshold, retry_time); // furry is down. @@ -1775,7 +1775,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_SPECIFIED, "fluffy", 80), 207); + RE(verify(result, TS_PARENT_SPECIFIED, "fluffy", 80), 207); params->markParentDown(result, fail_threshold, retry_time); // all are down now. @@ -1785,7 +1785,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, br(request, "i.am.rabbit.net"); FP; sleep(1); - RE(verify(result, PARENT_FAIL, nullptr, 80), 208); + RE(verify(result, TS_PARENT_FAIL, nullptr, 80), 208); // Tests 209 through 211 test that host selection is based upon the hash_string @@ -1799,7 +1799,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.stooges.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "larry", 80), 209); + RE(verify(result, TS_PARENT_SPECIFIED, "larry", 80), 209); // Test 210 // fuzzy { curly larry, moe } fluffy @@ -1811,7 +1811,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, REINIT; br(request, "i.am.stooges.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "curly", 80), 210); + RE(verify(result, TS_PARENT_SPECIFIED, "curly", 80), 210); // Test 211 // fuzzy { curly larry, moe } fluffy @@ -1825,7 +1825,7 @@ EXCLUSIVE_REGRESSION_TEST(PARENTSELECTION)(RegressionTest * /* t ATS_UNUSED */, _st.setHostStatus("curly", TS_HOST_STATUS_DOWN, 0, Reason::MANUAL); br(request, "i.am.stooges.net"); FP; - RE(verify(result, PARENT_SPECIFIED, "carol", 80), 211); + RE(verify(result, TS_PARENT_SPECIFIED, "carol", 80), 211); delete request; delete result; @@ -1842,7 +1842,7 @@ verify(ParentResult *r, TSParentResultType e, const char *h, int p) if (is_debug_tag_set("parent_select")) { show_result(r); } - return (r->result != e) ? 0 : ((e != PARENT_SPECIFIED) ? 1 : (strcmp(r->hostname, h) ? 0 : ((r->port == p) ? 1 : 0))); + return (r->result != e) ? 0 : ((e != TS_PARENT_SPECIFIED) ? 1 : (strcmp(r->hostname, h) ? 0 : ((r->port == p) ? 1 : 0))); } // br creates an HttpRequestData object @@ -1865,19 +1865,19 @@ void show_result(ParentResult *p) { switch (p->result) { - case PARENT_UNDEFINED: - printf("result is PARENT_UNDEFINED\n"); + case TS_PARENT_UNDEFINED: + printf("result is TS_PARENT_UNDEFINED\n"); break; - case PARENT_DIRECT: - printf("result is PARENT_DIRECT\n"); + case TS_PARENT_DIRECT: + printf("result is TS_PARENT_DIRECT\n"); break; - case PARENT_SPECIFIED: - printf("result is PARENT_SPECIFIED\n"); + case TS_PARENT_SPECIFIED: + printf("result is TS_PARENT_SPECIFIED\n"); printf("hostname is %s\n", p->hostname); printf("port is %d\n", p->port); break; - case PARENT_FAIL: - printf("result is PARENT_FAIL\n"); + case TS_PARENT_FAIL: + printf("result is TS_PARENT_FAIL\n"); break; default: // Handled here: diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h index 75b1d337739..f26891bf5a5 100644 --- a/proxy/ParentSelection.h +++ b/proxy/ParentSelection.h @@ -180,7 +180,7 @@ struct ParentResult { { ink_zero(*this); line_number = -1; - result = PARENT_UNDEFINED; + result = TS_PARENT_UNDEFINED; mapWrapped[0] = false; mapWrapped[1] = false; } @@ -199,7 +199,7 @@ struct ParentResult { // If we don't have a result, we either haven't done a parent // lookup yet (PARENT_UNDEFINED), or the lookup didn't match // anything (PARENT_DIRECT). - ink_assert(result == PARENT_UNDEFINED || result == PARENT_DIRECT); + ink_assert(result == TS_PARENT_UNDEFINED || result == TS_PARENT_DIRECT); return false; } @@ -267,7 +267,7 @@ struct ParentResult { return false; } else { // Caller should check for a valid result beforehand. - ink_assert(result != PARENT_UNDEFINED); + ink_assert(result != TS_PARENT_UNDEFINED); ink_assert(is_some()); return rec->bypass_ok(); } diff --git a/proxy/ParentSelectionStrategy.cc b/proxy/ParentSelectionStrategy.cc index cf067b41ea3..67a2d102a9e 100644 --- a/proxy/ParentSelectionStrategy.cc +++ b/proxy/ParentSelectionStrategy.cc @@ -32,8 +32,8 @@ ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_ // Make sure that we are being called back with with a // result structure with a parent - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { + ink_assert(result->result == TS_PARENT_SPECIFIED); + if (result->result != TS_PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover @@ -104,8 +104,8 @@ ParentSelectionStrategy::markParentUp(ParentResult *result) // Make sure that we are being called back with with a // result structure with a parent that is being retried ink_release_assert(result->retry == true); - ink_assert(result->result == PARENT_SPECIFIED); - if (result->result != PARENT_SPECIFIED) { + ink_assert(result->result == TS_PARENT_SPECIFIED); + if (result->result != TS_PARENT_SPECIFIED) { return; } // If we were set through the API we currently have not failover diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 6991b95c8ef..a50a80e083c 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -7411,7 +7411,7 @@ HttpSM::set_next_state() call_transact_and_set_next_state(nullptr); break; } else if (t_state.http_config_param->use_client_target_addr == 2 && !t_state.url_remap_success && - t_state.parent_result.result != PARENT_SPECIFIED && t_state.client_info.is_transparent && + t_state.parent_result.result != TS_PARENT_SPECIFIED && t_state.client_info.is_transparent && t_state.dns_info.os_addr_style == HttpTransact::DNSLookupInfo::OS_Addr::OS_ADDR_TRY_DEFAULT && ats_is_ip(addr = ua_txn->get_netvc()->get_local_addr())) { /* If the connection is client side transparent and the URL @@ -7440,14 +7440,14 @@ HttpSM::set_next_state() t_state.dns_info.os_addr_style = HttpTransact::DNSLookupInfo::OS_Addr::OS_ADDR_TRY_CLIENT; call_transact_and_set_next_state(nullptr); break; - } else if (t_state.parent_result.result == PARENT_UNDEFINED && t_state.dns_info.lookup_success) { + } else if (t_state.parent_result.result == TS_PARENT_UNDEFINED && t_state.dns_info.lookup_success) { // Already set, and we don't have a parent proxy to lookup ink_assert(ats_is_ip(t_state.host_db_info.ip())); SMDebug("dns", "[HttpTransact::HandleRequest] Skipping DNS lookup, provided by plugin"); call_transact_and_set_next_state(nullptr); break; } else if (t_state.dns_info.looking_up == HttpTransact::ORIGIN_SERVER && t_state.http_config_param->no_dns_forward_to_parent && - t_state.parent_result.result != PARENT_UNDEFINED) { + t_state.parent_result.result != TS_PARENT_UNDEFINED) { t_state.dns_info.lookup_success = true; call_transact_and_set_next_state(nullptr); break; diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index 2fa9dc130ae..ecf1781fbec 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -535,16 +535,16 @@ find_server_and_update_current_info(HttpTransact::State *s) // I just wanted to do this for cop heartbeats, someone else // wanted it for all requests to local_host. TxnDebug("http_trans", "request is from localhost, so bypass parent"); - s->parent_result.result = PARENT_DIRECT; + s->parent_result.result = TS_PARENT_DIRECT; } else if (s->method == HTTP_WKSIDX_CONNECT && s->http_config_param->disable_ssl_parenting) { - if (s->parent_result.result == PARENT_SPECIFIED) { + if (s->parent_result.result == TS_PARENT_SPECIFIED) { nextParent(s); } else { findParent(s); } if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) { TxnDebug("http_trans", "request not cacheable, so bypass parent"); - s->parent_result.result = PARENT_DIRECT; + s->parent_result.result = TS_PARENT_DIRECT; } } else if (s->txn_conf->uncacheable_requests_bypass_parent && s->http_config_param->no_dns_forward_to_parent == 0 && !HttpTransact::is_request_cache_lookupable(s)) { @@ -554,33 +554,33 @@ find_server_and_update_current_info(HttpTransact::State *s) // we are assuming both child and parent have similar configuration // with respect to whether a request is cacheable or not. // For example, the cache_urls_that_look_dynamic variable. - if (s->parent_result.result == PARENT_SPECIFIED) { + if (s->parent_result.result == TS_PARENT_SPECIFIED) { nextParent(s); } else { findParent(s); } if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) { TxnDebug("http_trans", "request not cacheable, so bypass parent"); - s->parent_result.result = PARENT_DIRECT; + s->parent_result.result = TS_PARENT_DIRECT; } } else { switch (s->parent_result.result) { - case PARENT_UNDEFINED: + case TS_PARENT_UNDEFINED: findParent(s); break; - case PARENT_SPECIFIED: + case TS_PARENT_SPECIFIED: nextParent(s); // Hack! // We already have a parent that failed, if we are now told // to go the origin server, we can only obey this if we // dns'ed the origin server - if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 0) { + if (s->parent_result.result == TS_PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 0) { ink_assert(!s->server_info.dst_addr.isValid()); - s->parent_result.result = PARENT_FAIL; + s->parent_result.result = TS_PARENT_FAIL; } break; - case PARENT_FAIL: + case TS_PARENT_FAIL: // Check to see if should bypass the parent and go direct // We can only do this if // 1) the config permitted us to dns the origin server @@ -588,13 +588,13 @@ find_server_and_update_current_info(HttpTransact::State *s) // 3) the parent was not set from API if (s->http_config_param->no_dns_forward_to_parent == 0 && bypass_ok(s) && parent_is_proxy(s) && !s->parent_params->apiParentExists(&s->request_data)) { - s->parent_result.result = PARENT_DIRECT; + s->parent_result.result = TS_PARENT_DIRECT; } break; default: ink_assert(0); // FALL THROUGH - case PARENT_DIRECT: + case TS_PARENT_DIRECT: // // if we have already decided to go direct // // dont bother calling nextParent. // // do nothing here, guy. @@ -603,7 +603,7 @@ find_server_and_update_current_info(HttpTransact::State *s) } switch (s->parent_result.result) { - case PARENT_SPECIFIED: + case TS_PARENT_SPECIFIED: s->parent_info.name = s->arena.str_store(s->parent_result.hostname, strlen(s->parent_result.hostname)); update_current_info(&s->current, &s->parent_info, HttpTransact::PARENT_PROXY, (s->current.attempts)++); update_dns_info(&s->dns_info, &s->current); @@ -611,17 +611,17 @@ find_server_and_update_current_info(HttpTransact::State *s) s->next_hop_scheme = URL_WKSIDX_HTTP; return HttpTransact::PARENT_PROXY; - case PARENT_FAIL: + case TS_PARENT_FAIL: // No more parents - need to return an error message s->current.request_to = HttpTransact::HOST_NONE; return HttpTransact::HOST_NONE; - case PARENT_DIRECT: + case TS_PARENT_DIRECT: // if the configuration does not allow the origin to be dns'd // we're unable to go direct to the origin. if (s->http_config_param->no_dns_forward_to_parent) { Warning("no available parents and the config proxy.config.http.no_dns_just_forward_to_parent, prevents origin lookups."); - s->parent_result.result = PARENT_FAIL; + s->parent_result.result = TS_PARENT_FAIL; return HttpTransact::HOST_NONE; } /* fall through */ @@ -1733,7 +1733,7 @@ HttpTransact::PPDNSLookup(State *s) if (!s->current.server->dst_addr.isValid()) { if (s->current.request_to == PARENT_PROXY) { TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, PPDNSLookup); - } else if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { + } else if (s->parent_result.result == TS_PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { // We ran out of parents but parent configuration allows us to go to Origin Server directly return CallOSDNSLookup(s); } else { @@ -2149,7 +2149,7 @@ HttpTransact::LookupSkipOpenServer(State *s) if (s->current.request_to == PARENT_PROXY) { TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, PPDNSLookup); - } else if (s->parent_result.result == PARENT_FAIL) { + } else if (s->parent_result.result == TS_PARENT_FAIL) { handle_parent_died(s); return; } @@ -2831,9 +2831,9 @@ HttpTransact::HandleCacheOpenReadHit(State *s) update_current_info(&s->current, nullptr, UNDEFINED_LOOKUP, 0); TxnDebug("http_trans", "CacheOpenReadHit - server_down, returning stale document"); } - // a parent lookup could come back as PARENT_FAIL if in parent.config, go_direct == false and + // a parent lookup could come back as TS_PARENT_FAIL if in parent.config, go_direct == false and // there are no available parents (all down). - else if (s->current.request_to == HOST_NONE && s->parent_result.result == PARENT_FAIL) { + else if (s->current.request_to == HOST_NONE && s->parent_result.result == TS_PARENT_FAIL) { if (is_server_negative_cached(s) && response_returnable == true && is_stale_cache_response_returnable(s) == true) { server_up = false; update_current_info(&s->current, nullptr, UNDEFINED_LOOKUP, 0); @@ -3273,16 +3273,16 @@ HttpTransact::HandleCacheOpenReadMiss(State *s) get_ka_info_from_config(s, &s->server_info); } find_server_and_update_current_info(s); - // a parent lookup could come back as PARENT_FAIL if in parent.config go_direct == false and + // a parent lookup could come back as TS_PARENT_FAIL if in parent.config go_direct == false and // there are no available parents (all down). - if (s->parent_result.result == PARENT_FAIL) { + if (s->parent_result.result == TS_PARENT_FAIL) { handle_parent_died(s); return; } if (!s->current.server->dst_addr.isValid()) { - ink_release_assert(s->parent_result.result == PARENT_DIRECT || s->current.request_to == PARENT_PROXY || + ink_release_assert(s->parent_result.result == TS_PARENT_DIRECT || s->current.request_to == PARENT_PROXY || s->http_config_param->no_dns_forward_to_parent != 0); - if (s->parent_result.result == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { + if (s->parent_result.result == TS_PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 1) { return CallOSDNSLookup(s); } if (s->current.request_to == PARENT_PROXY) { @@ -3587,7 +3587,7 @@ HttpTransact::handle_response_from_parent(State *s) if (s->current.state != OUTBOUND_CONGESTION) { markParentDown(s); } - s->parent_result.result = PARENT_FAIL; + s->parent_result.result = TS_PARENT_FAIL; handle_parent_died(s); return; } @@ -3625,7 +3625,7 @@ HttpTransact::handle_response_from_parent(State *s) if (s->current.state == CONNECTION_ERROR) { markParentDown(s); } - s->parent_result.result = PARENT_FAIL; + s->parent_result.result = TS_PARENT_FAIL; next_lookup = HOST_NONE; } break; @@ -7453,7 +7453,7 @@ HttpTransact::AuthenticationNeeded(const OverridableHttpConfigParams *p, HTTPHdr void HttpTransact::handle_parent_died(State *s) { - ink_assert(s->parent_result.result == PARENT_FAIL); + ink_assert(s->parent_result.result == TS_PARENT_FAIL); if (s->current.state == OUTBOUND_CONGESTION) { build_error_response(s, HTTP_STATUS_SERVICE_UNAVAILABLE, "Next Hop Congested", "congestion#retryAfter"); diff --git a/proxy/http/remap/NextHopConsistentHash.cc b/proxy/http/remap/NextHopConsistentHash.cc index dc032c8728e..444425c02f7 100644 --- a/proxy/http/remap/NextHopConsistentHash.cc +++ b/proxy/http/remap/NextHopConsistentHash.cc @@ -232,7 +232,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_INIT; HostStatRec *hst = nullptr; - if (result->line_number == -1 && result->result == PARENT_UNDEFINED) { + if (result->line_number == -1 && result->result == TS_PARENT_UNDEFINED) { firstcall = true; } @@ -315,7 +315,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) result->last_parent = pRec->host_index; result->last_lookup = pRec->group_index; result->retry = nextHopRetry; - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] next hop %s is now retryable, marked it available.", sm_id, pRec->hostname.c_str()); break; } @@ -379,7 +379,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) // ---------------------------------------------------------------------------------------------------- if (pRec && host_stat == TS_HOST_STATUS_UP && (pRec->available || result->retry)) { - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; result->hostname = pRec->hostname.c_str(); result->last_parent = pRec->host_index; result->last_lookup = result->last_group = cur_ring; @@ -397,9 +397,9 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) result->hostname, result->port); } else { if (go_direct == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; result->port = 0; diff --git a/proxy/http/remap/NextHopHealthStatus.cc b/proxy/http/remap/NextHopHealthStatus.cc index 45080352132..75f02898e4b 100644 --- a/proxy/http/remap/NextHopHealthStatus.cc +++ b/proxy/http/remap/NextHopHealthStatus.cc @@ -60,7 +60,7 @@ NextHopHealthStatus::markNextHop(TSHttpTxn txn, const char *hostname, const int if (status == NH_MARK_UP) { ink_assert(result.retry == true); } - if (result.result != PARENT_SPECIFIED) { + if (result.result != TS_PARENT_SPECIFIED) { return; } diff --git a/proxy/http/remap/NextHopRoundRobin.cc b/proxy/http/remap/NextHopRoundRobin.cc index e84880d1e6d..35dca028417 100644 --- a/proxy/http/remap/NextHopRoundRobin.cc +++ b/proxy/http/remap/NextHopRoundRobin.cc @@ -62,7 +62,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) HostStatus &pStatus = HostStatus::instance(); TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_UP; - if (result->line_number != -1 && result->result != PARENT_UNDEFINED) { + if (result->line_number != -1 && result->result != TS_PARENT_UNDEFINED) { firstcall = false; } @@ -108,9 +108,9 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) if (static_cast(cur_hst_index) == result->start_parent) { // We've wrapped around so bypass if we can if (go_direct == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; result->port = 0; @@ -168,7 +168,7 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) // The selected host is available or retryable, return the search result. if (parentUp == true && host_stat != TS_HOST_STATUS_DOWN) { NH_Debug(NH_DEBUG_TAG, "[%" PRIu64 "] status for %s: %s", sm_id, cur_host->hostname.c_str(), HostStatusNames[host_stat]); - result->result = PARENT_SPECIFIED; + result->result = TS_PARENT_SPECIFIED; result->hostname = cur_host->hostname.c_str(); result->port = cur_host->getPort(scheme); result->last_parent = cur_hst_index; @@ -217,9 +217,9 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, time_t now) } while (!wrapped); if (go_direct == true) { - result->result = PARENT_DIRECT; + result->result = TS_PARENT_DIRECT; } else { - result->result = PARENT_FAIL; + result->result = TS_PARENT_FAIL; } result->hostname = nullptr; diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index ee99a019613..53e1f98a962 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -9910,18 +9910,22 @@ TSHttpTxnRedoCacheLookup(TSHttpTxn txnp, const char *url, int length) return TS_ERROR; } -bool +TSReturnCode TSHostnameIsSelf(const char *hostname) { - return Machine::instance()->is_self(hostname); + const bool isSelf = Machine::instance()->is_self(hostname); + if (isSelf) { + return TS_SUCCESS; + } + return TS_ERROR; } -bool +TSReturnCode TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason) { HostStatRec *hst = HostStatus::instance().getHostStatus(hostname); if (hst == nullptr) { - return false; + return TS_ERROR; } if (status != nullptr) { *status = hst->status; @@ -9929,7 +9933,7 @@ TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason if (reason != nullptr) { *reason = hst->reasons; } - return true; + return TS_SUCCESS; } void From 830be98ddd17366f317a4959e7324d9cf47d7e7d Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Wed, 12 Aug 2020 22:23:03 -0600 Subject: [PATCH 05/15] Move API C++ files to include/tscpp --- include/tscpp/{ => api}/nexthop.h | 0 include/tscpp/{ => api}/parentresult.h | 6 +----- .../nexthop_strategy_consistenthash/consistenthash.cc | 4 ++-- .../consistenthash_config.cc | 4 ++-- .../nexthop_strategy_consistenthash/consistenthash_config.h | 2 +- .../nexthop_strategy_consistenthash/healthstatus.cc | 4 ++-- .../nexthop_strategy_consistenthash/healthstatus.h | 2 +- .../plugin_consistenthash.cc | 4 ++-- .../nexthop_strategy_consistenthash/strategy.cc | 4 ++-- .../experimental/nexthop_strategy_consistenthash/strategy.h | 2 +- proxy/ParentSelection.cc | 2 ++ proxy/ParentSelection.h | 2 +- proxy/http/HttpTransact.cc | 2 +- proxy/http/remap/NextHopSelectionStrategy.h | 2 +- src/traffic_server/InkAPI.cc | 2 +- 15 files changed, 20 insertions(+), 22 deletions(-) rename include/tscpp/{ => api}/nexthop.h (100%) rename include/tscpp/{ => api}/parentresult.h (82%) diff --git a/include/tscpp/nexthop.h b/include/tscpp/api/nexthop.h similarity index 100% rename from include/tscpp/nexthop.h rename to include/tscpp/api/nexthop.h diff --git a/include/tscpp/parentresult.h b/include/tscpp/api/parentresult.h similarity index 82% rename from include/tscpp/parentresult.h rename to include/tscpp/api/parentresult.h index 20b46d678f9..95a1cfbe240 100644 --- a/include/tscpp/parentresult.h +++ b/include/tscpp/api/parentresult.h @@ -24,11 +24,7 @@ #include "ts/apidefs.h" #include "tscore/ConsistentHash.h" -// Needed by core. Disabling the warning for plugins -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -static const char *ParentResultStr[] = {"PARENT_UNDEFINED", "PARENT_DIRECT", "PARENT_SPECIFIED", "PARENT_AGENT", "PARENT_FAIL"}; -#pragma GCC diagnostic pop +extern const char *ParentResultStr[]; struct TSParentResult { const char *hostname; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index 1ecd152c6ae..4d45043aeb9 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -40,8 +40,8 @@ #include "tscore/ink_assert.h" #include "ts/ts.h" #include "ts/remap.h" -#include "ts/nexthop.h" -#include "ts/parentresult.h" +#include "tscpp/api/nexthop.h" +#include "tscpp/api/parentresult.h" // hash_key strings. constexpr std::string_view hash_key_url = "url"; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc index 89808032538..0a0818e0340 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.cc @@ -40,8 +40,8 @@ #include "tscore/ink_assert.h" #include "ts/ts.h" #include "ts/remap.h" -#include "ts/nexthop.h" -#include "ts/parentresult.h" +#include "tscpp/api/nexthop.h" +#include "tscpp/api/parentresult.h" void loadConfigFile(const std::string fileName, std::stringstream &doc, std::unordered_set &include_once); diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h index b4e413ac921..953112fe142 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash_config.h @@ -20,7 +20,7 @@ #include #include -#include "ts/nexthop.h" +#include "tscpp/api/nexthop.h" TSNextHopSelectionStrategy *createStrategyFromFile(const char *file, const char *strategyName); TSNextHopSelectionStrategy *createStrategy(const std::string &name, const YAML::Node &node); diff --git a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc index 4167bf0aa1d..2c56386d380 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.cc @@ -40,8 +40,8 @@ #include "tscore/ink_assert.h" #include "ts/ts.h" #include "ts/remap.h" -#include "ts/nexthop.h" -#include "ts/parentresult.h" +#include "tscpp/api/nexthop.h" +#include "tscpp/api/parentresult.h" void NextHopHealthStatus::insert(std::vector> &hosts) diff --git a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h index 18bb07d2393..eb221ec63d7 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h +++ b/plugins/experimental/nexthop_strategy_consistenthash/healthstatus.h @@ -23,7 +23,7 @@ #include #include #include -#include "ts/nexthop.h" +#include "tscpp/api/nexthop.h" struct HostRecord; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc index 23e1765e269..581d5c7ab00 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/plugin_consistenthash.cc @@ -41,8 +41,8 @@ #include "tscore/ink_assert.h" #include "ts/ts.h" #include "ts/remap.h" -#include "ts/nexthop.h" -#include "ts/parentresult.h" +#include "tscpp/api/nexthop.h" +#include "tscpp/api/parentresult.h" void TSRemapDeleteInstance(void *ih) diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc index c8170c2999f..e92ae8f1e65 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc @@ -40,8 +40,8 @@ #include "tscore/ink_assert.h" #include "ts/ts.h" #include "ts/remap.h" -#include "ts/nexthop.h" -#include "ts/parentresult.h" +#include "tscpp/api/nexthop.h" +#include "tscpp/api/parentresult.h" // // NextHopSelectionStrategy.cc diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.h b/plugins/experimental/nexthop_strategy_consistenthash/strategy.h index 5a2e251e432..c572212dbc7 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/strategy.h +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.h @@ -29,7 +29,7 @@ #include #include "tscore/ConsistentHash.h" #include "ts/ts.h" -#include "ts/nexthop.h" +#include "tscpp/api/nexthop.h" #include "ts/remap.h" #include "healthstatus.h" diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc index 124e5b46476..ce6a0573c8a 100644 --- a/proxy/ParentSelection.cc +++ b/proxy/ParentSelection.cc @@ -48,6 +48,8 @@ static const char *default_var = "proxy.config.http.parent_proxies"; static const char *retry_var = "proxy.config.http.parent_proxy.retry_time"; static const char *threshold_var = "proxy.config.http.parent_proxy.fail_threshold"; +const char *ParentResultStr[] = {"PARENT_UNDEFINED", "PARENT_DIRECT", "PARENT_SPECIFIED", "PARENT_AGENT", "PARENT_FAIL"}; + // // Config Callback Prototypes // diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h index f26891bf5a5..a0d12da3cbb 100644 --- a/proxy/ParentSelection.h +++ b/proxy/ParentSelection.h @@ -37,7 +37,7 @@ #include "tscore/ConsistentHash.h" #include "tscore/Tokenizer.h" #include "tscore/ink_apidefs.h" -#include "ts/parentresult.h" +#include "tscpp/api/parentresult.h" #include "HostStatus.h" #include diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index ecf1781fbec..fd9b90445df 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -21,7 +21,7 @@ limitations under the License. */ -#include "ts/nexthop.h" +#include "tscpp/api/nexthop.h" #include "tscore/ink_platform.h" #include diff --git a/proxy/http/remap/NextHopSelectionStrategy.h b/proxy/http/remap/NextHopSelectionStrategy.h index 653e05f6484..9fd100af9f8 100644 --- a/proxy/http/remap/NextHopSelectionStrategy.h +++ b/proxy/http/remap/NextHopSelectionStrategy.h @@ -23,7 +23,7 @@ #pragma once -#include "ts/nexthop.h" +#include "tscpp/api/nexthop.h" #include "ParentSelection.h" #ifndef _NH_UNIT_TESTS_ diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 53e1f98a962..a30793a84bf 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -74,7 +74,7 @@ #include "I_Machine.h" #include "HttpProxyServerMain.h" #include "shared/overridable_txn_vars.h" -#include "ts/parentresult.h" +#include "tscpp/api/parentresult.h" #include "ts/ts.h" From 387f2d249aa20cfdaf0d1f6816a1b8255e0b3984 Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Wed, 12 Aug 2020 23:26:47 -0600 Subject: [PATCH 06/15] Fix NextHop unit tests --- .../remap/unit-tests/nexthop_test_stubs.cc | 2 + .../unit-tests/test_NextHopConsistentHash.cc | 56 +++++++++---------- .../unit-tests/test_NextHopRoundRobin.cc | 6 +- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/proxy/http/remap/unit-tests/nexthop_test_stubs.cc b/proxy/http/remap/unit-tests/nexthop_test_stubs.cc index f83217c24cc..f98387fb9dd 100644 --- a/proxy/http/remap/unit-tests/nexthop_test_stubs.cc +++ b/proxy/http/remap/unit-tests/nexthop_test_stubs.cc @@ -30,6 +30,8 @@ #include "HttpSM.h" #include "nexthop_test_stubs.h" +const char *ParentResultStr[] = {"PARENT_UNDEFINED", "PARENT_DIRECT", "PARENT_SPECIFIED", "PARENT_AGENT", "PARENT_FAIL"}; + HttpSM::HttpSM() : Continuation(nullptr), vc_table(this) {} void HttpSM::cleanup() diff --git a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc index 7a07e564cd1..977fc3e5135 100644 --- a/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc +++ b/proxy/http/remap/unit-tests/test_NextHopConsistentHash.cc @@ -96,7 +96,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // mark down p1.foo.com. markNextHop looks at the 'result' @@ -109,7 +109,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // mark down p2.foo.com @@ -120,7 +120,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", build_request(10003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "s2.bar.com") == 0); // mark down s2.bar.com @@ -131,7 +131,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", build_request(10004, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "s1.bar.com") == 0); // mark down s1.bar.com. @@ -142,7 +142,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", build_request(10005, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "q1.bar.com") == 0); // mark down q1.bar.com @@ -152,7 +152,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", build_request(10006, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "q2.bar.com") == 0); // mark down q2.bar.com @@ -162,7 +162,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", build_request(10007, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_DIRECT); + CHECK(result->result == TSParentResultType::TS_PARENT_DIRECT); CHECK(result->hostname == nullptr); // sleep and test that q2 is becomes retryable; @@ -172,7 +172,7 @@ SCENARIO("Testing NextHopConsistentHash class, using policy 'consistent_hash'", // simulating a failure triggers a search for another parent, not firstcall. build_request(10008, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp, now); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "q2.bar.com") == 0); // free up request resources. @@ -229,7 +229,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co build_request(20001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "p1.foo.com") == 0); // mark down p1.foo.com @@ -238,7 +238,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co build_request(20002, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // mark down p2.foo.com @@ -248,7 +248,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co result->reset(); build_request(20003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "s2.bar.com") == 0); // mark down s2.bar.com @@ -258,7 +258,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co result->reset(); build_request(20004, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "s1.bar.com") == 0); // mark down s1.bar.com @@ -268,7 +268,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co result->reset(); build_request(20005, &sm, nullptr, "rabbit.net/asset1", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "q1.bar.com") == 0); // sixth request - wait and p1 should now become available @@ -276,7 +276,7 @@ SCENARIO("Testing NextHopConsistentHash class (all firstcalls), using policy 'co result->reset(); build_request(20006, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp, now); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "p1.foo.com") == 0); } // free up request resources. @@ -329,7 +329,7 @@ SCENARIO("Testing NextHop ignore_self_detect false", "[NextHopConsistentHash]") build_request(10001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_DIRECT); + CHECK(result->result == TSParentResultType::TS_PARENT_DIRECT); CHECK(result->hostname == nullptr); br_destroy(sm); } @@ -380,7 +380,7 @@ SCENARIO("Testing NextHop ignore_self_detect true", "[NextHopConsistentHash]") build_request(10001, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "localhost") == 0); CHECK(result->port == 8000); br_destroy(sm); @@ -432,7 +432,7 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "localhost") == 0); CHECK(result->port == 8000); @@ -441,7 +441,7 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne build_request(10002, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "localhost") == 0); CHECK(result->port == 8002); @@ -450,7 +450,7 @@ SCENARIO("Testing NextHopConsistentHash same host different port markdown", "[Ne build_request(10003, &sm, nullptr, "rabbit.net", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "localhost") == 0); CHECK(result->port == 8004); br_destroy(sm); @@ -504,7 +504,7 @@ SCENARIO("Testing NextHopConsistentHash hash_string override", "[NextHopConsiste // We happen to know that 'foo.test' will be first if the hostname is the hash // and foo.test will be first for the hash 'first' and the bar.test hash 'second'. // So, if the hash_string override isn't getting applied, this will fail. - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "bar.test") == 0); CHECK(result->port == 80); @@ -564,7 +564,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy build_request(30001, &sm, nullptr, "bunny.net/asset1", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "c2.foo.com") == 0); // simulated failure, mark c2 down and retry request @@ -573,7 +573,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy // second request build_request(30002, &sm, nullptr, "bunny.net.net/asset1", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "c3.bar.com") == 0); // mark down c3.bar.com @@ -583,7 +583,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy build_request(30003, &sm, nullptr, "bunny.net/asset2", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "c6.bar.com") == 0); // just mark it down and retry request @@ -591,7 +591,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy // fourth request build_request(30004, &sm, nullptr, "bunny.net/asset2", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "c1.foo.com") == 0); // mark it down @@ -600,7 +600,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy build_request(30005, &sm, nullptr, "bunny.net/asset3", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "c4.bar.com") == 0); // mark it down and retry @@ -609,7 +609,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy result->reset(); build_request(30006, &sm, nullptr, "bunny.net/asset3", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "c5.bar.com") == 0); // mark it down @@ -618,7 +618,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy result->reset(); build_request(30007, &sm, nullptr, "bunny.net/asset4", nullptr); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_FAIL); + CHECK(result->result == TSParentResultType::TS_PARENT_FAIL); CHECK(result->hostname == nullptr); // eighth request - retry after waiting for the retry window to expire. @@ -626,7 +626,7 @@ SCENARIO("Testing NextHopConsistentHash class (alternating rings), using policy result->reset(); build_request(30008, &sm, nullptr, "bunny.net/asset4", nullptr); strategy->findNextHop(txnp, now); - CHECK(result->result == TSParentResultType::PARENT_SPECIFIED); + CHECK(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "c2.foo.com") == 0); } // free up request resources. diff --git a/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc b/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc index 772003442db..389ff2aa439 100644 --- a/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc +++ b/proxy/http/remap/unit-tests/test_NextHopRoundRobin.cc @@ -138,7 +138,7 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-strict'", "[NextHopR build_request(10009, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp); - CHECK(result->result == TSParentResultType::PARENT_DIRECT); + CHECK(result->result == TSParentResultType::TS_PARENT_DIRECT); // check that nextHopExists() returns false when all parents are down. CHECK(strategy->nextHopExists(txnp) == false); @@ -150,14 +150,14 @@ SCENARIO("Testing NextHopRoundRobin class, using policy 'rr-strict'", "[NextHopR build_request(10010, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp, now); - REQUIRE(result->result == TSParentResultType::PARENT_SPECIFIED); + REQUIRE(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "p2.foo.com") == 0); // tenth request, p1 should now be retried. build_request(10011, &sm, nullptr, "rabbit.net", nullptr); result->reset(); strategy->findNextHop(txnp, now); - REQUIRE(result->result == TSParentResultType::PARENT_SPECIFIED); + REQUIRE(result->result == TSParentResultType::TS_PARENT_SPECIFIED); CHECK(strcmp(result->hostname, "p1.foo.com") == 0); } br_destroy(sm); From ece3d577dd88b2b3c939334d3972061db4e965fa Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Fri, 16 Oct 2020 10:00:34 -0600 Subject: [PATCH 07/15] Fix comment for TSHostStatusGet+Set --- include/ts/ts.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ts/ts.h b/include/ts/ts.h index bf3dd5ed21a..2f5bc38617d 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -2617,7 +2617,7 @@ tsapi TSReturnCode TSHostnameIsSelf(const char *hostname); /* * Gets the status of hostname in the outparam status, and the status reason in the outparam reason. - * The reason is a logical-and combination of the reasons in TSHostStatusReason. + * The reason is a logical-or combination of the reasons in TSHostStatusReason. * If either outparam is null, it will not be set and no error will be returned. * Returns TS_SUCCESS if the hostname was a parent and existed in the HostStatus, else TS_ERROR. */ @@ -2625,7 +2625,7 @@ tsapi TSReturnCode TSHostStatusGet(const char *hostname, TSHostStatus *status, u /* * Sets the status of hostname in status, down_time, and reason. - * The reason is a logical-and combination of the reasons in TSHostStatusReason. + * The reason is a logical-or combination of the reasons in TSHostStatusReason. */ tsapi void TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int down_time, const unsigned int reason); From 6cf3985ba1bcb2b92ac9a7f84f7007d83c54c214 Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Fri, 16 Oct 2020 10:54:53 -0600 Subject: [PATCH 08/15] Change TSParentResult port int to in_port_t --- include/tscpp/api/parentresult.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/tscpp/api/parentresult.h b/include/tscpp/api/parentresult.h index 95a1cfbe240..7b63539a8c9 100644 --- a/include/tscpp/api/parentresult.h +++ b/include/tscpp/api/parentresult.h @@ -23,12 +23,13 @@ #include "ts/apidefs.h" #include "tscore/ConsistentHash.h" +#include extern const char *ParentResultStr[]; struct TSParentResult { const char *hostname; - int port; + in_port_t port; bool retry; TSParentResultType result; bool chash_init[TS_MAX_GROUP_RINGS] = {false}; From ba461355466a52f01fbffa2d44adb519dabd9e9e Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Fri, 16 Oct 2020 11:02:47 -0600 Subject: [PATCH 09/15] Remove plugin nexthop ?true:false --- .../nexthop_strategy_consistenthash/consistenthash.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index 4d45043aeb9..739da179704 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -64,7 +64,7 @@ chash_lookup(std::shared_ptr ring, uint64_t hash_key, ATSCons host_rec = static_cast(ring->lookup(nullptr, iter, wrapped, hash)); } bool wrap_around = *wrapped; - *wrapped = (*mapWrapped && *wrapped) ? true : false; + *wrapped = *mapWrapped && *wrapped; if (!*mapWrapped && wrap_around) { *mapWrapped = true; } From bcc3f7f9b42a4206218d04fc0729a8023e147134 Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Fri, 16 Oct 2020 11:11:01 -0600 Subject: [PATCH 10/15] Change assignment+if to ?: --- src/traffic_server/InkAPI.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index a30793a84bf..6799a556c2c 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -9913,11 +9913,7 @@ TSHttpTxnRedoCacheLookup(TSHttpTxn txnp, const char *url, int length) TSReturnCode TSHostnameIsSelf(const char *hostname) { - const bool isSelf = Machine::instance()->is_self(hostname); - if (isSelf) { - return TS_SUCCESS; - } - return TS_ERROR; + return Machine::instance()->is_self(hostname) ? TS_SUCCESS : TS_ERROR; } TSReturnCode From a9e2a14043b342d2d373bc45e8d5d86172c5b753 Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Mon, 19 Oct 2020 11:15:23 -0600 Subject: [PATCH 11/15] Change NextHop Strategy funcs to string_view Also changes the HostStatus and what it exposes, and changes char* to also take the len to make string_view construction faster/easier. --- include/ts/ts.h | 4 +- .../consistenthash.cc | 6 +-- .../strategy.cc | 2 +- proxy/HostStatus.h | 12 ++--- src/traffic_server/HostStatus.cc | 46 ++++++++++--------- src/traffic_server/InkAPI.cc | 8 ++-- 6 files changed, 40 insertions(+), 38 deletions(-) diff --git a/include/ts/ts.h b/include/ts/ts.h index 2f5bc38617d..3e7e9463a2e 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -2621,13 +2621,13 @@ tsapi TSReturnCode TSHostnameIsSelf(const char *hostname); * If either outparam is null, it will not be set and no error will be returned. * Returns TS_SUCCESS if the hostname was a parent and existed in the HostStatus, else TS_ERROR. */ -tsapi TSReturnCode TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason); +tsapi TSReturnCode TSHostStatusGet(const char *hostname, const size_t hostname_len, TSHostStatus *status, unsigned int *reason); /* * Sets the status of hostname in status, down_time, and reason. * The reason is a logical-or combination of the reasons in TSHostStatusReason. */ -tsapi void TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int down_time, const unsigned int reason); +tsapi void TSHostStatusSet(const char *hostname, const size_t hostname_len, TSHostStatus status, const unsigned int down_time, const unsigned int reason); struct TSParentResult; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index 739da179704..39c3a56cf9d 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -343,7 +343,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) pRec = host_groups[hostRec->group_index][hostRec->host_index]; if (firstcall) { TSHostStatus hostStatus; - const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, nullptr) == TS_SUCCESS) : false; + const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(), &hostStatus, nullptr) == TS_SUCCESS) : false; result->first_choice_status = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; break; } @@ -360,7 +360,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus hostStatus; unsigned int hostReasons; - const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; + const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble @@ -408,7 +408,7 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus hostStatus; unsigned int hostReasons; - const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; + const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(),&hostStatus, &hostReasons) == TS_SUCCESS) : false; host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason diff --git a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc index e92ae8f1e65..897e6c4029b 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/strategy.cc @@ -189,7 +189,7 @@ NextHopSelectionStrategy::Init(const YAML::Node &n) host_rec->group_index = grp; host_rec->host_index = hst; if (TSHostnameIsSelf(host_rec->hostname.c_str()) == TS_SUCCESS) { - TSHostStatusSet(host_rec->hostname.c_str(), TSHostStatus::TS_HOST_STATUS_DOWN, 0, + TSHostStatusSet(host_rec->hostname.c_str(), host_rec->hostname.size(), TSHostStatus::TS_HOST_STATUS_DOWN, 0, (unsigned int)TS_HOST_STATUS_SELF_DETECT); } hosts_inner.push_back(std::move(host_rec)); diff --git a/proxy/HostStatus.h b/proxy/HostStatus.h index 133e90a0be7..39ed8470a11 100644 --- a/proxy/HostStatus.h +++ b/proxy/HostStatus.h @@ -183,12 +183,12 @@ struct HostStatus { static HostStatus instance; return instance; } - void setHostStatus(const char *name, const TSHostStatus status, const unsigned int down_time, const unsigned int reason); - HostStatRec *getHostStatus(const char *name); - void createHostStat(const char *name, const char *data = nullptr); + void setHostStatus(const std::string_view name, const TSHostStatus status, const unsigned int down_time, const unsigned int reason); + HostStatRec *getHostStatus(const std::string_view name); + void createHostStat(const std::string_view name, const char *data = nullptr); void loadHostStatusFromStats(); - void loadRecord(std::string &name, HostStatRec &h); - RecErrT getHostStat(std::string &stat_name, char *buf, unsigned int buf_len); + void loadRecord(const std::string_view name, HostStatRec &h); + RecErrT getHostStat(const std::string &stat_name, char *buf, unsigned int buf_len); private: HostStatus(); @@ -196,7 +196,7 @@ struct HostStatus { HostStatus &operator=(HostStatus const &) = delete; // next hop status, key is hostname or ip string, data is HostStatRec - std::unordered_map hosts_statuses; + std::map> hosts_statuses; ink_rwlock host_status_rwlock; }; diff --git a/src/traffic_server/HostStatus.cc b/src/traffic_server/HostStatus.cc index 40c176b2c20..b680eae5417 100644 --- a/src/traffic_server/HostStatus.cc +++ b/src/traffic_server/HostStatus.cc @@ -20,13 +20,15 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include #include "HostStatus.h" #include "ProcessManager.h" inline void -getStatName(std::string &stat_name, const char *name) +getStatName(std::string &stat_name, const std::string_view name) { - stat_name = stat_prefix + name; + stat_name.clear(); + stat_name.append(stat_prefix).append(name); } static void @@ -195,7 +197,7 @@ handle_record_read(const RecRecord *rec, void *edata) // 1st move the pointer past the stat prefix. s += stat_prefix.length(); hostname = s; - hs.createHostStat(hostname.c_str(), rec->data.rec_string); + hs.createHostStat(hostname, rec->data.rec_string); HostStatRec h(rec->data.rec_string); hs.loadRecord(hostname, h); } @@ -226,13 +228,13 @@ HostStatus::loadHostStatusFromStats() } void -HostStatus::loadRecord(std::string &name, HostStatRec &h) +HostStatus::loadRecord(std::string_view name, HostStatRec &h) { HostStatRec *host_stat = nullptr; - Debug("host_statuses", "loading host status record for %s", name.c_str()); + Debug("host_statuses", "loading host status record for %.*s", int(name.size()), name.data()); ink_rwlock_wrlock(&host_status_rwlock); { - if (auto it = hosts_statuses.find(name.c_str()); it != hosts_statuses.end()) { + if (auto it = hosts_statuses.find(name); it != hosts_statuses.end()) { host_stat = it->second; } else { host_stat = static_cast(ats_malloc(sizeof(HostStatRec))); @@ -246,7 +248,7 @@ HostStatus::loadRecord(std::string &name, HostStatRec &h) } void -HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned int down_time, const unsigned int reason) +HostStatus::setHostStatus(const std::string_view name, TSHostStatus status, const unsigned int down_time, const unsigned int reason) { std::string stat_name; char buf[1024] = {0}; @@ -272,7 +274,7 @@ HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned hosts_statuses.emplace(name, host_stat); } if (reason & Reason::ACTIVE) { - Debug("host_statuses", "for host %s set status: %s, Reason:ACTIVE", name, HostStatusNames[status]); + Debug("host_statuses", "for host %.*s set status: %s, Reason:ACTIVE", int(name.size()), name.data(), HostStatusNames[status]); if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->active_marked_down = time(0); host_stat->active_down_time = down_time; @@ -286,7 +288,7 @@ HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned } } if (reason & Reason::LOCAL) { - Debug("host_statuses", "for host %s set status: %s, Reason:LOCAL", name, HostStatusNames[status]); + Debug("host_statuses", "for host %.*s set status: %s, Reason:LOCAL", int(name.size()), name.data(), HostStatusNames[status]); if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->local_marked_down = time(0); host_stat->local_down_time = down_time; @@ -300,7 +302,7 @@ HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned } } if (reason & Reason::MANUAL) { - Debug("host_statuses", "for host %s set status: %s, Reason:MANUAL", name, HostStatusNames[status]); + Debug("host_statuses", "for host %.*s set status: %s, Reason:MANUAL", int(name.size()), name.data(), HostStatusNames[status]); if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->manual_marked_down = time(0); host_stat->manual_down_time = down_time; @@ -314,7 +316,7 @@ HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned } } if (reason & Reason::SELF_DETECT) { - Debug("host_statuses", "for host %s set status: %s, Reason:SELF_DETECT", name, HostStatusNames[status]); + Debug("host_statuses", "for host %.*s set status: %s, Reason:SELF_DETECT", int(name.size()), name.data(), HostStatusNames[status]); if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->self_detect_marked_down = time(0); host_stat->reasons |= Reason::SELF_DETECT; @@ -343,23 +345,23 @@ HostStatus::setHostStatus(const char *name, TSHostStatus status, const unsigned status_rec << *host_stat; RecSetRecordString(stat_name.c_str(), const_cast(status_rec.str().c_str()), REC_SOURCE_EXPLICIT, true); if (status == TSHostStatus::TS_HOST_STATUS_UP) { - Debug("host_statuses", "set status up for name: %s, status: %d, stat_name: %s", name, status, stat_name.c_str()); + Debug("host_statuses", "set status up for name: %.*s, status: %d, stat_name: %s", int(name.size()), name.data(), status, stat_name.c_str()); } else { - Debug("host_statuses", "set status down for name: %s, status: %d, stat_name: %s", name, status, stat_name.c_str()); + Debug("host_statuses", "set status down for name: %.*s, status: %d, stat_name: %s", int(name.size()), name.data(), status, stat_name.c_str()); } } - Debug("host_statuses", "name: %s, status: %d", name, status); + Debug("host_statuses", "name: %.*s, status: %d", int(name.size()), name.data(), status); // log it. if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { - Note("Host %s has been marked down, down_time: %d - %s.", name, down_time, down_time == 0 ? "indefinitely." : "seconds."); + Note("Host %.*s has been marked down, down_time: %d - %s.", int(name.size()), name.data(), down_time, down_time == 0 ? "indefinitely." : "seconds."); } else { - Note("Host %s has been marked up.", name); + Note("Host %.*s has been marked up.", int(name.size()), name.data()); } } HostStatRec * -HostStatus::getHostStatus(const char *name) +HostStatus::getHostStatus(const std::string_view name) { HostStatRec *_status = nullptr; time_t now = time(0); @@ -381,7 +383,7 @@ HostStatus::getHostStatus(const char *name) unsigned int reasons = _status->reasons; if ((_status->reasons & Reason::ACTIVE) && _status->active_down_time > 0) { if ((_status->active_down_time + _status->active_marked_down) < now) { - Debug("host_statuses", "name: %s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", name, now, + Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), now, _status->active_down_time, _status->active_marked_down, Reason::ACTIVE_REASON); setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::ACTIVE); reasons ^= Reason::ACTIVE; @@ -389,7 +391,7 @@ HostStatus::getHostStatus(const char *name) } if ((_status->reasons & Reason::LOCAL) && _status->local_down_time > 0) { if ((_status->local_down_time + _status->local_marked_down) < now) { - Debug("host_statuses", "name: %s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", name, now, + Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), now, _status->local_down_time, _status->local_marked_down, Reason::LOCAL_REASON); setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::LOCAL); reasons ^= Reason::LOCAL; @@ -397,7 +399,7 @@ HostStatus::getHostStatus(const char *name) } if ((_status->reasons & Reason::MANUAL) && _status->manual_down_time > 0) { if ((_status->manual_down_time + _status->manual_marked_down) < now) { - Debug("host_statuses", "name: %s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", name, now, + Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), now, _status->manual_down_time, _status->manual_marked_down, Reason::MANUAL_REASON); setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::MANUAL); reasons ^= Reason::MANUAL; @@ -410,7 +412,7 @@ HostStatus::getHostStatus(const char *name) } void -HostStatus::createHostStat(const char *name, const char *data) +HostStatus::createHostStat(const std::string_view name, const char *data) { char buf[1024] = {0}; HostStatRec r; @@ -431,7 +433,7 @@ HostStatus::createHostStat(const char *name, const char *data) } RecErrT -HostStatus::getHostStat(std::string &stat_name, char *buf, unsigned int buf_len) +HostStatus::getHostStat(const std::string &stat_name, char *buf, unsigned int buf_len) { return RecGetRecordString(stat_name.c_str(), buf, buf_len, true); } diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 6799a556c2c..224a493f930 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -9917,9 +9917,9 @@ TSHostnameIsSelf(const char *hostname) } TSReturnCode -TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason) +TSHostStatusGet(const char *hostname, const size_t hostname_len, TSHostStatus *status, unsigned int *reason) { - HostStatRec *hst = HostStatus::instance().getHostStatus(hostname); + HostStatRec *hst = HostStatus::instance().getHostStatus(std::string_view(hostname, hostname_len)); if (hst == nullptr) { return TS_ERROR; } @@ -9933,9 +9933,9 @@ TSHostStatusGet(const char *hostname, TSHostStatus *status, unsigned int *reason } void -TSHostStatusSet(const char *hostname, TSHostStatus status, const unsigned int down_time, const unsigned int reason) +TSHostStatusSet(const char *hostname, const size_t hostname_len, TSHostStatus status, const unsigned int down_time, const unsigned int reason) { - HostStatus::instance().setHostStatus(hostname, status, down_time, reason); + HostStatus::instance().setHostStatus(std::string_view(hostname, hostname_len), status, down_time, reason); } void From 357544fb8857276acfe60d476a517bd7de293b52 Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Mon, 19 Oct 2020 12:55:14 -0600 Subject: [PATCH 12/15] Change RemapPluginInst.name to string_view --- proxy/http/remap/NextHopStrategyFactory.cc | 6 +++--- proxy/http/remap/NextHopStrategyFactory.h | 4 ++-- proxy/http/remap/PluginFactory.cc | 4 ++-- proxy/http/remap/PluginFactory.h | 6 ++++-- proxy/http/remap/RemapConfig.cc | 6 +++--- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/proxy/http/remap/NextHopStrategyFactory.cc b/proxy/http/remap/NextHopStrategyFactory.cc index 1cdfd5443bb..31739a8a0d0 100644 --- a/proxy/http/remap/NextHopStrategyFactory.cc +++ b/proxy/http/remap/NextHopStrategyFactory.cc @@ -166,13 +166,13 @@ NextHopStrategyFactory::strategyInstance(const char *name) * Designed for plugins which want to dynamically add strategies. */ bool -NextHopStrategyFactory::addStrategy(const std::string &name, std::shared_ptr strategy) +NextHopStrategyFactory::addStrategy(const std::string_view name, std::shared_ptr strategy) { if (_strategies.find(name) != _strategies.end()) { - NH_Error("failed to add strategy '%s' because a strategy with that name already exists", name.c_str()); + NH_Error("failed to add strategy '%.*s' because a strategy with that name already exists", int(name.size()), name.data()); return false; } - _strategies[name] = strategy; + _strategies.emplace(name, strategy); strategies_loaded = true; return true; } diff --git a/proxy/http/remap/NextHopStrategyFactory.h b/proxy/http/remap/NextHopStrategyFactory.h index 16e015f8ad1..a7d15f37fa5 100644 --- a/proxy/http/remap/NextHopStrategyFactory.h +++ b/proxy/http/remap/NextHopStrategyFactory.h @@ -43,7 +43,7 @@ class NextHopStrategyFactory NextHopStrategyFactory(const char *file); ~NextHopStrategyFactory(); std::shared_ptr strategyInstance(const char *name); - bool addStrategy(const std::string &name, std::shared_ptr strategy); + bool addStrategy(const std::string_view name, std::shared_ptr strategy); bool strategies_loaded; @@ -52,5 +52,5 @@ class NextHopStrategyFactory void loadConfigFile(const std::string &file, std::stringstream &doc, std::unordered_set &include_once); void createStrategy(const std::string &name, const NHPolicyType policy_type, const YAML::Node &node); void createStrategyPlugin(const std::string &name, const YAML::Node &node); - std::unordered_map> _strategies; + std::map, std::less<>> _strategies; }; diff --git a/proxy/http/remap/PluginFactory.cc b/proxy/http/remap/PluginFactory.cc index c86e3ca2760..9f02963d0e1 100644 --- a/proxy/http/remap/PluginFactory.cc +++ b/proxy/http/remap/PluginFactory.cc @@ -82,10 +82,10 @@ RemapPluginInst::getStrategy() return _plugin.initStrategy(this->_instance); } -std::string +std::string_view RemapPluginInst::name() const { - return _plugin.configPath().string(); + return _plugin.configPath().view(); } void diff --git a/proxy/http/remap/PluginFactory.h b/proxy/http/remap/PluginFactory.h index 111bf21f3a8..bce29d6e867 100644 --- a/proxy/http/remap/PluginFactory.h +++ b/proxy/http/remap/PluginFactory.h @@ -54,9 +54,11 @@ class RemapPluginInst TSRemapStatus doRemap(TSHttpTxn rh, TSRemapRequestInfo *rri); void osResponse(TSHttpTxn rh, int os_response_type); - /* gets the Strategy if the plugin has a TSRemapInitStrategy function. Returns a nullptr if not. */ + /* Gets the Strategy if the plugin has a TSRemapInitStrategy function. Returns a nullptr if not. */ std::shared_ptr getStrategy(); - std::string name() const; + /* Gets the name of the plugin. + Lifetime: this. The returned string_view must not be used after the RemapPluginInst is deallocated. */ + std::string_view name() const; /* List used by the plugin factory */ using self_type = RemapPluginInst; ///< Self reference type. diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc index 39495bbe24b..ff3c231fa4c 100644 --- a/proxy/http/remap/RemapConfig.cc +++ b/proxy/http/remap/RemapConfig.cc @@ -1310,12 +1310,12 @@ remap_parse_config_bti(const char *path, BUILD_TABLE_INFO *bti) continue; // TODO error? } std::shared_ptr strategy = pluginInst->getStrategy(); - const std::string pluginName = pluginInst->name(); + const std::string_view pluginName = pluginInst->name(); if (strategy != nullptr) { - Debug("remap_plugin", "Remap plugin got strategy '%s'", pluginName.c_str()); + Debug("remap_plugin", "Remap plugin got strategy '%.*s'", int(pluginName.size()), pluginName.data()); bti->rewrite->strategyFactory->addStrategy(pluginName, strategy); // will log an error if the name already exists } else { - Debug("remap_plugin", "Remap plugin has no strategy in '%s'", pluginName.c_str()); + Debug("remap_plugin", "Remap plugin has no strategy in '%.*s'", int(pluginName.size()), pluginName.data()); } } From b78a74ad253449a8cb97f26208a6d6156270912b Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Mon, 19 Oct 2020 13:59:03 -0600 Subject: [PATCH 13/15] Change NextHop plugin to not move shared_ptr --- .../nexthop_strategy_consistenthash/consistenthash.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index 39c3a56cf9d..2f1af0d7b59 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -134,7 +134,7 @@ NextHopConsistentHash::Init(const YAML::Node &n) p->hostname.c_str(), strategy_name.c_str()); } hash.clear(); - rings.push_back(std::move(hash_ring)); + rings.push_back(hash_ring); } return true; } From a89b8b722969f6bfc2c8a16def43978cc2ebfa59 Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Mon, 19 Oct 2020 14:40:51 -0600 Subject: [PATCH 14/15] Rename PluginInst.getStrategy to initStrategy --- proxy/http/HttpTransact.cc | 2 +- proxy/http/remap/PluginFactory.cc | 2 +- proxy/http/remap/PluginFactory.h | 4 ++-- proxy/http/remap/RemapConfig.cc | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index fd9b90445df..a21e731cf71 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -761,7 +761,7 @@ how_to_open_connection(HttpTransact::State *s) // Setting up a direct CONNECT tunnel enters OriginServerRawOpen. We always do that if we // are not forwarding CONNECT and are not going to a parent proxy. if (s->method == HTTP_WKSIDX_CONNECT) { - if (s->txn_conf->forward_connect_method != 1 && s->parent_result.result != PARENT_SPECIFIED) { + if (s->txn_conf->forward_connect_method != 1 && s->parent_result.result != TS_PARENT_SPECIFIED) { connect_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_RAW_OPEN; } } diff --git a/proxy/http/remap/PluginFactory.cc b/proxy/http/remap/PluginFactory.cc index 9f02963d0e1..493fe430ac1 100644 --- a/proxy/http/remap/PluginFactory.cc +++ b/proxy/http/remap/PluginFactory.cc @@ -77,7 +77,7 @@ RemapPluginInst::doRemap(TSHttpTxn rh, TSRemapRequestInfo *rri) } std::shared_ptr -RemapPluginInst::getStrategy() +RemapPluginInst::initStrategy() { return _plugin.initStrategy(this->_instance); } diff --git a/proxy/http/remap/PluginFactory.h b/proxy/http/remap/PluginFactory.h index bce29d6e867..ba44863fd68 100644 --- a/proxy/http/remap/PluginFactory.h +++ b/proxy/http/remap/PluginFactory.h @@ -54,8 +54,8 @@ class RemapPluginInst TSRemapStatus doRemap(TSHttpTxn rh, TSRemapRequestInfo *rri); void osResponse(TSHttpTxn rh, int os_response_type); - /* Gets the Strategy if the plugin has a TSRemapInitStrategy function. Returns a nullptr if not. */ - std::shared_ptr getStrategy(); + /* Initialize the Strategy if the plugin has a TSRemapInitStrategy function. Returns a nullptr if not. */ + std::shared_ptr initStrategy(); /* Gets the name of the plugin. Lifetime: this. The returned string_view must not be used after the RemapPluginInst is deallocated. */ std::string_view name() const; diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc index ff3c231fa4c..5e52f6d429e 100644 --- a/proxy/http/remap/RemapConfig.cc +++ b/proxy/http/remap/RemapConfig.cc @@ -1309,7 +1309,7 @@ remap_parse_config_bti(const char *path, BUILD_TABLE_INFO *bti) if (pluginInst == nullptr) { continue; // TODO error? } - std::shared_ptr strategy = pluginInst->getStrategy(); + std::shared_ptr strategy = pluginInst->initStrategy(); const std::string_view pluginName = pluginInst->name(); if (strategy != nullptr) { Debug("remap_plugin", "Remap plugin got strategy '%.*s'", int(pluginName.size()), pluginName.data()); From 9412a14dc58a9faf33db66ab5d904d0e2cb20e3a Mon Sep 17 00:00:00 2001 From: Robert Butts Date: Wed, 4 Nov 2020 11:43:54 -0700 Subject: [PATCH 15/15] clang-format --- include/ts/ts.h | 3 ++- .../consistenthash.cc | 13 ++++++---- proxy/HostStatus.h | 3 ++- src/traffic_server/HostStatus.cc | 24 +++++++++++-------- src/traffic_server/InkAPI.cc | 5 ++-- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/include/ts/ts.h b/include/ts/ts.h index 3e7e9463a2e..80be588cee6 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -2627,7 +2627,8 @@ tsapi TSReturnCode TSHostStatusGet(const char *hostname, const size_t hostname_l * Sets the status of hostname in status, down_time, and reason. * The reason is a logical-or combination of the reasons in TSHostStatusReason. */ -tsapi void TSHostStatusSet(const char *hostname, const size_t hostname_len, TSHostStatus status, const unsigned int down_time, const unsigned int reason); +tsapi void TSHostStatusSet(const char *hostname, const size_t hostname_len, TSHostStatus status, const unsigned int down_time, + const unsigned int reason); struct TSParentResult; diff --git a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc index 2f1af0d7b59..c8c10332651 100644 --- a/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc +++ b/plugins/experimental/nexthop_strategy_consistenthash/consistenthash.cc @@ -343,7 +343,8 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) pRec = host_groups[hostRec->group_index][hostRec->host_index]; if (firstcall) { TSHostStatus hostStatus; - const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(), &hostStatus, nullptr) == TS_SUCCESS) : false; + const bool hostExists = + pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(), &hostStatus, nullptr) == TS_SUCCESS) : false; result->first_choice_status = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; break; } @@ -360,8 +361,9 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus hostStatus; unsigned int hostReasons; - const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; - host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; + const bool hostExists = + pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; + host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble if ((pRec && ignore_self_detect) && (hostExists && hostStatus == TS_HOST_STATUS_DOWN)) { @@ -408,8 +410,9 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, time_t now) TSHostStatus hostStatus; unsigned int hostReasons; - const bool hostExists = pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(),&hostStatus, &hostReasons) == TS_SUCCESS) : false; - host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; + const bool hostExists = + pRec ? (TSHostStatusGet(pRec->hostname.c_str(), pRec->hostname.size(), &hostStatus, &hostReasons) == TS_SUCCESS) : false; + host_stat = hostExists ? hostStatus : TSHostStatus::TS_HOST_STATUS_UP; // if the config ignore_self_detect is set to true and the host is down due to SELF_DETECT reason // ignore the down status and mark it as avaialble diff --git a/proxy/HostStatus.h b/proxy/HostStatus.h index 39ed8470a11..6ed571f8f92 100644 --- a/proxy/HostStatus.h +++ b/proxy/HostStatus.h @@ -183,7 +183,8 @@ struct HostStatus { static HostStatus instance; return instance; } - void setHostStatus(const std::string_view name, const TSHostStatus status, const unsigned int down_time, const unsigned int reason); + void setHostStatus(const std::string_view name, const TSHostStatus status, const unsigned int down_time, + const unsigned int reason); HostStatRec *getHostStatus(const std::string_view name); void createHostStat(const std::string_view name, const char *data = nullptr); void loadHostStatusFromStats(); diff --git a/src/traffic_server/HostStatus.cc b/src/traffic_server/HostStatus.cc index b680eae5417..c993710d658 100644 --- a/src/traffic_server/HostStatus.cc +++ b/src/traffic_server/HostStatus.cc @@ -316,7 +316,8 @@ HostStatus::setHostStatus(const std::string_view name, TSHostStatus status, cons } } if (reason & Reason::SELF_DETECT) { - Debug("host_statuses", "for host %.*s set status: %s, Reason:SELF_DETECT", int(name.size()), name.data(), HostStatusNames[status]); + Debug("host_statuses", "for host %.*s set status: %s, Reason:SELF_DETECT", int(name.size()), name.data(), + HostStatusNames[status]); if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { host_stat->self_detect_marked_down = time(0); host_stat->reasons |= Reason::SELF_DETECT; @@ -345,16 +346,19 @@ HostStatus::setHostStatus(const std::string_view name, TSHostStatus status, cons status_rec << *host_stat; RecSetRecordString(stat_name.c_str(), const_cast(status_rec.str().c_str()), REC_SOURCE_EXPLICIT, true); if (status == TSHostStatus::TS_HOST_STATUS_UP) { - Debug("host_statuses", "set status up for name: %.*s, status: %d, stat_name: %s", int(name.size()), name.data(), status, stat_name.c_str()); + Debug("host_statuses", "set status up for name: %.*s, status: %d, stat_name: %s", int(name.size()), name.data(), status, + stat_name.c_str()); } else { - Debug("host_statuses", "set status down for name: %.*s, status: %d, stat_name: %s", int(name.size()), name.data(), status, stat_name.c_str()); + Debug("host_statuses", "set status down for name: %.*s, status: %d, stat_name: %s", int(name.size()), name.data(), status, + stat_name.c_str()); } } Debug("host_statuses", "name: %.*s, status: %d", int(name.size()), name.data(), status); // log it. if (status == TSHostStatus::TS_HOST_STATUS_DOWN) { - Note("Host %.*s has been marked down, down_time: %d - %s.", int(name.size()), name.data(), down_time, down_time == 0 ? "indefinitely." : "seconds."); + Note("Host %.*s has been marked down, down_time: %d - %s.", int(name.size()), name.data(), down_time, + down_time == 0 ? "indefinitely." : "seconds."); } else { Note("Host %.*s has been marked up.", int(name.size()), name.data()); } @@ -383,24 +387,24 @@ HostStatus::getHostStatus(const std::string_view name) unsigned int reasons = _status->reasons; if ((_status->reasons & Reason::ACTIVE) && _status->active_down_time > 0) { if ((_status->active_down_time + _status->active_marked_down) < now) { - Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), now, - _status->active_down_time, _status->active_marked_down, Reason::ACTIVE_REASON); + Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), + now, _status->active_down_time, _status->active_marked_down, Reason::ACTIVE_REASON); setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::ACTIVE); reasons ^= Reason::ACTIVE; } } if ((_status->reasons & Reason::LOCAL) && _status->local_down_time > 0) { if ((_status->local_down_time + _status->local_marked_down) < now) { - Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), now, - _status->local_down_time, _status->local_marked_down, Reason::LOCAL_REASON); + Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), + now, _status->local_down_time, _status->local_marked_down, Reason::LOCAL_REASON); setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::LOCAL); reasons ^= Reason::LOCAL; } } if ((_status->reasons & Reason::MANUAL) && _status->manual_down_time > 0) { if ((_status->manual_down_time + _status->manual_marked_down) < now) { - Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), now, - _status->manual_down_time, _status->manual_marked_down, Reason::MANUAL_REASON); + Debug("host_statuses", "name: %.*s, now: %ld, down_time: %d, marked_down: %ld, reason: %s", int(name.size()), name.data(), + now, _status->manual_down_time, _status->manual_marked_down, Reason::MANUAL_REASON); setHostStatus(name, TSHostStatus::TS_HOST_STATUS_UP, 0, Reason::MANUAL); reasons ^= Reason::MANUAL; } diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 224a493f930..3faf9d4cdbc 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -9913,7 +9913,7 @@ TSHttpTxnRedoCacheLookup(TSHttpTxn txnp, const char *url, int length) TSReturnCode TSHostnameIsSelf(const char *hostname) { - return Machine::instance()->is_self(hostname) ? TS_SUCCESS : TS_ERROR; + return Machine::instance()->is_self(hostname) ? TS_SUCCESS : TS_ERROR; } TSReturnCode @@ -9933,7 +9933,8 @@ TSHostStatusGet(const char *hostname, const size_t hostname_len, TSHostStatus *s } void -TSHostStatusSet(const char *hostname, const size_t hostname_len, TSHostStatus status, const unsigned int down_time, const unsigned int reason) +TSHostStatusSet(const char *hostname, const size_t hostname_len, TSHostStatus status, const unsigned int down_time, + const unsigned int reason) { HostStatus::instance().setHostStatus(std::string_view(hostname, hostname_len), status, down_time, reason); }