This is an automated email from the ASF dual-hosted git repository. shinrich pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new 4e62375 Remove Congestion Control Feature 4e62375 is described below commit 4e62375623b3307b073d9b8375e19171d3af4e54 Author: Susan Hinrichs <shinr...@apache.org> AuthorDate: Thu Dec 21 09:47:25 2017 -0600 Remove Congestion Control Feature This feature has been gathering dust. I don't beleive anyone is using the feature, and the feedback I received is that it doesn't really work. --- doc/admin-guide/configuration/cache-basics.en.rst | 32 - doc/admin-guide/files/congestion.config.en.rst | 198 ------ doc/admin-guide/files/index.en.rst | 5 - doc/admin-guide/files/records.config.en.rst | 6 - mgmt/RecordsConfig.cc | 34 - proxy/ControlMatcher.cc | 8 - proxy/Main.cc | 2 - proxy/Makefile.am | 3 +- proxy/congest/Congestion.cc | 727 ---------------------- proxy/congest/Congestion.h | 470 -------------- proxy/congest/CongestionDB.cc | 633 ------------------- proxy/congest/CongestionDB.h | 106 ---- proxy/congest/CongestionStats.cc | 50 -- proxy/congest/CongestionStats.h | 48 -- proxy/congest/CongestionTest.cc | 568 ----------------- proxy/congest/MT_hashtable.h | 433 ------------- proxy/http/HttpDebugNames.cc | 8 - proxy/http/HttpSM.cc | 118 +--- proxy/http/HttpSM.h | 3 - proxy/http/HttpTransact.cc | 60 +- proxy/http/HttpTransact.h | 17 +- 21 files changed, 10 insertions(+), 3519 deletions(-) diff --git a/doc/admin-guide/configuration/cache-basics.en.rst b/doc/admin-guide/configuration/cache-basics.en.rst index d857fe9..d8a86f7 100644 --- a/doc/admin-guide/configuration/cache-basics.en.rst +++ b/doc/admin-guide/configuration/cache-basics.en.rst @@ -639,38 +639,6 @@ To alter the limit on the number of alternates: #. Run the command :option:`traffic_ctl config reload` to apply the configuration changes. -.. _using-congestion-control: - -Using Congestion Control -======================== - -The *Congestion Control* option enables you to configure Traffic -Server to stop forwarding HTTP requests to origin servers when they -become congested. Traffic Server then sends the client a message to -retry the congested origin server later. - -To enable this option: - -#. Set :ts:cv:`proxy.config.http.congestion_control.enabled` to ``1`` in - :file:`records.config`. :: - - CONFIG proxy.config.http.congestion_control.enabled INT 1 - -#. Create rules in :file:`congestion.config` to specify: - - - Which origin servers Traffic Server tracks for congestion. - - - The timeouts Traffic Server uses, depending on whether a server is - congested. - - - The page Traffic Server sends to the client when a server becomes - congested. - - - Whether Traffic Server tracks the origin servers by IP address or by - hostname. - -#. Run the command :option:`traffic_ctl config reload` to apply the configuration changes. - .. _transaction-buffering-control: Using Transaction Buffering Control diff --git a/doc/admin-guide/files/congestion.config.en.rst b/doc/admin-guide/files/congestion.config.en.rst deleted file mode 100644 index 9cc8140..0000000 --- a/doc/admin-guide/files/congestion.config.en.rst +++ /dev/null @@ -1,198 +0,0 @@ -.. 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. - -================= -congestion.config -================= - -.. configfile:: congestion.config - -The :file:`congestion.config` file (by default, located in -``/usr/local/etc/trafficserver/``) enables you to configure Traffic Server -to stop forwarding HTTP requests to origin servers when they become -congested, and then send the client a message to retry the congested -origin server later. After you modify the :file:`congestion.config` file, -navigate to the Traffic Server bin directory; then run the -:option:`traffic_ctl config reload` command to apply changes. When you apply the changes -to a node in a cluster, Traffic Server automatically applies the changes -to all other nodes in the cluster. Traffic Server uses the -:file:`congestion.config` file only if you enable the -:ts:cv:`proxy.config.http.congestion_control.enabled` option. - -You can create rules in the congestion.config file to specify: - -- Which origin servers Traffic Server tracks for congestion. -- The timeouts Traffic Server uses, depending on whether a server is - congested. -- The page Traffic Server sends to the client when a server becomes - congested. -- If Traffic Server tracks the origin servers per IP address or per - hostname. - -Format -====== - -Each line in :file:`congestion.config` must follow the format below. Traffic -Server applies the rules in the order listed, starting at the top of the -file. Traffic Server recognizes three space-delimited tags:: - - primary_destination=value secondary_specifier=value action=value - -The following list shows possible primary destinations with allowed -values. - -``dest_domain`` - A requested domain name. - -``dest_host`` - A requested hostname. - -``dest_ip`` - A requested IP address. - -``url_regex`` - A regular expression (regex) to be found in a URL. - -The secondary specifiers are optional in the congestion.config file. The -following list shows possible secondary specifiers with allowed values. -You can use more than one secondary specifier in a rule; however, you -cannot repeat a secondary specifier. - -``port`` - A requested URL port or range of ports. - -``prefix`` - A prefix in the path part of a URL. - -The following list shows the possible tags and their allowed values. - -``max_connection_failures`` - Default: ``5`` - The maximum number of connection failures allowed within the fail - window described below before Traffic Server marks the origin server - as congested. - -``fail_window`` - Default: ``120`` seconds. - The time period during which the maximum number of connection - failures can occur before Traffic Server marks the origin server as - congested. - -``proxy_retry_interval`` - Default: ``10`` seconds. - The number of seconds that Traffic Server waits before contacting a - congested origin server again. - -``client_wait_interval`` - Default: ``300`` seconds. - The number of seconds that the client is advised to wait before - retrying the congested origin server. - -``wait_interval_alpha`` - Default: ``30`` seconds - The upper limit for a random number that is added to the wait - interval. - -``live_os_conn_timeout`` - Default: ``60`` seconds. - The connection timeout to the live (uncongested) origin server. If a - client stops a request before the timeout occurs, then Traffic - Server does not record a connection failure. - -``live_os_conn_retries`` - Default: ``2`` - The maximum number of retries allowed to the live (uncongested) - origin server. - -``dead_os_conn_timeout`` - Default: ``15`` seconds. - The connection timeout to the congested origin server. - -``dead_os_conn_retries`` - Default: ``1`` - The maximum number of retries allowed to the congested origin - server. - -``max_connection`` - Default: ``-1`` - The maximum number of connections allowed from Traffic Server to the - origin server. - -``error_page`` - Default: ``"congestion#retryAfter"`` - The error page sent to the client when a server is congested. You - must enclose the value in quotes; - -``congestion_scheme`` - Default: ``"per_ip"`` - Specifies if Traffic Server applies the rule on a per-host - (``"per_host"``) or per-IP basis (``"per_ip"``). You must enclose - the value in quotes. - - For example: if the server ``www.host1.com`` has two IP addresses - and you use the tag value ``"per_ip"``, then each IP address has its - own number of connection failures and is marked as congested - independently. If you use the tag value ``"per_host"`` and the - server ``www.host1.com`` is marked as congested, then both IP - addresses are marked as congested. - -Examples -======== - -The following :file:`congestion.config` rule configures Traffic Server to -stop forwarding requests to the server ``www.host.com`` on port 80 (HTTP -traffic) if the server is congested, according to the timeouts -specified. Traffic Server uses the default tag values because no tag has -been specified. - -:: - - dest_host=www.host.com port=80 - -You can use one or more tags in a rule, but each tag must have one value -only. If you specify no tags in the rule, then Traffic Server uses the -default values. - -You can override any of the default tag values by adding configuration -variables at the end of :file:`records.config` as follows: - -:: - - CONFIG proxy.config.http.congestion_control.default.tag INT|STRING value - -where tag is one of the tags described in the list under -:file:`congestion.config` and value is the value you -want to use. - -For example:: - - CONFIG proxy.config.http.congestion_control.default.congestion_scheme STRING per_host - -.. important:: - - Rules in the :file:`congestion.config` file override the - following variables in the :file:`records.config` file: - -:: - - proxy.config.http.connect_attempts_max_retries - proxy.config.http.connect_attempts_max_retries_dead_server - proxy.config.http.connect_attempts_rr_retries - proxy.config.http.connect_attempts_timeout - proxy.config.http.down_server.cache_time - proxy.config.http.down_server.abort_threshold - diff --git a/doc/admin-guide/files/index.en.rst b/doc/admin-guide/files/index.en.rst index 4a158f7..aa5be0e 100644 --- a/doc/admin-guide/files/index.en.rst +++ b/doc/admin-guide/files/index.en.rst @@ -26,7 +26,6 @@ Configuration Files :hidden: cache.config.en - congestion.config.en hosting.config.en ip_allow.config.en log_hosts.config.en @@ -47,10 +46,6 @@ Configuration Files Defines if, how, and for what durations |TS| caches objects, based on destinations, clients, URL components, and more. -:doc:`congestion.config.en` - Defines network conditions under which clients will receive retry messages - instead of |TS| contacting origin servers. - :doc:`hosting.config.en` Allows |TS| administrators to assign cache volumes to specific origin servers or domains. diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst index 6f46747..ae88333 100644 --- a/doc/admin-guide/files/records.config.en.rst +++ b/doc/admin-guide/files/records.config.en.rst @@ -1533,12 +1533,6 @@ Origin Server Connect Attempts Congestion Control ================== -.. ts:cv:: CONFIG proxy.config.http.congestion_control.enabled INT 0 - - Enables (``1``) or disables (``0``) the Congestion Control option, which configures Traffic Server to stop forwarding - HTTP requests to origin servers when they become congested. Traffic Server sends the client a message to retry the - congested origin server later. Refer to :ref:`using-congestion-control`. - .. ts:cv:: CONFIG proxy.config.http.flow_control.enabled INT 0 :overridable: diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc index 273f6a8..b24e1f6 100644 --- a/mgmt/RecordsConfig.cc +++ b/mgmt/RecordsConfig.cc @@ -300,40 +300,6 @@ static const RecordElement RecordsConfig[] = {RECT_CONFIG, "proxy.config.alarm.script_runtime", RECD_INT, "5", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-300]", RECA_NULL} , - //#################################################################### - //# congestion control - //#################################################################### - {RECT_CONFIG, "proxy.config.http.congestion_control.enabled", RECD_INT, "0", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.localtime", RECD_INT, "0", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.filename", RECD_STRING, "congestion.config", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.max_connection_failures", RECD_INT, "5", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.fail_window", RECD_INT, "120", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.proxy_retry_interval", RECD_INT, "10", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.client_wait_interval", RECD_INT, "300", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.wait_interval_alpha", RECD_INT, "30", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.live_os_conn_timeout", RECD_INT, "60", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.live_os_conn_retries", RECD_INT, "2", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.dead_os_conn_timeout", RECD_INT, "15", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.dead_os_conn_retries", RECD_INT, "1", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.max_connection", RECD_INT, "-1", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.error_page", RECD_STRING, "congestion#retryAfter", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - {RECT_CONFIG, "proxy.config.http.congestion_control.default.congestion_scheme", RECD_STRING, "per_ip", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} - , - // ########### // # Parsing # // ########### diff --git a/proxy/ControlMatcher.cc b/proxy/ControlMatcher.cc index 5f290d6..d96f139 100644 --- a/proxy/ControlMatcher.cc +++ b/proxy/ControlMatcher.cc @@ -45,7 +45,6 @@ #include "P_Net.h" #include "P_Cache.h" #include "P_SplitDNS.h" -#include "congest/Congestion.h" /**************************************************************** * Place all template instantiations at the bottom of the file @@ -1004,10 +1003,3 @@ template class HostMatcher<CacheControlRecord, CacheControlResult>; template class RegexMatcher<CacheControlRecord, CacheControlResult>; template class UrlMatcher<CacheControlRecord, CacheControlResult>; template class IpMatcher<CacheControlRecord, CacheControlResult>; - -template class ControlMatcher<CongestionControlRecord, CongestionControlRule>; -template class HostMatcher<CongestionControlRecord, CongestionControlRule>; -template class HostRegexMatcher<CongestionControlRecord, CongestionControlRule>; -template class RegexMatcher<CongestionControlRecord, CongestionControlRule>; -template class UrlMatcher<CongestionControlRecord, CongestionControlRule>; -template class IpMatcher<CongestionControlRecord, CongestionControlRule>; diff --git a/proxy/Main.cc b/proxy/Main.cc index f6df8a9..0f2a6e2 100644 --- a/proxy/Main.cc +++ b/proxy/Main.cc @@ -88,7 +88,6 @@ extern "C" int plock(int); #include "Plugin.h" #include "DiagsConfig.h" #include "CoreUtils.h" -#include "congest/Congestion.h" #include "RemapProcessor.h" #include "I_Tasks.h" #include "InkAPIInternal.h" @@ -1840,7 +1839,6 @@ main(int /* argc ATS_UNUSED */, const char **argv) remapProcessor.start(num_remap_threads, stacksize); RecProcessStart(); initCacheControl(); - initCongestionControl(); IpAllow::startup(); ParentConfig::startup(); #ifdef SPLIT_DNS diff --git a/proxy/Makefile.am b/proxy/Makefile.am index 1df35af..da5cf67 100644 --- a/proxy/Makefile.am +++ b/proxy/Makefile.am @@ -19,7 +19,7 @@ include $(top_srcdir)/build/tidy.mk # Note that hdrs is targeted from ../Makefile.am -SUBDIRS = congest http http2 logging config +SUBDIRS = http http2 logging config noinst_LIBRARIES = bin_PROGRAMS = \ traffic_server \ @@ -181,7 +181,6 @@ traffic_server_LDADD = \ http/libhttp.a \ http2/libhttp2.a \ http/remap/libhttp_remap.a \ - congest/libCongestionControl.a \ logging/liblogging.a \ logging/liblogcollation.a \ hdrs/libhdrs.a \ diff --git a/proxy/congest/Congestion.cc b/proxy/congest/Congestion.cc deleted file mode 100644 index e2bfdfd..0000000 --- a/proxy/congest/Congestion.cc +++ /dev/null @@ -1,727 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/***************************************************************************** - * - * Congestion.cc - Content and User Access Control - * - * - ****************************************************************************/ -#include "ts/ink_platform.h" -#include "I_Net.h" -#include "CongestionDB.h" -#include "Congestion.h" -#include "ControlMatcher.h" -#include "ProxyConfig.h" - -RecRawStatBlock *congest_rsb; - -InkRand CongestionRand(123); - -static const char *congestPrefix = "[CongestionControl]"; - -static const matcher_tags congest_dest_tags = {"dest_host", "dest_domain", "dest_ip", NULL, NULL, "host_regex", true}; - -/* default congestion control values */ - -char *DEFAULT_error_page = NULL; -int DEFAULT_max_connection_failures = 5; -int DEFAULT_fail_window = 120; -int DEFAULT_proxy_retry_interval = 10; -int DEFAULT_client_wait_interval = 300; -int DEFAULT_wait_interval_alpha = 30; -int DEFAULT_live_os_conn_timeout = 60; -int DEFAULT_live_os_conn_retries = 2; -int DEFAULT_dead_os_conn_timeout = 15; -int DEFAULT_dead_os_conn_retries = 1; -int DEFAULT_max_connection = -1; -char *DEFAULT_congestion_scheme_str = NULL; -int DEFAULT_congestion_scheme = PER_IP; - -/* congestion control limits */ -#define CONG_RULE_MAX_max_connection_failures (1 << (sizeof(cong_hist_t) * 8)) - -#define CONG_RULE_ULIMITED_max_connection_failures -1 -#define CONG_RULE_ULIMITED_mac_connection -1 - -struct CongestionMatcherTable : public ControlMatcher<CongestionControlRecord, CongestionControlRule>, public ConfigInfo { - CongestionMatcherTable(const char *file_var, const char *name, const matcher_tags *tags) - : ControlMatcher<CongestionControlRecord, CongestionControlRule>(file_var, name, tags) - { - } - - static void reconfigure(); - - static int configid; -}; - -int CongestionMatcherTable::configid = 0; - -static CongestionMatcherTable *CongestionMatcher = NULL; -static ConfigUpdateHandler<CongestionMatcherTable> *CongestionControlUpdate; -int congestionControlEnabled = 0; -int congestionControlLocalTime = 0; - -CongestionControlRecord::CongestionControlRecord(const CongestionControlRecord &rec) -{ - prefix = ats_strdup(rec.prefix); - prefix_len = rec.prefix_len; - port = rec.port; - congestion_scheme = rec.congestion_scheme; - error_page = ats_strdup(rec.error_page); - max_connection_failures = rec.max_connection_failures; - fail_window = rec.fail_window; - proxy_retry_interval = rec.proxy_retry_interval; - client_wait_interval = rec.client_wait_interval; - wait_interval_alpha = rec.wait_interval_alpha; - live_os_conn_timeout = rec.live_os_conn_timeout; - live_os_conn_retries = rec.live_os_conn_retries; - dead_os_conn_timeout = rec.dead_os_conn_timeout; - dead_os_conn_retries = rec.dead_os_conn_retries; - max_connection = rec.max_connection; - pRecord = NULL; - ref_count = 1; - line_num = rec.line_num; - rank = 0; -} - -void -CongestionControlRecord::setdefault() -{ - cleanup(); - congestion_scheme = DEFAULT_congestion_scheme; - port = 0; - prefix_len = 0; - rank = 0; - max_connection_failures = DEFAULT_max_connection_failures; - fail_window = DEFAULT_fail_window; - proxy_retry_interval = DEFAULT_proxy_retry_interval; - client_wait_interval = DEFAULT_client_wait_interval; - wait_interval_alpha = DEFAULT_wait_interval_alpha; - live_os_conn_timeout = DEFAULT_live_os_conn_timeout; - live_os_conn_retries = DEFAULT_live_os_conn_retries; - dead_os_conn_timeout = DEFAULT_dead_os_conn_timeout; - dead_os_conn_retries = DEFAULT_dead_os_conn_retries; - max_connection = DEFAULT_max_connection; -} - -Result -CongestionControlRecord::validate() -{ -#define IsGt0(var) \ - if (var < 1) { \ - cleanup(); \ - return Result::failure("line %d: invalid %s = %d, %s must > 0", line_num, #var, var, #var); \ - } - - if (error_page == NULL) { - error_page = ats_strdup(DEFAULT_error_page); - } - if (max_connection_failures >= CONG_RULE_MAX_max_connection_failures || - (max_connection_failures <= 0 && max_connection_failures != CONG_RULE_ULIMITED_max_connection_failures)) { - cleanup(); - return Result::failure("line %d: invalid %s = %d not in [1, %d) range", line_num, "max_connection_failures", - max_connection_failures, CONG_RULE_MAX_max_connection_failures); - } - - IsGt0(fail_window); - IsGt0(proxy_retry_interval); - IsGt0(client_wait_interval); - IsGt0(wait_interval_alpha); - IsGt0(live_os_conn_timeout); - IsGt0(live_os_conn_retries); - IsGt0(dead_os_conn_timeout); - IsGt0(dead_os_conn_retries); -// max_connection_failures <= 0 no failure num control -// max_connection == -1 no max_connection control -// max_connection_failures <= 0 && max_connection == -1 no congestion control for the rule -// max_connection == 0, no connection allow to the origin server for the rule -#undef IsGt0 - - return Result::ok(); -} - -Result -CongestionControlRecord::Init(matcher_line *line_info) -{ - const char *tmp; - char *label; - char *val; - line_num = line_info->line_num; - - /* initialize the rule to defaults */ - setdefault(); - - for (int i = 0; i < MATCHER_MAX_TOKENS; i++) { - label = line_info->line[0][i]; - val = line_info->line[1][i]; - - if (label == NULL) { - continue; - } - if (strcasecmp(label, "max_connection_failures") == 0) { - max_connection_failures = atoi(val); - } else if (strcasecmp(label, "fail_window") == 0) { - fail_window = atoi(val); - } else if (strcasecmp(label, "proxy_retry_interval") == 0) { - proxy_retry_interval = atoi(val); - } else if (strcasecmp(label, "client_wait_interval") == 0) { - client_wait_interval = atoi(val); - } else if (strcasecmp(label, "wait_interval_alpha") == 0) { - wait_interval_alpha = atoi(val); - } else if (strcasecmp(label, "live_os_conn_timeout") == 0) { - live_os_conn_timeout = atoi(val); - } else if (strcasecmp(label, "live_os_conn_retries") == 0) { - live_os_conn_retries = atoi(val); - } else if (strcasecmp(label, "dead_os_conn_timeout") == 0) { - dead_os_conn_timeout = atoi(val); - } else if (strcasecmp(label, "dead_os_conn_retries") == 0) { - dead_os_conn_retries = atoi(val); - } else if (strcasecmp(label, "max_connection") == 0) { - max_connection = atoi(val); - } else if (strcasecmp(label, "congestion_scheme") == 0) { - if (!strcasecmp(val, "per_ip")) { - congestion_scheme = PER_IP; - } else if (!strcasecmp(val, "per_host")) { - congestion_scheme = PER_HOST; - } else { - congestion_scheme = PER_IP; - } - } else if (strcasecmp(label, "error_page") == 0) { - error_page = ats_strdup(val); - } else if (strcasecmp(label, "prefix") == 0) { - prefix = ats_strdup(val); - prefix_len = strlen(prefix); - rank += 1; - // prefix will be used in the ControlBase - continue; - } else if (strcasecmp(label, "port") == 0) { - port = atoi(val); - rank += 2; - // port will be used in the ControlBase; - continue; - } else { - continue; - } - // Consume the label/value pair we used - line_info->line[0][i] = NULL; - line_info->num_el--; - } - if (line_info->num_el > 0) { - tmp = ProcessModifiers(line_info); - - if (tmp != NULL) { - return Result::failure("%s %s at line %d in congestion.config", congestPrefix, tmp, line_num); - } - } - - Result result = validate(); - if (result.failed()) { - return result; - } - - pRecord = new CongestionControlRecord(*this); - return Result::ok(); -} - -void -CongestionControlRecord::UpdateMatch(CongestionControlRule *pRule, RequestData *rdata) -{ - /* - * Select the first matching rule specified in congestion.config - * rank Matches - * 3 dest && prefix && port - * 2 dest && port - * 1 dest && prefix - * 0 dest - */ - if (pRule->record == 0 || pRule->record->rank < rank || (pRule->record->line_num > line_num && pRule->record->rank == rank)) { - if (rank > 0) { - CongestionEntry *entry = dynamic_cast<CongestionEntry *>(rdata); - if (entry) { - // Enforce the same port and prefix - if (port != 0 && port != entry->pRecord->port) { - return; - } - if (prefix != NULL && entry->pRecord->prefix == NULL) { - return; - } - if (prefix != NULL && strncmp(prefix, entry->pRecord->prefix, prefix_len)) { - return; - } - } else { - HttpRequestData *h = dynamic_cast<HttpRequestData *>(rdata); - if (h && !this->CheckModifiers(h)) { - return; - } - } - } - pRule->record = this; - Debug("congestion_config", "Matched with record %p at line %d", this, line_num); - } -} - -void -CongestionControlRecord::Print() -{ -#define PrintNUM(var) Debug("congestion_config", "%30s = %d", #var, var); -#define PrintSTR(var) Debug("congestion_config", "%30s = %s", #var, (var == NULL ? "NULL" : var)); - - PrintNUM(line_num); - PrintSTR(prefix); - PrintNUM(congestion_scheme); - PrintSTR(error_page); - PrintNUM(max_connection_failures); - PrintNUM(fail_window); - PrintNUM(proxy_retry_interval); - PrintNUM(client_wait_interval); - PrintNUM(wait_interval_alpha); - PrintNUM(live_os_conn_timeout); - PrintNUM(live_os_conn_retries); - PrintNUM(dead_os_conn_timeout); - PrintNUM(dead_os_conn_retries); - PrintNUM(max_connection); -#undef PrintNUM -#undef PrintSTR -} - -extern void initCongestionDB(); - -// place holder for congestion control enable config -static int -CongestionControlEnabledChanged(const char * /* name ATS_UNUSED */, RecDataT /* data_type ATS_UNUSED */, - RecData /* data ATS_UNUSED */, void * /* cookie ATS_UNUSED */) -{ - if (congestionControlEnabled == 1 || congestionControlEnabled == 2) { - revalidateCongestionDB(); - } - return 0; -} - -static int -CongestionControlDefaultSchemeChanged(const char * /* name ATS_UNUSED */, RecDataT /* data_type ATS_UNUSED */, - RecData /* data ATS_UNUSED */, void * /* cookie ATS_UNUSED */) -{ - if (strcasecmp(DEFAULT_congestion_scheme_str, "per_host") == 0) { - DEFAULT_congestion_scheme = PER_HOST; - } else { - DEFAULT_congestion_scheme = PER_IP; - } - return 0; -} - -//----------------------------------------------- -// hack for link the RegressionTest into the -// TS binary -//----------------------------------------------- -extern void init_CongestionRegressionTest(); - -void -initCongestionControl() -{ -// TODO: This is very, very strange, we run the regression tests even on a normal startup?? -#if TS_HAS_TESTS - init_CongestionRegressionTest(); -#endif - ink_assert(CongestionMatcher == NULL); - // register the stats variables - register_congest_stats(); - - CongestionControlUpdate = new ConfigUpdateHandler<CongestionMatcherTable>(); - - // register config variables - REC_EstablishStaticConfigInt32(congestionControlEnabled, "proxy.config.http.congestion_control.enabled"); - REC_EstablishStaticConfigInt32(DEFAULT_max_connection_failures, - "proxy.config.http.congestion_control.default.max_connection_failures"); - REC_EstablishStaticConfigInt32(DEFAULT_fail_window, "proxy.config.http.congestion_control.default.fail_window"); - REC_EstablishStaticConfigInt32(DEFAULT_proxy_retry_interval, "proxy.config.http.congestion_control.default.proxy_retry_interval"); - REC_EstablishStaticConfigInt32(DEFAULT_client_wait_interval, "proxy.config.http.congestion_control.default.client_wait_interval"); - REC_EstablishStaticConfigInt32(DEFAULT_wait_interval_alpha, "proxy.config.http.congestion_control.default.wait_interval_alpha"); - REC_EstablishStaticConfigInt32(DEFAULT_live_os_conn_timeout, "proxy.config.http.congestion_control.default.live_os_conn_timeout"); - REC_EstablishStaticConfigInt32(DEFAULT_live_os_conn_retries, "proxy.config.http.congestion_control.default.live_os_conn_retries"); - REC_EstablishStaticConfigInt32(DEFAULT_dead_os_conn_timeout, "proxy.config.http.congestion_control.default.dead_os_conn_timeout"); - REC_EstablishStaticConfigInt32(DEFAULT_dead_os_conn_retries, "proxy.config.http.congestion_control.default.dead_os_conn_retries"); - REC_EstablishStaticConfigInt32(DEFAULT_max_connection, "proxy.config.http.congestion_control.default.max_connection"); - REC_EstablishStaticConfigStringAlloc(DEFAULT_congestion_scheme_str, - "proxy.config.http.congestion_control.default.congestion_scheme"); - REC_EstablishStaticConfigStringAlloc(DEFAULT_error_page, "proxy.config.http.congestion_control.default.error_page"); - REC_EstablishStaticConfigInt32(congestionControlLocalTime, "proxy.config.http.congestion_control.localtime"); - { - RecData recdata; - recdata.rec_int = 0; - CongestionControlDefaultSchemeChanged(NULL, RECD_NULL, recdata, NULL); - } - - if (congestionControlEnabled) { - CongestionMatcherTable::reconfigure(); - } else { - Debug("congestion_config", "congestion control disabled"); - } - - RecRegisterConfigUpdateCb("proxy.config.http.congestion_control.default.congestion_scheme", - &CongestionControlDefaultSchemeChanged, NULL); - RecRegisterConfigUpdateCb("proxy.config.http.congestion_control.enabled", &CongestionControlEnabledChanged, NULL); - - CongestionControlUpdate->attach("proxy.config.http.congestion_control.filename"); -} - -void -CongestionMatcherTable::reconfigure() -{ - Note("congestion control config changed, reloading"); - CongestionMatcher = - new CongestionMatcherTable("proxy.config.http.congestion_control.filename", congestPrefix, &congest_dest_tags); - -#ifdef DEBUG_CONGESTION_MATCHER - CongestionMatcher->Print(); -#endif - - configid = configProcessor.set(configid, CongestionMatcher); - if (congestionControlEnabled) { - revalidateCongestionDB(); - } -} - -CongestionControlRecord * -CongestionControlled(RequestData *rdata) -{ - if (congestionControlEnabled) { - CongestionControlRule result; - CongestionMatcher->Match(rdata, &result); - if (result.record) { - return result.record->pRecord; - } - } else { - return NULL; - } - return NULL; -} - -uint64_t -make_key(char *hostname, sockaddr const *ip, CongestionControlRecord *record) -{ - int host_len = 0; - if (hostname) { - host_len = strlen(hostname); - } - return make_key(hostname, host_len, ip, record); -} - -uint64_t -make_key(char *hostname, int len, sockaddr const *ip, CongestionControlRecord *record) -{ - INK_MD5 md5; - INK_DIGEST_CTX ctx; - ink_code_incr_md5_init(&ctx); - if (record->congestion_scheme == PER_HOST && len > 0) { - ink_code_incr_md5_update(&ctx, hostname, len); - } else { - ink_code_incr_md5_update(&ctx, reinterpret_cast<const char *>(ats_ip_addr8_cast(ip)), ats_ip_addr_size(ip)); - } - if (record->port != 0) { - unsigned short p = record->port; - p = htons(p); - ink_code_incr_md5_update(&ctx, (char *)&p, 2); - } - if (record->prefix != NULL) { - ink_code_incr_md5_update(&ctx, record->prefix, record->prefix_len); - } - ink_code_incr_md5_final((char *)&md5, &ctx); - - return md5.fold(); -} - -uint64_t -make_key(char *hostname, int len, sockaddr const *ip, char *prefix, int prelen, short port) -{ - /* if the hostname != NULL, use hostname, else, use ip */ - INK_MD5 md5; - INK_DIGEST_CTX ctx; - ink_code_incr_md5_init(&ctx); - if (hostname && len > 0) { - ink_code_incr_md5_update(&ctx, hostname, len); - } else { - ink_code_incr_md5_update(&ctx, reinterpret_cast<const char *>(ats_ip_addr8_cast(ip)), ats_ip_addr_size(ip)); - } - if (port != 0) { - unsigned short p = port; - p = htons(p); - ink_code_incr_md5_update(&ctx, (char *)&p, 2); - } - if (prefix != NULL) { - ink_code_incr_md5_update(&ctx, prefix, prelen); - } - ink_code_incr_md5_final((char *)&md5, &ctx); - - return md5.fold(); -} - -//---------------------------------------------------------- -// FailHistory Implementation -//---------------------------------------------------------- -void -FailHistory::init(int window) -{ - bin_len = (window + CONG_HIST_ENTRIES) / CONG_HIST_ENTRIES; - if (bin_len <= 0) { - bin_len = 1; - } - length = bin_len * CONG_HIST_ENTRIES; - for (int i = 0; i < CONG_HIST_ENTRIES; i++) { - bins[i] = 0; - } - last_event = 0; - cur_index = 0; - events = 0; - start = 0; -} - -void -FailHistory::init_event(long t, int n) -{ - last_event = t; - cur_index = 0; - events = n; - bins[0] = n; - for (int i = 1; i < CONG_HIST_ENTRIES; i++) { - bins[i] = 0; - } - start = (last_event + bin_len) - last_event % bin_len - length; -} - -int -FailHistory::regist_event(long t, int n) -{ - if (t < start) { - return events; - } - if (t > last_event + length) { - init_event(t, n); - return events; - } - if (t < start + length) { - bins[((t - start) / bin_len + 1 + cur_index) % CONG_HIST_ENTRIES] += n; - } else { - do { - start += bin_len; - cur_index++; - if (cur_index == CONG_HIST_ENTRIES) { - cur_index = 0; - } - events -= bins[cur_index]; - bins[cur_index] = 0; - } while (start + length < t); - bins[cur_index] = n; - } - events += n; - if (last_event < t) { - last_event = t; - } - return events; -} - -//---------------------------------------------------------- -// CongestionEntry Implementation -//---------------------------------------------------------- -CongestionEntry::CongestionEntry(const char *hostname, sockaddr const *ip, CongestionControlRecord *rule, uint64_t key) - : m_key(key), - m_last_congested(0), - m_congested(0), - m_stat_congested_conn_failures(0), - m_M_congested(0), - m_last_M_congested(0), - m_num_connections(0), - m_stat_congested_max_conn(0), - m_ref_count(1) -{ - memset(&m_ip, 0, sizeof(m_ip)); - if (ip != NULL) { - ats_ip_copy(&m_ip.sa, ip); - } - m_hostname = ats_strdup(hostname); - rule->get(); - pRecord = rule; - clearFailHistory(); - m_hist_lock = new_ProxyMutex(); -} - -void -CongestionEntry::init(CongestionControlRecord *rule) -{ - if (pRecord) { - pRecord->put(); - } - rule->get(); - pRecord = rule; - clearFailHistory(); - - // TODO: This used to signal via SNMP - if ((pRecord->max_connection > m_num_connections) && ink_atomic_swap(&m_M_congested, 0)) { - // action not congested? - } -} - -bool -CongestionEntry::validate() -{ - CongestionControlRecord *p = CongestionControlled(this); - if (p == NULL) { - return false; - } - - uint64_t key = make_key(m_hostname, &m_ip.sa, p); - if (key != m_key) { - return false; - } - applyNewRule(p); - return true; -} - -void -CongestionEntry::applyNewRule(CongestionControlRecord *rule) -{ - if (pRecord->fail_window != rule->fail_window) { - init(rule); - return; - } - int mcf = pRecord->max_connection_failures; - pRecord->put(); - rule->get(); - pRecord = rule; - // TODO: This used to signal via SNMP - if (((pRecord->max_connection < 0) || (pRecord->max_connection > m_num_connections)) && ink_atomic_swap(&m_M_congested, 0)) { - // action not congested ? - } - // TODO: This used to signal via SNMP - if (pRecord->max_connection_failures < 0) { - if (ink_atomic_swap(&m_congested, 0)) { - // action not congested ? - } - return; - } - // TODO: This used to signal via SNMP - if (mcf < pRecord->max_connection_failures) { - if (ink_atomic_swap(&m_congested, 0)) { - // action not congested? - } - } else if (mcf > pRecord->max_connection_failures && m_history.events >= pRecord->max_connection_failures) { - if (!ink_atomic_swap(&m_congested, 1)) { - // action congested? - } - } -} - -int -CongestionEntry::sprint(char *buf, int buflen, int format) -{ - char str_time[100] = " "; - char addrbuf[INET6_ADDRSTRLEN]; - int len = 0; - ink_hrtime timestamp = 0; - char state; - if (pRecord->max_connection >= 0 && m_num_connections >= pRecord->max_connection) { - timestamp = ink_hrtime_to_sec(Thread::get_hrtime()); - state = 'M'; - } else { - timestamp = m_last_congested; - state = (m_congested ? 'F' : ' '); - } - len += snprintf(buf + len, buflen - len, "%" PRId64 "|%d|%s|%s", timestamp, pRecord->line_num, (m_hostname ? m_hostname : " "), - (ats_is_ip(&m_ip) ? ats_ip_ntop(&m_ip.sa, addrbuf, sizeof(addrbuf)) : " ")); - - len += snprintf(buf + len, buflen - len, "|%s|%s|%c", (pRecord->congestion_scheme == PER_IP ? "per_ip" : "per_host"), - (pRecord->prefix ? pRecord->prefix : " "), state); - - len += snprintf(buf + len, buflen - len, "|%d|%d", m_stat_congested_conn_failures, m_stat_congested_max_conn); - - if (format > 0) { - if (m_congested) { - struct tm time; - time_t seconds = m_last_congested; - if (congestionControlLocalTime) { - ink_localtime_r(&seconds, &time); - } else { - gmtime_r(&seconds, &time); - } - snprintf(str_time, sizeof(str_time), "%04d/%02d/%02d %02d:%02d:%02d", time.tm_year + 1900, time.tm_mon + 1, time.tm_mday, - time.tm_hour, time.tm_min, time.tm_sec); - } - len += snprintf(buf + len, buflen - len, "|%s", str_time); - - if (format > 1) { - len += snprintf(buf + len, buflen - len, "|%" PRIu64 "", m_key); - - if (format > 2) { - len += snprintf(buf + len, buflen - len, "|%ld", m_history.last_event); - - if (format > 3) { - len += snprintf(buf + len, buflen - len, "|%d|%d|%d", m_history.events, m_ref_count, m_num_connections); - } - } - } - } - len += snprintf(buf + len, buflen - len, "\n"); - return len; -} - -//------------------------------------------------------------- -// When a connection failure happened, try to get the lock -// first and change register the event, if we can not get -// the lock, discard the event -//------------------------------------------------------------- -void -CongestionEntry::failed_at(ink_hrtime t) -{ - if (pRecord->max_connection_failures == -1) { - return; - } - // long time = ink_hrtime_to_sec(t); - long time = t; - Debug("congestion_control", "failed_at: %ld", time); - MUTEX_TRY_LOCK(lock, m_hist_lock, this_ethread()); - if (lock.is_locked()) { - m_history.regist_event(time); - if (!m_congested) { - int32_t new_congested = compCongested(); - // TODO: This used to signal via SNMP - if (new_congested && !ink_atomic_swap(&m_congested, 1)) { - m_last_congested = m_history.last_event; - // action congested ? - } - } - } else { - Debug("congestion_control", "failure info lost due to lock contention(Entry: %p, Time: %ld)", (void *)this, time); - } -} - -void -CongestionEntry::go_alive() -{ - // TODO: This used to signal via SNMP - if (ink_atomic_swap(&m_congested, 0)) { - // Action not congested ? - } -} - -#define SERVER_CONGESTED_SIG REC_SIGNAL_HTTP_CONGESTED_SERVER -#define SERVER_ALLEVIATED_SIG REC_SIGNAL_HTTP_ALLEVIATED_SERVER diff --git a/proxy/congest/Congestion.h b/proxy/congest/Congestion.h deleted file mode 100644 index 9224a65..0000000 --- a/proxy/congest/Congestion.h +++ /dev/null @@ -1,470 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/***************************************************************************** - * - * Congestion.h - Implementation of Congestion Control - * - * - ****************************************************************************/ - -#ifndef CONGESTION_H_ -#define CONGESTION_H_ - -#include "ts/ink_platform.h" -#include "ts/Result.h" -#include "P_EventSystem.h" -#include "ControlBase.h" -#include "ControlMatcher.h" -#include "CongestionStats.h" - -#define CONGESTION_EVENT_CONGESTED_ON_M (CONGESTION_EVENT_EVENTS_START + 1) -#define CONGESTION_EVENT_CONGESTED_ON_F (CONGESTION_EVENT_EVENTS_START + 2) -#define CONGESTION_EVENT_CONGESTED_LIST_DONE (CONGESTION_EVENT_EVENTS_START + 3) -#define CONGESTION_EVENT_CONTROL_LOOKUP_DONE (CONGESTION_EVENT_EVENTS_START + 4) - -struct RequestData; - -extern InkRand CongestionRand; - -enum { - PER_IP, - PER_HOST, -}; - -class CongestionControlRecord; - -struct CongestionControlRule { - CongestionControlRule(); - ~CongestionControlRule(); - CongestionControlRecord *record; -}; - -class CongestionControlRecord : public ControlBase -{ -public: - CongestionControlRecord(); - CongestionControlRecord(const CongestionControlRecord &rec); - ~CongestionControlRecord(); - Result Init(matcher_line *line_info); - void UpdateMatch(CongestionControlRule *pRule, RequestData *rdata); - void Print(); - - void cleanup(); - void setdefault(); - Result validate(); - - int rank; // matching preference - /* - * Select the first matching rule specified in congestion.config - * rank Matches - * 3 dest && prefix && port - * 2 dest && port - * 1 dest && prefix - * 0 dest - */ - - char *prefix; - int prefix_len; - unsigned short port; - int congestion_scheme; - char *error_page; - - int max_connection_failures; - int fail_window; - int proxy_retry_interval; - int client_wait_interval; - int wait_interval_alpha; - int live_os_conn_timeout; - int live_os_conn_retries; - int dead_os_conn_timeout; - int dead_os_conn_retries; - int max_connection; - - CongestionControlRecord *pRecord; - int32_t ref_count; - - void - get() - { - ink_atomic_increment(&ref_count, 1); - } - void - put() - { - if (ink_atomic_increment(&ref_count, -1) == 1) - delete this; - } -}; - -inline CongestionControlRule::CongestionControlRule() : record(NULL) -{ -} - -inline CongestionControlRule::~CongestionControlRule() -{ - record = NULL; -} - -inline CongestionControlRecord::CongestionControlRecord() - : rank(0), - prefix(NULL), - prefix_len(0), - port(0), - congestion_scheme(PER_IP), - error_page(NULL), - max_connection_failures(5), - fail_window(120), - proxy_retry_interval(10), - client_wait_interval(300), - wait_interval_alpha(30), - live_os_conn_timeout(60), - live_os_conn_retries(2), - dead_os_conn_timeout(15), - dead_os_conn_retries(1), - max_connection(-1), - pRecord(NULL), - ref_count(0) -{ -} - -inline CongestionControlRecord::~CongestionControlRecord() -{ - cleanup(); -} -inline void -CongestionControlRecord::cleanup() -{ - if (pRecord) { - pRecord->put(); - pRecord = NULL; - } - ats_free(prefix), prefix = NULL; - ats_free(error_page), error_page = NULL; -} - -typedef unsigned short cong_hist_t; -#define CONG_HIST_ENTRIES 17 - -// CongestionEntry -struct FailHistory { - long start; - int bin_len; - int length; - cong_hist_t bins[CONG_HIST_ENTRIES]; - int cur_index; - long last_event; - int events; - - FailHistory() : start(0), bin_len(0), length(0), cur_index(0), last_event(0), events(0) { bzero((void *)&bins, sizeof(bins)); } - void init(int window); - void init_event(long t, int n = 1); - int regist_event(long t, int n = 1); - int - get_bin_events(int index) - { - return bins[(index + 1 + cur_index) % CONG_HIST_ENTRIES]; - } -}; - -struct CongestionEntry : public RequestData { - // key in the hash table; - uint64_t m_key; - // host info - IpEndpoint m_ip; - char *m_hostname; - - // Pointer to the congestion.config entry - // Remember to update the refcount of pRecord - CongestionControlRecord *pRecord; - - // State -- connection failures - FailHistory m_history; - Ptr<ProxyMutex> m_hist_lock; - ink_hrtime m_last_congested; - int m_congested; // 0 | 1 - int m_stat_congested_conn_failures; - - int m_M_congested; - ink_hrtime m_last_M_congested; - - // State -- concorrent connections - int m_num_connections; - int m_stat_congested_max_conn; - - // Reference count - int m_ref_count; - - CongestionEntry(const char *hostname, sockaddr const *ip, CongestionControlRecord *rule, uint64_t key); - CongestionEntry(); - virtual ~CongestionEntry(); - - /* RequestData virtural functions */ - virtual char * - get_string() - { - return pRecord->prefix; - } - virtual const char * - get_host() - { - return m_hostname; - } - virtual sockaddr const * - get_ip() - { - return &m_ip.sa; - } - virtual const sockaddr * - get_client_ip() - { - return NULL; - } - - /* print the entry into the congested list output buffer */ - int sprint(char *buf, int buflen, int format = 0); - - /* reference counter manipulation */ - void get(); - void put(); - - /* congestion control functions */ - // Is the server congested? - bool F_congested(); - bool M_congested(ink_hrtime t); - bool congested(); - - // Update state info - void go_alive(); - void failed_at(ink_hrtime t); - void connection_opened(); - void connection_closed(); - - // Connection controls - bool proxy_retry(ink_hrtime t); - int client_retry_after(); - int connect_retries(); - int connect_timeout(); - char * - getErrorPage() - { - return pRecord->error_page; - } - - // stats - void stat_inc_F(); - void stat_inc_M(); - - // fail history operations - void clearFailHistory(); - bool compCongested(); - - // CongestionEntry and CongestionControl rules interaction helper functions - bool usefulInfo(ink_hrtime t); - bool validate(); - void applyNewRule(CongestionControlRecord *rule); - void init(CongestionControlRecord *rule); -}; - -inline bool -CongestionEntry::usefulInfo(ink_hrtime t) -{ - return (m_ref_count > 1 || m_congested != 0 || m_num_connections > 0 || - (m_history.last_event + pRecord->fail_window > t && m_history.events > 0)); -} - -inline int -CongestionEntry::client_retry_after() -{ - int prat = 0; - if (F_congested()) { - prat = pRecord->proxy_retry_interval + m_history.last_event - ink_hrtime_to_sec(Thread::get_hrtime()); - if (prat < 0) - prat = 0; - } - return (prat + pRecord->client_wait_interval + CongestionRand.random() % pRecord->wait_interval_alpha); -} - -inline bool -CongestionEntry::proxy_retry(ink_hrtime t) -{ - return ((ink_hrtime_to_sec(t) - m_history.last_event) >= pRecord->proxy_retry_interval); -} - -inline bool -CongestionEntry::F_congested() -{ - return m_congested == 1; -} - -inline bool -CongestionEntry::M_congested(ink_hrtime t) -{ - if (pRecord->max_connection >= 0 && m_num_connections >= pRecord->max_connection) { - if (ink_atomic_swap(&m_M_congested, 1) == 0) { - m_last_M_congested = t; - // TODO: Used to signal congestions - } - return true; - } - return false; -} - -inline bool -CongestionEntry::congested() -{ - return (F_congested() || m_M_congested == 1); -} - -inline int -CongestionEntry::connect_retries() -{ - if (F_congested()) { - return pRecord->dead_os_conn_retries; - } else { - return pRecord->live_os_conn_retries; - } -} - -inline int -CongestionEntry::connect_timeout() -{ - if (F_congested()) { - return pRecord->dead_os_conn_timeout; - } else { - return pRecord->live_os_conn_timeout; - } -} - -inline void -CongestionEntry::stat_inc_F() -{ - ink_atomic_increment(&m_stat_congested_conn_failures, 1); -} - -inline void -CongestionEntry::stat_inc_M() -{ - ink_atomic_increment(&m_stat_congested_max_conn, 1); -} - -inline bool -CongestionEntry::compCongested() -{ - if (m_congested) - return true; - if (pRecord->max_connection_failures == -1) - return false; - return pRecord->max_connection_failures <= m_history.events; -} - -// return true when max_conn state changed -inline void -CongestionEntry::connection_opened() -{ - ink_atomic_increment(&m_num_connections, 1); -} - -// return true when max_conn state changed -inline void -CongestionEntry::connection_closed() -{ - ink_atomic_increment(&m_num_connections, -1); - if (ink_atomic_swap(&m_M_congested, 0) == 1) { - // TODO: Used to signal not congested - } -} - -inline void -CongestionEntry::clearFailHistory() -{ - m_history.init(pRecord->fail_window); - m_congested = 0; -} - -inline CongestionEntry::CongestionEntry() - : m_key(0), - m_hostname(NULL), - pRecord(NULL), - m_last_congested(0), - m_congested(0), - m_stat_congested_conn_failures(0), - m_M_congested(0), - m_last_M_congested(0), - m_num_connections(0), - m_stat_congested_max_conn(0), - m_ref_count(1) -{ - memset(&m_ip, 0, sizeof(m_ip)); - m_hist_lock = new_ProxyMutex(); -} - -inline CongestionEntry::~CongestionEntry() -{ - if (m_hostname) - ats_free(m_hostname), m_hostname = NULL; - m_hist_lock = NULL; - if (pRecord) - pRecord->put(), pRecord = NULL; -} - -inline void -CongestionEntry::get() -{ - ink_atomic_increment(&m_ref_count, 1); -} - -inline void -CongestionEntry::put() -{ - if (ink_atomic_increment(&m_ref_count, -1) == 1) { - delete this; - } -} - -// API to outside world - -extern int congestionControlEnabled; -extern int congestionControlLocalTime; - -void initCongestionControl(); -CongestionControlRecord *CongestionControlled(RequestData *rdata); - -uint64_t make_key(char *hostname, int len, sockaddr const *ip, CongestionControlRecord *record); -uint64_t make_key(char *hostname, sockaddr const *ip, CongestionControlRecord *record); -uint64_t make_key(char *hostname, int len, sockaddr const *ip, char *prefix, int prelen, short port = 0); - -//---------------------------------------------------- -// the following functions are actually declared in -// CongestionDB.h and defined in CongestionDB.cc -// They are included here only to make the -// editing & compiling process faster -//---------------------------------------------------- -extern Action *get_congest_entry(Continuation *cont, HttpRequestData *data, CongestionEntry **ppEntry); -extern Action *get_congest_list(Continuation *cont, MIOBuffer *buffer, int format); - -extern void remove_congested_entry(uint64_t key); -extern void remove_all_congested_entry(void); -extern void remove_congested_entry(char *buf, MIOBuffer *out_buffer); - -#endif /* CONGESTTION_H_ */ diff --git a/proxy/congest/CongestionDB.cc b/proxy/congest/CongestionDB.cc deleted file mode 100644 index 32be9c9..0000000 --- a/proxy/congest/CongestionDB.cc +++ /dev/null @@ -1,633 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/***************************************************************************** - * - * CongestionDB.cc - Implementation of congestion control datastore - * - * - ****************************************************************************/ -#include "ts/ink_platform.h" -#include "P_EventSystem.h" -#include "P_Net.h" -#include "Main.h" -#include "CongestionDB.h" -#include "Congestion.h" -#include "ProcessManager.h" - -#define SCHEDULE_CONGEST_CONT_INTERVAL HRTIME_MSECONDS(5) -int CONGESTION_DB_SIZE = 1024; - -CongestionDB *theCongestionDB = NULL; - -/* - * the CongestionDBCont is the continuation to do the congestion db related work - * when the CongestionDB's corresponding function does not get the lock in the - * first try - */ - -class CongestionDBCont : public Continuation -{ -public: - CongestionDBCont(); - int GC(int event, Event *e); - - int get_congest_list(int event, Event *e); - - int get_congest_entry(int event, Event *e); - - Action m_action; - - // To save momery, use a union here - union { - struct { - MIOBuffer *m_iobuf; - int m_CurPartitionID; - int m_list_format; // format of list - } list_info; - struct { - uint64_t m_key; - char *m_hostname; - IpEndpoint m_ip; - CongestionControlRecord *m_rule; - CongestionEntry **m_ppEntry; - } entry_info; - } data; -}; - -// MACRO's to save typing -#define CDBC_buf data.list_info.m_iobuf -#define CDBC_pid data.list_info.m_CurPartitionID -#define CDBC_lf data.list_info.m_list_format -#define CDBC_key data.entry_info.m_key -#define CDBC_host data.entry_info.m_hostname -#define CDBC_ip data.entry_info.m_ip -#define CDBC_rule data.entry_info.m_rule -#define CDBC_ppE data.entry_info.m_ppEntry - -inline CongestionDBCont::CongestionDBCont() : Continuation(NULL) -{ - memset(&data, 0, sizeof(data)); -} - -//-------------------------------------------------------------- -// class allocators -static ClassAllocator<CongestionDBCont> CongestionDBContAllocator("CongestionDBContAllocator"); - -inline void -Free_CongestionDBCont(CongestionDBCont *cont) -{ - cont->m_action = NULL; - cont->mutex = NULL; - CongestionDBContAllocator.free(cont); -} - -ClassAllocator<CongestRequestParam> CongestRequestParamAllocator("CongestRequestParamAllocator"); - -inline void -Free_CongestRequestParam(CongestRequestParam *param) -{ - CongestRequestParamAllocator.free(param); -} - -//----------------------------------------------------------------- -// CongestionDB implementation -//----------------------------------------------------------------- -/* - * CongestionDB(int tablesize) - * tablesize is the initial hashtable bucket number - */ -static long congestEntryGCTime = 0; - -// Before the garbage collection of the congestion db, set the -// current GC time, CongestionEntry::usefulInfo(t) will use the -// timestamp to determine if the entry contains useful infomation - -void -preCongestEntryGC(void) -{ - congestEntryGCTime = (long)ink_hrtime_to_sec(Thread::get_hrtime()); -} - -// if the entry contains useful info, return false -- keep it -// else return true -- delete it -bool -congestEntryGC(CongestionEntry *p) -{ - if (!p->usefulInfo(congestEntryGCTime)) { - p->put(); - return true; - } - return false; -} - -CongestionDB::CongestionDB(int tablesize) : CongestionTable(tablesize, &congestEntryGC, &preCongestEntryGC) -{ - ink_assert(tablesize > 0); - todo_lists = new InkAtomicList[MT_HASHTABLE_PARTITIONS]; - for (int i = 0; i < MT_HASHTABLE_PARTITIONS; i++) { - ink_atomiclist_init(&todo_lists[i], "cong_todo_list", (uintptr_t) & ((CongestRequestParam *)0)->link); - } -} - -/* - * There should be no entry in the DB, before you call the destructor - */ - -CongestionDB::~CongestionDB() -{ - delete[] todo_lists; -} - -void -CongestionDB::addRecord(uint64_t key, CongestionEntry *pEntry) -{ - ink_assert(key == pEntry->m_key); - pEntry->get(); - ProxyMutex *bucket_mutex = lock_for_key(key); - MUTEX_TRY_LOCK(lock, bucket_mutex, this_ethread()); - if (lock.is_locked()) { - RunTodoList(part_num(key)); - CongestionEntry *tmp = insert_entry(key, pEntry); - if (tmp) { - tmp->put(); - } - } else { - CongestRequestParam *param = CongestRequestParamAllocator.alloc(); - param->m_op = CongestRequestParam::ADD_RECORD; - param->m_key = key; - param->m_pEntry = pEntry; - ink_atomiclist_push(&todo_lists[part_num(key)], param); - } -} - -void -CongestionDB::removeAllRecords() -{ - CongestionEntry *tmp; - Iter it; - for (int part = 0; part < MT_HASHTABLE_PARTITIONS; part++) { - ProxyMutex *bucket_mutex = lock_for_key(part); - MUTEX_TRY_LOCK(lock, bucket_mutex, this_ethread()); - if (lock.is_locked()) { - RunTodoList(part); - tmp = first_entry(part, &it); - while (tmp) { - remove_entry(part, &it); - tmp->put(); - tmp = cur_entry(part, &it); - } - } else { - CongestRequestParam *param = CongestRequestParamAllocator.alloc(); - param->m_op = CongestRequestParam::REMOVE_ALL_RECORDS; - param->m_key = part; - ink_atomiclist_push(&todo_lists[part], param); - } - } -} - -void -CongestionDB::removeRecord(uint64_t key) -{ - CongestionEntry *tmp; - ProxyMutex *bucket_mutex = lock_for_key(key); - MUTEX_TRY_LOCK(lock, bucket_mutex, this_ethread()); - if (lock.is_locked()) { - RunTodoList(part_num(key)); - tmp = remove_entry(key); - if (tmp) { - tmp->put(); - } - } else { - CongestRequestParam *param = CongestRequestParamAllocator.alloc(); - param->m_op = CongestRequestParam::REMOVE_RECORD; - param->m_key = key; - ink_atomiclist_push(&todo_lists[part_num(key)], param); - } -} - -// process one item in the to do list -void -CongestionDB::process(int buckId, CongestRequestParam *param) -{ - CongestionEntry *pEntry = NULL; - switch (param->m_op) { - case CongestRequestParam::ADD_RECORD: - pEntry = insert_entry(param->m_key, param->m_pEntry); - if (pEntry) { - pEntry->put(); - } - break; - case CongestRequestParam::REMOVE_ALL_RECORDS: { - CongestionEntry *tmp; - Iter it; - tmp = first_entry(param->m_key, &it); - while (tmp) { - remove_entry(param->m_key, &it); - tmp->put(); - tmp = cur_entry(param->m_key, &it); - } - break; - } - case CongestRequestParam::REMOVE_RECORD: - pEntry = remove_entry(param->m_key); - if (pEntry) { - pEntry->put(); - } - break; - case CongestRequestParam::REVALIDATE_BUCKET: - revalidateBucket(buckId); - break; - default: - ink_assert(!"CongestionDB::process unrecognized op"); - } -} - -void -CongestionDB::RunTodoList(int buckId) -{ - CongestRequestParam *param = NULL, *cur = NULL; - if ((param = (CongestRequestParam *)ink_atomiclist_popall(&todo_lists[buckId])) != NULL) { - /* start the work at the end of the list */ - param->link.prev = NULL; - while (param->link.next) { - param->link.next->link.prev = param; - param = param->link.next; - }; - while (param) { - process(buckId, param); - cur = param; - param = param->link.prev; - Free_CongestRequestParam(cur); - } - } -} - -void -CongestionDB::revalidateBucket(int buckId) -{ - Iter it; - CongestionEntry *cur = NULL; - cur = first_entry(buckId, &it); - while (cur != NULL) { - if (!cur->validate()) { - remove_entry(buckId, &it); - cur->put(); - // the next entry has been moved to the current pos - // because of the remove_entry - cur = cur_entry(buckId, &it); - } else { - cur = next_entry(buckId, &it); - } - } -} - -//----------------------------------------------------------------- -// CongestionDBCont implementation -//----------------------------------------------------------------- - -int -CongestionDBCont::GC(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) -{ - if (congestionControlEnabled == 1 || congestionControlEnabled == 2) { - if (theCongestionDB == NULL) { - goto Ldone; - } - for (; CDBC_pid < theCongestionDB->getSize(); CDBC_pid++) { - ProxyMutex *bucket_mutex = theCongestionDB->lock_for_key(CDBC_pid); - { - MUTEX_TRY_LOCK(lock, bucket_mutex, this_ethread()); - if (lock.is_locked()) { - ink_hrtime now = Thread::get_hrtime(); - now = ink_hrtime_to_sec(now); - theCongestionDB->RunTodoList(CDBC_pid); - Iter it; - CongestionEntry *pEntry = theCongestionDB->first_entry(CDBC_pid, &it); - while (pEntry) { - if (!pEntry->usefulInfo(now)) { - theCongestionDB->remove_entry(CDBC_pid, &it); - pEntry->put(); - pEntry = theCongestionDB->cur_entry(CDBC_pid, &it); - } - } - } else { - Debug("congestion_db", "flush gc missed the lock [%d], retry", CDBC_pid); - return EVENT_CONT; - } - } - } - } -Ldone: - CDBC_pid = 0; - return EVENT_DONE; -} - -int -CongestionDBCont::get_congest_list(int /* event ATS_UNUSED */, Event *e) -{ - if (m_action.cancelled) { - Free_CongestionDBCont(this); - return EVENT_DONE; - } - for (; CDBC_pid < theCongestionDB->getSize(); CDBC_pid++) { - ProxyMutex *bucket_mutex = theCongestionDB->lock_for_key(CDBC_pid); - { - MUTEX_TRY_LOCK(lock_bucket, bucket_mutex, this_ethread()); - if (!lock_bucket.is_locked()) { - e->schedule_in(SCHEDULE_CONGEST_CONT_INTERVAL); - return EVENT_CONT; - } else { - theCongestionDB->RunTodoList(CDBC_pid); - char buf[1024]; - Iter it; - int len; - CongestionEntry *pEntry = theCongestionDB->first_entry(CDBC_pid, &it); - while (pEntry) { - if ((pEntry->congested() && pEntry->pRecord->max_connection != 0) || CDBC_lf > 10) { - len = pEntry->sprint(buf, 1024, CDBC_lf); - CDBC_buf->write(buf, len); - } - pEntry = theCongestionDB->next_entry(CDBC_pid, &it); - } - } - } - } - - /* handle event done */ - m_action.continuation->handleEvent(CONGESTION_EVENT_CONGESTED_LIST_DONE, NULL); - Free_CongestionDBCont(this); - return EVENT_DONE; -} - -int -CongestionDBCont::get_congest_entry(int /* event ATS_UNUSED */, Event *e) -{ - Debug("congestion_control", "cont::get_congest_entry started"); - - if (m_action.cancelled) { - Debug("congestion_cont", "action cancelled for %p", this); - Free_CongestionDBCont(this); - Debug("congestion_control", "cont::get_congest_entry state machine canceled"); - return EVENT_DONE; - } - ProxyMutex *bucket_mutex = theCongestionDB->lock_for_key(CDBC_key); - MUTEX_TRY_LOCK(lock_bucket, bucket_mutex, this_ethread()); - if (lock_bucket.is_locked()) { - theCongestionDB->RunTodoList(theCongestionDB->part_num(CDBC_key)); - *CDBC_ppE = theCongestionDB->lookup_entry(CDBC_key); - if (*CDBC_ppE != NULL) { - CDBC_rule->put(); - (*CDBC_ppE)->get(); - Debug("congestion_control", "cont::get_congest_entry entry found"); - m_action.continuation->handleEvent(CONGESTION_EVENT_CONTROL_LOOKUP_DONE, NULL); - } else { - /* create a new entry and add it to the congestDB */ - *CDBC_ppE = new CongestionEntry(CDBC_host, &CDBC_ip.sa, CDBC_rule, CDBC_key); - CDBC_rule->put(); - (*CDBC_ppE)->get(); - theCongestionDB->insert_entry(CDBC_key, *CDBC_ppE); - Debug("congestion_control", "cont::get_congest_entry new entry created"); - m_action.continuation->handleEvent(CONGESTION_EVENT_CONTROL_LOOKUP_DONE, NULL); - } - Free_CongestionDBCont(this); - return EVENT_DONE; - } else { - Debug("congestion_control", "cont::get_congest_entry MUTEX_TRY_LOCK failed"); - e->schedule_in(SCHEDULE_CONGEST_CONT_INTERVAL); - return EVENT_CONT; - } -} - -//----------------------------------------------------------------- -// Global fuctions implementation -//----------------------------------------------------------------- - -void -initCongestionDB() -{ - if (theCongestionDB == NULL) { - theCongestionDB = new CongestionDB(CONGESTION_DB_SIZE / MT_HASHTABLE_PARTITIONS); - } -} - -void -revalidateCongestionDB() -{ - ProxyMutex *bucket_mutex; - if (theCongestionDB == NULL) { - theCongestionDB = new CongestionDB(CONGESTION_DB_SIZE / MT_HASHTABLE_PARTITIONS); - return; - } - Debug("congestion_config", "congestion control revalidating CongestionDB"); - for (int i = 0; i < theCongestionDB->getSize(); i++) { - bucket_mutex = theCongestionDB->lock_for_key(i); - { - MUTEX_TRY_LOCK(lock_bucket, bucket_mutex, this_ethread()); - if (lock_bucket.is_locked()) { - theCongestionDB->RunTodoList(i); - theCongestionDB->revalidateBucket(i); - } else { - CongestRequestParam *param = CongestRequestParamAllocator.alloc(); - param->m_op = CongestRequestParam::REVALIDATE_BUCKET; - ink_atomiclist_push(&theCongestionDB->todo_lists[i], param); - } - } - } - Debug("congestion_config", "congestion control revalidating CongestionDB Done"); -} - -Action * -get_congest_entry(Continuation *cont, HttpRequestData *data, CongestionEntry **ppEntry) -{ - if (congestionControlEnabled != 1 && congestionControlEnabled != 2) { - return ACTION_RESULT_DONE; - } - Debug("congestion_control", "congestion control get_congest_entry start"); - - CongestionControlRecord *p = CongestionControlled(data); - Debug("congestion_control", "Control Matcher matched rule_num %d", p == NULL ? -1 : p->line_num); - if (p == NULL) { - return ACTION_RESULT_DONE; - } - // if the fail_window <= 0 and the max_connection == -1, then no congestion control - if (p->max_connection_failures <= 0 && p->max_connection < 0) { - return ACTION_RESULT_DONE; - } - uint64_t key = make_key((char *)data->get_host(), data->get_ip(), p); - Debug("congestion_control", "Key = %" PRIu64 "", key); - - ProxyMutex *bucket_mutex = theCongestionDB->lock_for_key(key); - MUTEX_TRY_LOCK(lock_bucket, bucket_mutex, this_ethread()); - if (lock_bucket.is_locked()) { - theCongestionDB->RunTodoList(theCongestionDB->part_num(key)); - *ppEntry = theCongestionDB->lookup_entry(key); - if (*ppEntry != NULL) { - (*ppEntry)->get(); - Debug("congestion_control", "get_congest_entry, found entry %p done", (void *)*ppEntry); - return ACTION_RESULT_DONE; - } else { - // create a new entry and add it to the congestDB - *ppEntry = new CongestionEntry(data->get_host(), data->get_ip(), p, key); - (*ppEntry)->get(); - theCongestionDB->insert_entry(key, *ppEntry); - Debug("congestion_control", "get_congest_entry, new entry %p done", (void *)*ppEntry); - return ACTION_RESULT_DONE; - } - } else { - Debug("congestion_control", "get_congest_entry, trylock failed, schedule cont"); - CongestionDBCont *Ccont = CongestionDBContAllocator.alloc(); - Ccont->m_action = cont; - Ccont->mutex = cont->mutex; - Ccont->CDBC_key = key; - Ccont->CDBC_host = (char *)data->get_host(); - ats_ip_copy(&Ccont->CDBC_ip.sa, data->get_ip()); - p->get(); - Ccont->CDBC_rule = p; - Ccont->CDBC_ppE = ppEntry; - - SET_CONTINUATION_HANDLER(Ccont, &CongestionDBCont::get_congest_entry); - eventProcessor.schedule_in(Ccont, SCHEDULE_CONGEST_CONT_INTERVAL, ET_NET); - return &Ccont->m_action; - } -} - -Action * -get_congest_list(Continuation *cont, MIOBuffer *buffer, int format) -{ - if (theCongestionDB == NULL || (congestionControlEnabled != 1 && congestionControlEnabled != 2)) { - return ACTION_RESULT_DONE; - } - for (int i = 0; i < theCongestionDB->getSize(); i++) { - ProxyMutex *bucket_mutex = theCongestionDB->lock_for_key(i); - { - MUTEX_TRY_LOCK(lock_bucket, bucket_mutex, this_ethread()); - if (lock_bucket.is_locked()) { - theCongestionDB->RunTodoList(i); - char buf[1024]; - Iter it; - int len; - CongestionEntry *pEntry = theCongestionDB->first_entry(i, &it); - while (pEntry) { - if ((pEntry->congested() && pEntry->pRecord->max_connection != 0) || format > 10) { - len = pEntry->sprint(buf, 1024, format); - buffer->write(buf, len); - } - pEntry = theCongestionDB->next_entry(i, &it); - } - } else { - /* we did not get the lock, schedule it */ - CongestionDBCont *CCcont = CongestionDBContAllocator.alloc(); - CCcont->CDBC_pid = i; - CCcont->CDBC_buf = buffer; - CCcont->m_action = cont; - CCcont->mutex = cont->mutex; - CCcont->CDBC_lf = format; - SET_CONTINUATION_HANDLER(CCcont, &CongestionDBCont::get_congest_list); - eventProcessor.schedule_in(CCcont, SCHEDULE_CONGEST_CONT_INTERVAL, ET_NET); - return &CCcont->m_action; - } - } - } - return ACTION_RESULT_DONE; -} - -/* - * this function is to suport removing the congested state for a - * specific server when the administrator knows it is online again - */ - -void -remove_all_congested_entry() -{ - if (theCongestionDB != NULL) { - theCongestionDB->removeAllRecords(); - } -} - -void -remove_congested_entry(uint64_t key) -{ - if (theCongestionDB != NULL) { - theCongestionDB->removeRecord(key); - } -} - -//-------------------------------------------------------------- -// remove_congested_entry(char* buf, MIOBuffer *out_buffer) -// INPUT: buf -// format: "all", -// "host=<hostname>[/<prefix>]", -// "ip=<ip addr>[/<prefix>]", -// "key=<internal key>" -// OUTPUT: out_buffer -// message to the Raf -//-------------------------------------------------------------- -void -remove_congested_entry(char *buf, MIOBuffer *out_buffer) -{ - const int MSG_LEN = 512; - char msg[MSG_LEN + 1]; - int len = 0; - uint64_t key; - if (strcasecmp(buf, "all") == 0) { - remove_all_congested_entry(); - len = snprintf(msg, MSG_LEN, "all entries in congestion control table removed\n"); - // coverity[secure_coding] - } else if (sscanf(buf, "key=%" PRIu64 "", &key) == 1) { - remove_congested_entry(key); - len = snprintf(msg, MSG_LEN, "key %" PRIu64 " removed\n", key); - } else if (strncasecmp(buf, "host=", 5) == 0) { - char *p = buf + 5; - char *prefix = strchr(p, '/'); - int prelen = 0; - if (prefix) { - *prefix = '\0'; - prefix++; - prelen = strlen(prefix); - } - key = make_key(p, strlen(p), 0, prefix, prelen); - remove_congested_entry(key); - len = snprintf(msg, MSG_LEN, "host=%s prefix=%s removed\n", p, prefix ? prefix : "(nil)"); - } else if (strncasecmp(buf, "ip=", 3) == 0) { - IpEndpoint ip; - memset(&ip, 0, sizeof(ip)); - - char *p = buf + 3; - char *prefix = strchr(p, '/'); - int prelen = 0; - if (prefix) { - *prefix = '\0'; - prefix++; - prelen = strlen(prefix); - } - ats_ip_pton(p, &ip); - if (!ats_is_ip(&ip)) { - len = snprintf(msg, MSG_LEN, "invalid ip: %s\n", buf); - } else { - key = make_key(NULL, 0, &ip.sa, prefix, prelen); - remove_congested_entry(key); - len = snprintf(msg, MSG_LEN, "ip=%s prefix=%s removed\n", p, prefix ? prefix : "(nil)"); - } - } - out_buffer->write(msg, len); -} diff --git a/proxy/congest/CongestionDB.h b/proxy/congest/CongestionDB.h deleted file mode 100644 index 84b78ff..0000000 --- a/proxy/congest/CongestionDB.h +++ /dev/null @@ -1,106 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/***************************************************************************** - * - * CongestionDB.h - Implementation of Congestion Control - * - * - ****************************************************************************/ - -/* - * CongestionDB is implemented in a Multithread-Safe hash table - * the Data will be wrote to a disk file for recovery purpose. - */ -#ifndef CongestionDB_H_ -#define CongestionDB_H_ - -#include "P_EventSystem.h" -#include "MT_hashtable.h" -#include "ControlMatcher.h" - -class CongestionControlRecord; -struct CongestionEntry; - -typedef MTHashTable<uint64_t, CongestionEntry *> CongestionTable; -typedef HashTableIteratorState<uint64_t, CongestionEntry *> Iter; - -/* API to the outside world */ -// check whether key was congested, store the found entry into pEntry -Action *get_congest_entry(Continuation *cont, HttpRequestData *data, CongestionEntry **ppEntry); -Action *get_congest_list(Continuation *cont, MIOBuffer *buffer, int format = 0); -void remove_all_congested_entry(void); -void remove_congested_entry(uint64_t key); -void remove_congested_entry(char *buf, MIOBuffer *out_buffer); -void revalidateCongestionDB(); -void initCongestionDB(); - -/* - * CongestRequestParam is the data structure passed to the request - * to update the congestion db with the appropriate info - * It is used when the TS missed a try_lock, the request info will be - * stored in the CongestRequestParam and insert in the to-do list of the - * approperiate DB partition. - * The first operation after the TS get the lock for a partition is - * to run the to do list - */ - -struct CongestRequestParam { - enum Op_t { - ADD_RECORD, - REMOVE_RECORD, - REMOVE_ALL_RECORDS, - REVALIDATE_BUCKET, - }; - - CongestRequestParam() : m_key(0), m_op(REVALIDATE_BUCKET), m_pEntry(NULL) {} - ~CongestRequestParam() {} - uint64_t m_key; - Op_t m_op; - CongestionEntry *m_pEntry; - - LINK(CongestRequestParam, link); -}; - -/* struct declaration and definitions */ -class CongestionDB : public CongestionTable -{ -public: - CongestionDB(int tablesize); - ~CongestionDB(); - bool congested(uint64_t key); - - // add an entry to the db - void addRecord(uint64_t key, CongestionEntry *pEntry); - // remove an entry from the db - void removeRecord(uint64_t key); - void removeAllRecords(void); - InkAtomicList *todo_lists; - void RunTodoList(int buckId); - void process(int buckId, CongestRequestParam *param); - void revalidateBucket(int buckId); -}; - -extern CongestionDB *theCongestionDB; - -#endif /* CongestionDB_H_ */ diff --git a/proxy/congest/CongestionStats.cc b/proxy/congest/CongestionStats.cc deleted file mode 100644 index 8f2e13c..0000000 --- a/proxy/congest/CongestionStats.cc +++ /dev/null @@ -1,50 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/***************************************************************************** - * - * CongestionStats.cc - Implementation of Congestion Control - * - * - ****************************************************************************/ - -#include "CongestionStats.h" - -void -register_congest_stats() -{ -#define CONGEST_CLEAR_DYN_STAT(x) \ - do { \ - RecSetRawStatSum(congest_rsb, x, 0); \ - RecSetRawStatCount(congest_rsb, x, 0); \ - } while (0); - - congest_rsb = RecAllocateRawStatBlock((int)congest_num_stats); - RecRegisterRawStat(congest_rsb, RECT_PROCESS, "proxy.process.congestion.congested_on_conn_failures", RECD_INT, - RECP_NON_PERSISTENT, (int)congested_on_F_stat, RecRawStatSyncSum); - CONGEST_CLEAR_DYN_STAT(congested_on_F_stat); - - RecRegisterRawStat(congest_rsb, RECT_PROCESS, "proxy.process.congestion.congested_on_max_connection", RECD_INT, - RECP_NON_PERSISTENT, (int)congested_on_M_stat, RecRawStatSyncSum); - CONGEST_CLEAR_DYN_STAT(congested_on_M_stat); -} diff --git a/proxy/congest/CongestionStats.h b/proxy/congest/CongestionStats.h deleted file mode 100644 index 0d5a90f..0000000 --- a/proxy/congest/CongestionStats.h +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/***************************************************************************** - * - * CongestionStats.h - Implementation of Congestion Control - * - * - ****************************************************************************/ -#ifndef CONGESTION_STATS_H_ -#define CONGESTION_STATS_H_ - -void register_congest_stats(); -#include "P_RecProcess.h" -extern RecRawStatBlock *congest_rsb; - -/* Instead of enumerating the stats in DynamicStats.h, each module needs - to enumerate its stats separately and register them with librecords - */ -enum { - congested_on_F_stat, - congested_on_M_stat, - congest_num_stats, -}; -#define CONGEST_SUM_GLOBAL_DYN_STAT(_x, _y) RecIncrGlobalRawStatSum(congest_rsb, (int)_x, _y) -#define CONGEST_INCREMENT_DYN_STAT(_x) RecIncrRawStat(congest_rsb, mutex->thread_holding, (int)_x, 1) - -#endif /* CONGESTION_STATS_H_ */ diff --git a/proxy/congest/CongestionTest.cc b/proxy/congest/CongestionTest.cc deleted file mode 100644 index d9b6275..0000000 --- a/proxy/congest/CongestionTest.cc +++ /dev/null @@ -1,568 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/***************************************************************************** - * - * CongestionTest.cc - Regression Test of the congestion control module - * - * - ****************************************************************************/ -#include "ts/ink_platform.h" -#include "Main.h" -#include "CongestionDB.h" -#include "Congestion.h" - -//------------------------------------------------------------- -// Test the HashTable implementation -//------------------------------------------------------------- -/* all of the elements inserted into the HashTable should be in the - * table and can be easily retrived - * also exercise the resizing of the table - */ -EXCLUSIVE_REGRESSION_TEST(Congestion_HashTable)(RegressionTest *t, int /* atype ATS_UNUSED */, int *pstatus) -{ - MTHashTable<long, long> *htable = new MTHashTable<long, long>(4); - // add elements to the table; - long i, count = 1 * 1024 * 1024; - rprintf(t, "adding data into the hash table .", count); - for (i = 1; i <= count; i++) { - htable->insert_entry(i, i); - if (i % (count / 50) == 0) { - fprintf(stderr, "."); - } - } - fprintf(stderr, "done\n"); - rprintf(t, "%d data added into the hash table\n", count); - rprintf(t, "verifying the content"); - for (i = 1; i <= count; i++) { - long data = htable->lookup_entry(i); - if (i % (count / 50) == 0) { - fprintf(stderr, "."); - } - if (data != i) { - rprintf(t, "verify content failed: key(%d) data(%d)\n", i, data); - *pstatus = REGRESSION_TEST_FAILED; - return; - } - } - fprintf(stderr, "done\n"); - long removed_count = 0; - // delete some data - rprintf(t, "removing data."); - for (i = 1; i < count / 2; i++) { - htable->remove_entry(i * 2); - if (i % (count / 50) == 0) { - fprintf(stderr, "."); - } - removed_count++; - } - fprintf(stderr, "done\n"); - - rprintf(t, "%d data entries are removed\n", removed_count); - rprintf(t, "verify the content again"); - for (i = 1; i <= count; i++) { - long data = htable->lookup_entry(i); - if (i % 2 == 1 && data == 0) { - rprintf(t, "verify content failed: key(%d) deleted\n", i); - *pstatus = REGRESSION_TEST_FAILED; - delete htable; - return; - } - if (data != 0 && data != i) { - rprintf(t, "verify content failed: key(%d) data(%d)\n", i, data); - *pstatus = REGRESSION_TEST_FAILED; - delete htable; - return; - } - if (i % (count / 50) == 0) { - fprintf(stderr, "."); - } - } - fprintf(stderr, "done\n"); - - rprintf(t, "use iterator to list all the elements and delete half of them"); - HashTableIteratorState<long, long> it; - int j, new_count = 0; - for (j = 0; j < MT_HASHTABLE_PARTITIONS; j++) { - int data = htable->first_entry(j, &it); - while (data > 0) { - new_count++; - if (new_count % (count / 25) == 0) { - fprintf(stderr, "."); - } - - if (new_count % 2 == 0) { - htable->remove_entry(j, &it); - data = htable->cur_entry(j, &it); - removed_count++; - } else { - data = htable->next_entry(j, &it); - } - } - } - fprintf(stderr, "done\n"); - - rprintf(t, "verify the content once again"); - new_count = count - removed_count; - for (j = 0; j < MT_HASHTABLE_PARTITIONS; j++) { - int data = htable->first_entry(j, &it); - while (data > 0) { - new_count--; - if (new_count % (count / 25) == 0) { - fprintf(stderr, "."); - } - data = htable->next_entry(j, &it); - if (data != htable->lookup_entry(data)) { - rprintf(t, "verify content failed: key(%d) data(%d)\n", data, htable->lookup_entry(data)); - *pstatus = REGRESSION_TEST_FAILED; - delete htable; - return; - } - } - } - - fprintf(stderr, "done\n"); - if (new_count != 0) { - rprintf(t, "there are %d extra entries in the table\n", new_count); - *pstatus = REGRESSION_TEST_FAILED; - delete htable; - return; - } - - rprintf(t, "remove everything using iterator"); - new_count = count - removed_count; - for (j = 0; j < MT_HASHTABLE_PARTITIONS; j++) { - int data = htable->first_entry(j, &it); - while (data > 0) { - new_count--; - if (new_count % (count / 25) == 0) { - fprintf(stderr, "."); - } - htable->remove_entry(j, &it); - data = htable->cur_entry(j, &it); - } - } - - fprintf(stderr, "done\n"); - if (new_count != 0) { - rprintf(t, "there are %d extra entries in the table\n", new_count); - *pstatus = REGRESSION_TEST_FAILED; - delete htable; - return; - } - - delete htable; - *pstatus = REGRESSION_TEST_PASSED; -} - -//------------------------------------------------------------- -// Test the FailHistory implementation -//------------------------------------------------------------- -/* register events into the FailHistory and the number of events - * should be correct - */ -struct CCFailHistoryTestCont : public Continuation { - enum { - FAIL_WINDOW = 300, - }; - - enum { - SIMPLE_TEST, - MULTIPLE_THREAD_TEST, - ROTATING_TEST, - }; - - int mainEvent(int event, Event *e); - CCFailHistoryTestCont() : Continuation(new_ProxyMutex()) {} - - CCFailHistoryTestCont(Ptr<ProxyMutex> _mutex, RegressionTest *_test) - : Continuation(_mutex), - test_mode(SIMPLE_TEST), - final_status(REGRESSION_TEST_PASSED), - complete(false), - test(_test), - failEvents(NULL), - pending_action(NULL) - { - SET_HANDLER(&CCFailHistoryTestCont::mainEvent); - rule = new CongestionControlRecord; - rule->fail_window = FAIL_WINDOW; - rule->max_connection_failures = 10; - rule->pRecord = new CongestionControlRecord(*rule); - entry = new CongestionEntry("dummy_host", 0, rule->pRecord, 0); - } - - ~CCFailHistoryTestCont() - { - if (pending_action) { - pending_action->cancel(); - } - entry->put(); - delete rule; - clear_events(); - } - - void init_events(); - void clear_events(); - int check_history(bool print); - int schedule_event(int event, Event *e); - - struct FailEvents { - time_t time; - Link<FailEvents> link; - }; - - int test_mode = SIMPLE_TEST; - int final_status = 0; - bool complete = false; - RegressionTest *test = nullptr; - InkAtomicList *failEvents = nullptr; - CongestionControlRecord *rule = nullptr; - CongestionEntry *entry = nullptr; - Action *pending_action = nullptr; -}; - -void -CCFailHistoryTestCont::clear_events() -{ - if (failEvents) { - CCFailHistoryTestCont::FailEvents *events = (CCFailHistoryTestCont::FailEvents *)ink_atomiclist_popall(failEvents); - while (events != NULL) { - CCFailHistoryTestCont::FailEvents *next = events->link.next; - delete events; - events = next; - } - delete failEvents; - failEvents = NULL; - } -} - -void -CCFailHistoryTestCont::init_events() -{ - clear_events(); - - failEvents = new InkAtomicList; - ink_atomiclist_init(failEvents, "failEvents", (uintptr_t) & ((CCFailHistoryTestCont::FailEvents *)0)->link); - - int i, j; - CCFailHistoryTestCont::FailEvents *new_event = NULL; - - switch (test_mode) { - case CCFailHistoryTestCont::ROTATING_TEST: - for (i = 0; i < 16384; i++) { - for (j = 0; j < 10; j++) { - new_event = new CCFailHistoryTestCont::FailEvents; - // coverity[secure_coding] - new_event->time = rand() % (FAIL_WINDOW) + j * FAIL_WINDOW; - ink_atomiclist_push(failEvents, new_event); - } - } - break; - case CCFailHistoryTestCont::SIMPLE_TEST: - default: - for (i = 0; i < 65536; i++) { - new_event = new CCFailHistoryTestCont::FailEvents; - // coverity[secure_coding] - new_event->time = rand() % FAIL_WINDOW; - ink_atomiclist_push(failEvents, new_event); - } - } -} - -int -CCFailHistoryTestCont::schedule_event(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) -{ - if (failEvents == NULL) { - return EVENT_DONE; - } - CCFailHistoryTestCont::FailEvents *f = (CCFailHistoryTestCont::FailEvents *)ink_atomiclist_pop(failEvents); - if (f != NULL) { - entry->failed_at(f->time); - delete f; - return EVENT_CONT; - } - return EVENT_DONE; -} - -int -CCFailHistoryTestCont::check_history(bool print) -{ - if (print) { - rprintf(test, "Verify the result\n"); - rprintf(test, "Content of history\n"); - int e = 0; - for (int i = 0; i < CONG_HIST_ENTRIES; i++) { - e += entry->m_history.bins[i]; - rprintf(test, "bucket %d => events %d , sum = %d\n", i, entry->m_history.bins[i], e); - } - fprintf(stderr, "Events: %d, CurIndex: %d, LastEvent: %ld, HistLen: %d, BinLen: %d, Start: %ld\n", entry->m_history.events, - entry->m_history.cur_index, entry->m_history.last_event, entry->m_history.length, entry->m_history.bin_len, - entry->m_history.start); - char buf[1024]; - entry->sprint(buf, 1024, 10); - rprintf(test, "%s", buf); - } - if (test_mode == CCFailHistoryTestCont::SIMPLE_TEST && entry->m_history.events == 65536) { - return 0; - } - return 0; -} - -int -CCFailHistoryTestCont::mainEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) -{ - test_mode = CCFailHistoryTestCont::SIMPLE_TEST; - init_events(); - entry->init(rule->pRecord); - while (schedule_event(0, NULL) == EVENT_CONT) { - ; - } - if (check_history(true) == 0) { - final_status = REGRESSION_TEST_PASSED; - } else { - final_status = REGRESSION_TEST_FAILED; - goto Ldone; - } - - test_mode = CCFailHistoryTestCont::ROTATING_TEST; - init_events(); - entry->init(rule->pRecord); - while (schedule_event(0, NULL) == EVENT_CONT) { - ; - } - if (check_history(true) == 0) { - final_status = REGRESSION_TEST_PASSED; - } else { - final_status = REGRESSION_TEST_FAILED; - goto Ldone; - } - -Ldone: - complete = true; - if (complete) { - test->status = final_status; - delete this; - return EVENT_DONE; - } - return EVENT_CONT; -} - -EXCLUSIVE_REGRESSION_TEST(Congestion_FailHistory)(RegressionTest *t, int /* atype ATS_UNUSED */, int *pstatus) -{ - CCFailHistoryTestCont *test = new CCFailHistoryTestCont(make_ptr(new_ProxyMutex()), t); - eventProcessor.schedule_in(test, HRTIME_SECONDS(1)); - *pstatus = REGRESSION_TEST_INPROGRESS; -} - -//------------------------------------------------------------- -// Test the CongestionDB implementation -//------------------------------------------------------------- -/* Insert simulated CongestionEntry into the CongestionDB and - * exercise the GC of the DB, remove entries from DB - */ - -struct CCCongestionDBTestCont : public Continuation { - int final_status; - bool complete; - RegressionTest *test; - - int mainEvent(int event, Event *e); - - void init(); - int get_congest_list(); - CongestionControlRecord *rule; - CongestionDB *db; - int dbsize; - CongestionEntry *gen_CongestionEntry(sockaddr const *ip, int congested = 0); - - CCCongestionDBTestCont(Ptr<ProxyMutex> _mutex, RegressionTest *_test) - : Continuation(_mutex), final_status(REGRESSION_TEST_PASSED), complete(false), test(_test), rule(NULL), db(NULL), dbsize(1024) - { - SET_HANDLER(&CCCongestionDBTestCont::mainEvent); - } - virtual ~CCCongestionDBTestCont() - { - if (db) { - db->removeAllRecords(); - delete db; - } - if (rule) { - delete rule; - } - } -}; - -CongestionEntry * -CCCongestionDBTestCont::gen_CongestionEntry(sockaddr const *ip, int congested) -{ - char hostname[INET6_ADDRSTRLEN]; - uint64_t key; - ats_ip_ntop(ip, hostname, sizeof(hostname)); - key = make_key(hostname, strlen(hostname), ip, rule->pRecord); - CongestionEntry *ret = new CongestionEntry(hostname, ip, rule->pRecord, key); - ret->m_congested = congested; - ret->m_ref_count = 0; - return ret; -} - -void -CCCongestionDBTestCont::init() -{ - // create/clear db - if (!db) { - db = new CongestionDB(dbsize / MT_HASHTABLE_PARTITIONS); - } else { - db->removeAllRecords(); - } - if (!rule) { - rule = new CongestionControlRecord; - rule->fail_window = 300; - rule->max_connection_failures = 10; - rule->pRecord = new CongestionControlRecord(*rule); - } -} - -int -CCCongestionDBTestCont::get_congest_list() -{ - int cnt = 0; - if (db == NULL) { - return 0; - } - for (int i = 0; i < db->getSize(); i++) { - db->RunTodoList(i); - char buf[1024]; - Iter it; - - CongestionEntry *pEntry = db->first_entry(i, &it); - while (pEntry) { - cnt++; - if (cnt % 100 == 0) { - pEntry->sprint(buf, 1024, 100); - fprintf(stderr, "%s", buf); - } - pEntry = db->next_entry(i, &it); - } - } - return cnt; -} - -int -CCCongestionDBTestCont::mainEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) -{ - int to_add = 1 * 1024 * 1024; - int i; - int items[10] = {0}; - init(); - rprintf(test, "Add %d records into the db", dbsize); - - for (i = 0; i < dbsize; i++) { - if (i % (dbsize / 25) == 0) { - fprintf(stderr, "."); - } - - IpEndpoint ip; - ats_ip4_set(&ip, i + 255); - - CongestionEntry *tmp = gen_CongestionEntry(&ip.sa); - db->addRecord(tmp->m_key, tmp); - } - fprintf(stderr, "done\n"); - - items[0] = get_congest_list(); - - db->removeAllRecords(); - - rprintf(test, "There are %d records in the db\n", items[0]); - - rprintf(test, "Add %d records into the db", to_add); - for (i = 0; i < to_add; i++) { - if (i % (to_add / 25) == 0) { - fprintf(stderr, "."); - } - - IpEndpoint ip; - ats_ip4_set(&ip, i + 255); - CongestionEntry *tmp = gen_CongestionEntry(&ip.sa); - db->addRecord(tmp->m_key, tmp); - } - - items[1] = get_congest_list(); - - db->removeAllRecords(); - - rprintf(test, "There are %d records in the db\n", items[1]); - - rprintf(test, "Add %d congested records into the db", to_add); - - for (i = 0; i < to_add; i++) { - if (i % (to_add / 25) == 0) { - fprintf(stderr, "."); - } - - IpEndpoint ip; - ats_ip4_set(&ip, i + 255); - - CongestionEntry *tmp = gen_CongestionEntry(&ip.sa, 1); - db->addRecord(tmp->m_key, tmp); - } - items[2] = get_congest_list(); - rprintf(test, "There are %d records in the db\n", items[2]); - - db->removeAllRecords(); - - for (i = 0; i < 3; i++) { - rprintf(test, "After test [%d] there are %d records in the db\n", i + 1, items[i]); - } - - complete = true; - if (complete) { - test->status = final_status; - delete this; - return EVENT_DONE; - } - return EVENT_CONT; -} - -EXCLUSIVE_REGRESSION_TEST(Congestion_CongestionDB)(RegressionTest *t, int /* atype ATS_UNUSED */, int *pstatus) -{ - CCCongestionDBTestCont *test = new CCCongestionDBTestCont(make_ptr(new_ProxyMutex()), t); - eventProcessor.schedule_in(test, HRTIME_SECONDS(1)); - *pstatus = REGRESSION_TEST_INPROGRESS; -} - -//------------------------------------------------------------- -// Test the CongestionControl implementation -//------------------------------------------------------------- -/* test the whole thing - * 1. Match rules - * 2. Apply new rules - */ -void -init_CongestionRegressionTest() -{ - (void)regressionTest_Congestion_HashTable; - (void)regressionTest_Congestion_FailHistory; - (void)regressionTest_Congestion_CongestionDB; -} diff --git a/proxy/congest/MT_hashtable.h b/proxy/congest/MT_hashtable.h deleted file mode 100644 index 05aee5e..0000000 --- a/proxy/congest/MT_hashtable.h +++ /dev/null @@ -1,433 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/**************************************************************************** - - MT_hashtable.h - - Multithread Safe Hash table implementation - - - ****************************************************************************/ -#ifndef MT_HASHTABLE_H_ -#define MT_HASHTABLE_H_ -//#include "Lock.h" - -#define MT_HASHTABLE_PARTITION_BITS 6 -#define MT_HASHTABLE_PARTITIONS (1 << MT_HASHTABLE_PARTITION_BITS) -#define MT_HASHTABLE_PARTITION_MASK (MT_HASHTABLE_PARTITIONS - 1) -#define MT_HASHTABLE_MAX_CHAIN_AVG_LEN 4 -template <class key_t, class data_t> struct HashTableEntry { - key_t key; - data_t data; - HashTableEntry *next; - - static HashTableEntry * - alloc() - { - return (HashTableEntry *)ats_malloc(sizeof(HashTableEntry)); - } - - static void - free(HashTableEntry *entry) - { - ats_free(entry); - } -}; - -/* -struct MT_ListEntry{ - MT_ListEntry():next(NULL),prev(NULL){} - MT_ListEntry* next; - MT_ListEntry* prev; -}; - -#define INIT_CHAIN_HEAD(h) {(h)->next = (h)->prev = (h);} -#define APPEND_TO_CHAIN(h, p) {(p)->next = (h)->next; (h)->next->prev = (p); (p)->prev = (h); (h)->next = (p);} -#define REMOVE_FROM_CHAIN(p) {(p)->next->prev = (p)->prev; (p)->prev->next = (p)->next; (p)->prev = (p)->next = NULL;} -#define GET_OBJ_PTR(p, type, offset) ((type*)((char*)(p) - offset)) -*/ - -template <class key_t, class data_t> class HashTableIteratorState -{ -public: - HashTableIteratorState() : cur_buck(-1), ppcur(NULL) {} - int cur_buck; - HashTableEntry<key_t, data_t> **ppcur; -}; - -template <class key_t, class data_t> class IMTHashTable -{ -public: - IMTHashTable(int size, bool (*gc_func)(data_t) = NULL, void (*pre_gc_func)(void) = NULL) - { - m_gc_func = gc_func; - m_pre_gc_func = pre_gc_func; - bucket_num = size; - cur_size = 0; - buckets = new HashTableEntry<key_t, data_t> *[bucket_num]; - memset(buckets, 0, bucket_num * sizeof(HashTableEntry<key_t, data_t> *)); - } - ~IMTHashTable() { reset(); } - int - getBucketNum() - { - return bucket_num; - } - int - getCurSize() - { - return cur_size; - } - - int - bucket_id(key_t key, int a_bucket_num) - { - return (int)(((key >> MT_HASHTABLE_PARTITION_BITS) ^ key) % a_bucket_num); - } - - int - bucket_id(key_t key) - { - return bucket_id(key, bucket_num); - } - - void - reset() - { - HashTableEntry<key_t, data_t> *tmp; - for (int i = 0; i < bucket_num; i++) { - tmp = buckets[i]; - while (tmp) { - buckets[i] = tmp->next; - HashTableEntry<key_t, data_t>::free(tmp); - tmp = buckets[i]; - } - } - delete[] buckets; - buckets = NULL; - } - - data_t insert_entry(key_t key, data_t data); - data_t remove_entry(key_t key); - data_t lookup_entry(key_t key); - - data_t first_entry(int bucket_id, HashTableIteratorState<key_t, data_t> *s); - static data_t next_entry(HashTableIteratorState<key_t, data_t> *s); - static data_t cur_entry(HashTableIteratorState<key_t, data_t> *s); - data_t remove_entry(HashTableIteratorState<key_t, data_t> *s); - - void - GC(void) - { - if (m_gc_func == NULL) - return; - if (m_pre_gc_func) - m_pre_gc_func(); - for (int i = 0; i < bucket_num; i++) { - HashTableEntry<key_t, data_t> *cur = buckets[i]; - HashTableEntry<key_t, data_t> *prev = NULL; - HashTableEntry<key_t, data_t> *next = NULL; - while (cur != NULL) { - next = cur->next; - if (m_gc_func(cur->data)) { - if (prev != NULL) - prev->next = next; - else - buckets[i] = next; - ats_free(cur); - cur_size--; - } else { - prev = cur; - } - cur = next; - } - } - } - - void - resize(int size) - { - int new_bucket_num = size; - HashTableEntry<key_t, data_t> **new_buckets = new HashTableEntry<key_t, data_t> *[new_bucket_num]; - memset(new_buckets, 0, new_bucket_num * sizeof(HashTableEntry<key_t, data_t> *)); - - for (int i = 0; i < bucket_num; i++) { - HashTableEntry<key_t, data_t> *cur = buckets[i]; - HashTableEntry<key_t, data_t> *next = NULL; - while (cur != NULL) { - next = cur->next; - int new_id = bucket_id(cur->key, new_bucket_num); - cur->next = new_buckets[new_id]; - new_buckets[new_id] = cur; - cur = next; - } - buckets[i] = NULL; - } - delete[] buckets; - buckets = new_buckets; - bucket_num = new_bucket_num; - } - -private: - HashTableEntry<key_t, data_t> **buckets; - int cur_size; - int bucket_num; - bool (*m_gc_func)(data_t); - void (*m_pre_gc_func)(void); - -private: - IMTHashTable(); - IMTHashTable(IMTHashTable &); -}; - -/* - * we can use ClassAllocator here if the malloc performance becomes a problem - */ - -template <class key_t, class data_t> -inline data_t -IMTHashTable<key_t, data_t>::insert_entry(key_t key, data_t data) -{ - int id = bucket_id(key); - HashTableEntry<key_t, data_t> *cur = buckets[id]; - while (cur != NULL && cur->key != key) { - cur = cur->next; - } - if (cur != NULL) { - if (data == cur->data) - return (data_t)0; - else { - data_t tmp = cur->data; - cur->data = data; - // potential memory leak, need to check the return value by the caller - return tmp; - } - } - - HashTableEntry<key_t, data_t> *newEntry = HashTableEntry<key_t, data_t>::alloc(); - newEntry->key = key; - newEntry->data = data; - newEntry->next = buckets[id]; - buckets[id] = newEntry; - cur_size++; - if (cur_size / bucket_num > MT_HASHTABLE_MAX_CHAIN_AVG_LEN) { - GC(); - if (cur_size / bucket_num > MT_HASHTABLE_MAX_CHAIN_AVG_LEN) - resize(bucket_num * 2); - } - return (data_t)0; -} - -template <class key_t, class data_t> -inline data_t -IMTHashTable<key_t, data_t>::remove_entry(key_t key) -{ - int id = bucket_id(key); - data_t ret = (data_t)0; - HashTableEntry<key_t, data_t> *cur = buckets[id]; - HashTableEntry<key_t, data_t> *prev = NULL; - while (cur != NULL && cur->key != key) { - prev = cur; - cur = cur->next; - } - if (cur != NULL) { - if (prev != NULL) - prev->next = cur->next; - else - buckets[id] = cur->next; - ret = cur->data; - HashTableEntry<key_t, data_t>::free(cur); - cur_size--; - } - - return ret; -} - -template <class key_t, class data_t> -inline data_t -IMTHashTable<key_t, data_t>::lookup_entry(key_t key) -{ - int id = bucket_id(key); - data_t ret = (data_t)0; - HashTableEntry<key_t, data_t> *cur = buckets[id]; - while (cur != NULL && cur->key != key) { - cur = cur->next; - } - if (cur != NULL) { - ret = cur->data; - } - return ret; -} - -template <class key_t, class data_t> -inline data_t -IMTHashTable<key_t, data_t>::first_entry(int bucket_id, HashTableIteratorState<key_t, data_t> *s) -{ - s->cur_buck = bucket_id; - s->ppcur = &(buckets[bucket_id]); - if (*(s->ppcur) != NULL) - return (*(s->ppcur))->data; - return (data_t)0; -} - -template <class key_t, class data_t> -inline data_t -IMTHashTable<key_t, data_t>::next_entry(HashTableIteratorState<key_t, data_t> *s) -{ - if ((*(s->ppcur)) != NULL) { - s->ppcur = &((*(s->ppcur))->next); - if (*(s->ppcur) != NULL) - return (*(s->ppcur))->data; - } - return (data_t)0; -} - -template <class key_t, class data_t> -inline data_t -IMTHashTable<key_t, data_t>::cur_entry(HashTableIteratorState<key_t, data_t> *s) -{ - if (*(s->ppcur) == NULL) - return (data_t)0; - return (*(s->ppcur))->data; -} - -template <class key_t, class data_t> -inline data_t -IMTHashTable<key_t, data_t>::remove_entry(HashTableIteratorState<key_t, data_t> *s) -{ - data_t data = (data_t)0; - HashTableEntry<key_t, data_t> *pEntry = *(s->ppcur); - if (pEntry != NULL) { - data = pEntry->data; - (*(s->ppcur)) = pEntry->next; - HashTableEntry<key_t, data_t>::free(pEntry); - cur_size--; - } - return data; -} - -template <class key_t, class data_t> class MTHashTable -{ -public: - MTHashTable(int size, bool (*gc_func)(data_t) = NULL, void (*pre_gc_func)(void) = NULL) - { - for (int i = 0; i < MT_HASHTABLE_PARTITIONS; i++) { - locks[i] = new_ProxyMutex(); - hashTables[i] = new IMTHashTable<key_t, data_t>(size, gc_func, pre_gc_func); - // INIT_CHAIN_HEAD(&chain_heads[i]); - // last_GC_time[i] = 0; - } - // cur_items = 0; - } - ~MTHashTable() - { - for (int i = 0; i < MT_HASHTABLE_PARTITIONS; i++) { - locks[i] = NULL; - delete hashTables[i]; - } - } - - ProxyMutex * - lock_for_key(key_t key) - { - return locks[part_num(key)].get(); - } - - int - getSize() - { - return MT_HASHTABLE_PARTITIONS; - } - int - part_num(key_t key) - { - return (int)(key & MT_HASHTABLE_PARTITION_MASK); - } - data_t - insert_entry(key_t key, data_t data) - { - // ink_atomic_increment(&cur_items, 1); - return hashTables[part_num(key)]->insert_entry(key, data); - } - data_t - remove_entry(key_t key) - { - // ink_atomic_increment(&cur_items, -1); - return hashTables[part_num(key)]->remove_entry(key); - } - data_t - lookup_entry(key_t key) - { - return hashTables[part_num(key)]->lookup_entry(key); - } - - data_t - first_entry(int part_id, HashTableIteratorState<key_t, data_t> *s) - { - data_t ret = (data_t)0; - for (int i = 0; i < hashTables[part_id]->getBucketNum(); i++) { - ret = hashTables[part_id]->first_entry(i, s); - if (ret != (data_t)0) - return ret; - } - return (data_t)0; - } - - data_t - cur_entry(int part_id, HashTableIteratorState<key_t, data_t> *s) - { - data_t data = IMTHashTable<key_t, data_t>::cur_entry(s); - if (!data) - data = next_entry(part_id, s); - return data; - }; - data_t - next_entry(int part_id, HashTableIteratorState<key_t, data_t> *s) - { - data_t ret = IMTHashTable<key_t, data_t>::next_entry(s); - if (ret != (data_t)0) - return ret; - for (int i = s->cur_buck + 1; i < hashTables[part_id]->getBucketNum(); i++) { - ret = hashTables[part_id]->first_entry(i, s); - if (ret != (data_t)0) - return ret; - } - return (data_t)0; - } - data_t - remove_entry(int part_id, HashTableIteratorState<key_t, data_t> *s) - { - // ink_atomic_increment(&cur_items, -1); - return hashTables[part_id]->remove_entry(s); - } - -private: - IMTHashTable<key_t, data_t> *hashTables[MT_HASHTABLE_PARTITIONS]; - Ptr<ProxyMutex> locks[MT_HASHTABLE_PARTITIONS]; - // MT_ListEntry chain_heads[MT_HASHTABLE_PARTITIONS]; - // int last_GC_time[MT_HASHTABLE_PARTITIONS]; - // int32_t cur_items; -}; - -#endif /* MT_HASHTABLE_H_ */ diff --git a/proxy/http/HttpDebugNames.cc b/proxy/http/HttpDebugNames.cc index a67d574..b72a50c 100644 --- a/proxy/http/HttpDebugNames.cc +++ b/proxy/http/HttpDebugNames.cc @@ -212,14 +212,6 @@ HttpDebugNames::get_event_name(int event) return ("HTTP_TUNNEL_EVENT_CONSUMER_DETACH"); ////////////////////////////// - // CongestionControl Events - ////////////////////////////// - case CONGESTION_EVENT_CONGESTED_ON_F: - return ("CONGESTION_EVENT_CONGESTED_ON_F"); - case CONGESTION_EVENT_CONGESTED_ON_M: - return ("CONGESTION_EVENT_CONGESTED_ON_M"); - - ////////////////////////////// // Plugin Events ////////////////////////////// case HTTP_API_CONTINUE: diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 1fee0ff..9d0a7a5 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -46,7 +46,6 @@ #include "IPAllow.h" //#include "I_Auth.h" //#include "HttpAuthParams.h" -#include "congest/Congestion.h" #include "ts/I_Layout.h" #define DEFAULT_RESPONSE_BUFFER_SIZE_INDEX 6 // 8K @@ -1090,10 +1089,6 @@ HttpSM::state_raw_http_server_open(int event, void *data) case NET_EVENT_OPEN: - if (t_state.pCongestionEntry != nullptr) { - t_state.pCongestionEntry->connection_opened(); - t_state.congestion_connection_opened = 1; - } // Record the VC in our table server_entry = vc_table.new_entry(); server_entry->vc = netvc = (NetVConnection *)data; @@ -1106,21 +1101,9 @@ HttpSM::state_raw_http_server_open(int event, void *data) case VC_EVENT_ERROR: case NET_EVENT_OPEN_FAILED: - if (t_state.pCongestionEntry != nullptr) { - t_state.current.state = HttpTransact::CONNECTION_ERROR; - call_transact_and_set_next_state(HttpTransact::HandleResponse); - return 0; - } else { - t_state.current.state = HttpTransact::OPEN_RAW_ERROR; - // use this value just to get around other values - t_state.hdr_info.response_error = HttpTransact::STATUS_CODE_SERVER_ERROR; - } - break; - case CONGESTION_EVENT_CONGESTED_ON_F: - t_state.current.state = HttpTransact::CONGEST_CONTROL_CONGESTED_ON_F; - break; - case CONGESTION_EVENT_CONGESTED_ON_M: - t_state.current.state = HttpTransact::CONGEST_CONTROL_CONGESTED_ON_M; + t_state.current.state = HttpTransact::OPEN_RAW_ERROR; + // use this value just to get around other values + t_state.hdr_info.response_error = HttpTransact::STATUS_CODE_SERVER_ERROR; break; default: @@ -1806,14 +1789,6 @@ HttpSM::state_http_server_open(int event, void *data) call_transact_and_set_next_state(HttpTransact::HandleResponse); } return 0; - case CONGESTION_EVENT_CONGESTED_ON_F: - t_state.current.state = HttpTransact::CONGEST_CONTROL_CONGESTED_ON_F; - call_transact_and_set_next_state(HttpTransact::HandleResponse); - return 0; - case CONGESTION_EVENT_CONGESTED_ON_M: - t_state.current.state = HttpTransact::CONGEST_CONTROL_CONGESTED_ON_M; - call_transact_and_set_next_state(HttpTransact::HandleResponse); - return 0; default: Error("[HttpSM::state_http_server_open] Unknown event: %d", event); @@ -4735,23 +4710,6 @@ HttpSM::do_http_server_open(bool raw) } } - // Congestion Check - if (t_state.pCongestionEntry != nullptr) { - if (t_state.pCongestionEntry->F_congested() && - (!t_state.pCongestionEntry->proxy_retry(milestones[TS_MILESTONE_SERVER_CONNECT]))) { - t_state.congestion_congested_or_failed = 1; - t_state.pCongestionEntry->stat_inc_F(); - CONGEST_INCREMENT_DYN_STAT(congested_on_F_stat); - handleEvent(CONGESTION_EVENT_CONGESTED_ON_F, nullptr); - return; - } else if (t_state.pCongestionEntry->M_congested(ink_hrtime_to_sec(milestones[TS_MILESTONE_SERVER_CONNECT]))) { - t_state.pCongestionEntry->stat_inc_M(); - t_state.congestion_congested_or_failed = 1; - CONGEST_INCREMENT_DYN_STAT(congested_on_M_stat); - handleEvent(CONGESTION_EVENT_CONGESTED_ON_M, nullptr); - return; - } - } // If this is not a raw connection, we try to get a session from the // shared session pool. Raw connections are for SSLs tunnel and // require a new connection @@ -5028,8 +4986,6 @@ HttpSM::do_http_server_open(bool raw) connect_timeout = t_state.txn_conf->post_connect_attempts_timeout; } else if (t_state.current.server == &t_state.parent_info) { connect_timeout = t_state.txn_conf->parent_connect_timeout; - } else if (t_state.pCongestionEntry != nullptr) { - connect_timeout = t_state.pCongestionEntry->connect_timeout(); } else { connect_timeout = t_state.txn_conf->connect_attempts_timeout; } @@ -5373,13 +5329,6 @@ HttpSM::handle_http_server_open() } } - if (t_state.pCongestionEntry != nullptr) { - if (t_state.congestion_connection_opened == 0) { - t_state.congestion_connection_opened = 1; - t_state.pCongestionEntry->connection_opened(); - } - } - int method = t_state.hdr_info.server_request.method_get_wksidx(); if (method != HTTP_WKSIDX_TRACE && (t_state.hdr_info.request_content_length > 0 || t_state.client_info.transfer_encoding == HttpTransact::CHUNKED_ENCODING) && @@ -5924,9 +5873,6 @@ HttpSM::attach_server_session(HttpServerSession *s) } else { connect_timeout = t_state.txn_conf->connect_attempts_timeout; } - if (t_state.pCongestionEntry != nullptr) { - connect_timeout = t_state.pCongestionEntry->connect_timeout(); - } if (t_state.api_txn_connect_timeout_value != -1) { server_session->get_netvc()->set_inactivity_timeout(HRTIME_MSECONDS(t_state.api_txn_connect_timeout_value)); @@ -6850,12 +6796,6 @@ HttpSM::kill_this() plugin_tunnel = nullptr; } - if (t_state.pCongestionEntry != nullptr) { - if (t_state.congestion_congested_or_failed != 1) { - t_state.pCongestionEntry->go_alive(); - } - } - ink_assert(pending_action == nullptr); ink_release_assert(vc_table.is_table_clear() == true); ink_release_assert(tunnel.is_tunnel_active() == false); @@ -7334,13 +7274,6 @@ HttpSM::set_next_state() } case HttpTransact::SM_ACTION_ORIGIN_SERVER_OPEN: { - if (congestionControlEnabled && (t_state.congest_saved_next_action == HttpTransact::SM_ACTION_UNDEFINED)) { - t_state.congest_saved_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_OPEN; - HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_congestion_control_lookup); - if (!do_congestion_control_lookup()) { - break; - } - } HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_http_server_open); // We need to close the previous attempt @@ -7530,14 +7463,6 @@ HttpSM::set_next_state() } case HttpTransact::SM_ACTION_ORIGIN_SERVER_RAW_OPEN: { - if (congestionControlEnabled && (t_state.congest_saved_next_action == HttpTransact::SM_ACTION_UNDEFINED)) { - t_state.congest_saved_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_RAW_OPEN; - HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_congestion_control_lookup); - if (!do_congestion_control_lookup()) { - break; - } - } - HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_raw_http_server_open); ink_assert(server_entry == nullptr); @@ -7620,43 +7545,6 @@ clear_http_handler_times() { } -bool -HttpSM::do_congestion_control_lookup() -{ - ink_assert(pending_action == nullptr); - - Action *congestion_control_action_handle = get_congest_entry(this, &t_state.request_data, &t_state.pCongestionEntry); - if (congestion_control_action_handle != ACTION_RESULT_DONE) { - pending_action = congestion_control_action_handle; - return false; - } - - return true; -} - -int -HttpSM::state_congestion_control_lookup(int event, void *data) -{ - STATE_ENTER(&HttpSM::state_congestion_control_lookup, event); - if (event == CONGESTION_EVENT_CONTROL_LOOKUP_DONE) { - pending_action = nullptr; - t_state.next_action = t_state.congest_saved_next_action; - t_state.transact_return_point = nullptr; - set_next_state(); - } else { - if (pending_action != nullptr) { - pending_action->cancel(); - pending_action = nullptr; - } - if (t_state.congest_saved_next_action == HttpTransact::SM_ACTION_ORIGIN_SERVER_OPEN) { - return state_http_server_open(event, data); - } else if (t_state.congest_saved_next_action == HttpTransact::SM_ACTION_ORIGIN_SERVER_RAW_OPEN) { - return state_raw_http_server_open(event, data); - } - } - return 0; -} - // YTS Team, yamsat Plugin void diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index 3110d05..21fe894 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -399,7 +399,6 @@ protected: int state_auth_callback(int event, void *data); int state_add_to_list(int event, void *data); int state_remove_from_list(int event, void *data); - int state_congestion_control_lookup(int event, void *data); // Y! ebalsa: remap handlers int state_remap_request(int event, void *data); @@ -456,8 +455,6 @@ protected: void do_drain_request_body(); #endif - bool do_congestion_control_lookup(); - virtual void handle_api_return(); void handle_server_setup_error(int event, void *data); void handle_http_server_open(); diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index 88a0e3e..ca93ea2 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -3465,13 +3465,6 @@ HttpTransact::handle_response_from_server(State *s) s->current.server->clear_connect_fail(); handle_forward_server_connection_open(s); break; - case CONGEST_CONTROL_CONGESTED_ON_F: - case CONGEST_CONTROL_CONGESTED_ON_M: - TxnDebug("http_trans", "[handle_response_from_server] Error. congestion control -- congested."); - SET_VIA_STRING(VIA_DETAIL_SERVER_CONNECT, VIA_DETAIL_SERVER_FAILURE); - s->current.server->set_connect_fail(EUSERS); // too many users - handle_server_connection_not_open(s); - break; case OPEN_RAW_ERROR: /* fall through */ case CONNECTION_ERROR: @@ -3496,9 +3489,6 @@ HttpTransact::handle_response_from_server(State *s) // server not yet negative cached - use default number of retries max_connect_retries = s->txn_conf->connect_attempts_max_retries; } - if (s->pCongestionEntry != nullptr) { - max_connect_retries = s->pCongestionEntry->connect_retries(); - } if (is_request_retryable(s) && s->current.attempts < max_connect_retries) { // If this is a round robin DNS entry & we're tried configured @@ -7355,16 +7345,6 @@ HttpTransact::handle_server_died(State *s) // FIX: all the body types below need to be filled in // //////////////////////////////////////////////////////// - // - // congestion control - // - if (s->pCongestionEntry != nullptr) { - s->congestion_congested_or_failed = 1; - if (s->current.state != CONGEST_CONTROL_CONGESTED_ON_F && s->current.state != CONGEST_CONTROL_CONGESTED_ON_M) { - s->pCongestionEntry->failed_at(s->current.now); - } - } - switch (s->current.state) { case CONNECTION_ALIVE: /* died while alive for unknown reason */ ink_release_assert(s->hdr_info.response_error != NO_RESPONSE_HEADER_ERROR); @@ -7409,26 +7389,6 @@ HttpTransact::handle_server_died(State *s) reason = "Invalid HTTP Response"; body_type = "response#bad_response"; break; - case CONGEST_CONTROL_CONGESTED_ON_F: - status = HTTP_STATUS_SERVICE_UNAVAILABLE; - reason = "Origin server congested"; - if (s->pCongestionEntry) { - body_type = s->pCongestionEntry->getErrorPage(); - } else { - body_type = "congestion#retryAfter"; - } - s->hdr_info.response_error = TOTAL_RESPONSE_ERROR_TYPES; - break; - case CONGEST_CONTROL_CONGESTED_ON_M: - status = HTTP_STATUS_SERVICE_UNAVAILABLE; - reason = "Too many users"; - if (s->pCongestionEntry) { - body_type = s->pCongestionEntry->getErrorPage(); - } else { - body_type = "congestion#retryAfter"; - } - s->hdr_info.response_error = TOTAL_RESPONSE_ERROR_TYPES; - break; case STATE_UNDEFINED: case TRANSACTION_COMPLETE: default: /* unknown death */ @@ -7439,14 +7399,6 @@ HttpTransact::handle_server_died(State *s) break; } - if (s->pCongestionEntry && s->pCongestionEntry->F_congested() && status != HTTP_STATUS_SERVICE_UNAVAILABLE) { - s->pCongestionEntry->stat_inc_F(); - CONGEST_SUM_GLOBAL_DYN_STAT(congested_on_F_stat, 1); - status = HTTP_STATUS_SERVICE_UNAVAILABLE; - reason = "Service Unavailable"; - body_type = s->pCongestionEntry->getErrorPage(); - s->hdr_info.response_error = TOTAL_RESPONSE_ERROR_TYPES; - } //////////////////////////////////////////////////////// // FIX: comment stuff above and below here, not clear // //////////////////////////////////////////////////////// @@ -7901,15 +7853,13 @@ HttpTransact::build_error_response(State *s, HTTPStatus status_code, const char build_response(s, &s->hdr_info.client_response, s->client_info.http_version, status_code, reason_phrase); if (status_code == HTTP_STATUS_SERVICE_UNAVAILABLE) { - if (s->pCongestionEntry != nullptr) { - int ret_tmp; - int retry_after = s->pCongestionEntry->client_retry_after(); + int ret_tmp; + int retry_after = 0; - s->congestion_control_crat = retry_after; - if (s->hdr_info.client_response.value_get(MIME_FIELD_RETRY_AFTER, MIME_LEN_RETRY_AFTER, &ret_tmp) == nullptr) { - s->hdr_info.client_response.value_set_int(MIME_FIELD_RETRY_AFTER, MIME_LEN_RETRY_AFTER, retry_after); - } + if (s->hdr_info.client_response.value_get(MIME_FIELD_RETRY_AFTER, MIME_LEN_RETRY_AFTER, &ret_tmp) != nullptr) { + retry_after = ret_tmp; } + s->congestion_control_crat = retry_after; } // Add a bunch of headers to make sure that caches between diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h index c69cdd1..3b09a71 100644 --- a/proxy/http/HttpTransact.h +++ b/proxy/http/HttpTransact.h @@ -42,8 +42,6 @@ #include "UrlMapping.h" #include <records/I_RecHttp.h> -#include "congest/Congestion.h" - #define MAX_DNS_LOOKUPS 2 #define HTTP_RELEASE_ASSERT(X) ink_release_assert(X) @@ -831,12 +829,7 @@ public: UrlMappingContainer url_map; host_hdr_info hh_info = {nullptr, 0, 0}; - // congestion control - CongestionEntry *pCongestionEntry = nullptr; - StateMachineAction_t congest_saved_next_action = SM_ACTION_UNDEFINED; - int congestion_control_crat = 0; // 'client retry after' - int congestion_congested_or_failed = 0; - int congestion_connection_opened = 0; + int congestion_control_crat = 0; // Client retry after unsigned int filter_mask = 0; char *remap_redirect = nullptr; @@ -920,14 +913,6 @@ public: redirect_info.original_url.destroy(); redirect_info.redirect_url.destroy(); - if (pCongestionEntry) { - if (congestion_connection_opened == 1) { - pCongestionEntry->connection_closed(); - congestion_connection_opened = 0; - } - pCongestionEntry->put(), pCongestionEntry = nullptr; - } - url_map.clear(); arena.reset(); unmapped_url.clear(); -- To stop receiving notification emails like this one, please contact ['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].