You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by sh...@apache.org on 2018/01/16 14:52:51 UTC
[trafficserver] branch master updated: Remove Congestion Control
Feature
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 <sh...@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" <co...@trafficserver.apache.org>'].