Repository: trafficserver
Updated Branches:
  refs/heads/master 4e26efd63 -> ce08ae8a8


TS-153: "Dynamic" keep-alive timeouts for incoming connections


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ce08ae8a
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ce08ae8a
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ce08ae8a

Branch: refs/heads/master
Commit: ce08ae8a88b15cda917484197e75e524456d0a5d
Parents: 4e26efd
Author: Bryan Call <[email protected]>
Authored: Mon Dec 15 11:43:13 2014 -0800
Committer: Bryan Call <[email protected]>
Committed: Mon Dec 15 11:43:13 2014 -0800

----------------------------------------------------------------------
 iocore/net/I_NetVConnection.h     |  4 ++++
 iocore/net/P_UnixNet.h            | 10 ++++++++--
 iocore/net/P_UnixNetVConnection.h |  4 ++++
 iocore/net/UnixConnection.cc      | 19 +++++++++++++++++++
 iocore/net/UnixNet.cc             | 22 +++++++++++++++++++++-
 iocore/net/UnixNetVConnection.cc  |  2 ++
 mgmt/RecordsConfig.cc             |  2 ++
 proxy/PluginVC.cc                 | 12 ++++++++++++
 proxy/PluginVC.h                  |  2 ++
 proxy/http/HttpClientSession.cc   |  2 ++
 10 files changed, 76 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/iocore/net/I_NetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h
index 99e9466..3ff5ff0 100644
--- a/iocore/net/I_NetVConnection.h
+++ b/iocore/net/I_NetVConnection.h
@@ -430,6 +430,10 @@ public:
   */
   virtual void cancel_inactivity_timeout() = 0;
 
+  virtual void add_to_keep_alive_lru() = 0;
+
+  virtual void remove_from_keep_alive_lru() = 0;
+
   /** @return the current active_timeout value in nanosecs */
   virtual ink_hrtime get_active_timeout() = 0;
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/iocore/net/P_UnixNet.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_UnixNet.h b/iocore/net/P_UnixNet.h
index 9d16924..98060d8 100644
--- a/iocore/net/P_UnixNet.h
+++ b/iocore/net/P_UnixNet.h
@@ -192,6 +192,8 @@ public:
   DList(UnixNetVConnection, cop_link) cop_list;
   ASLLM(UnixNetVConnection, NetState, read, enable_link) read_enable_list;
   ASLLM(UnixNetVConnection, NetState, write, enable_link) write_enable_list;
+  DList(UnixNetVConnection, keep_alive_link) keep_alive_list;
+  uint32_t keep_alive_lru_size;
 
   time_t sec;
   int cycles;
@@ -397,8 +399,10 @@ read_disable(NetHandler * nh, UnixNetVConnection * vc)
     }
   }
 #else
-  if (!vc->write.enabled)
+  if (!vc->write.enabled) {
     vc->next_inactivity_timeout_at = 0;
+    Debug("socket", "read_disable updating inactivity_at %" PRId64 ", 
NetVC=%p", vc->next_inactivity_timeout_at, vc);
+  }
 #endif
   vc->read.enabled = 0;
   nh->read_ready_list.remove(vc);
@@ -416,8 +420,10 @@ write_disable(NetHandler * nh, UnixNetVConnection * vc)
     }
   }
 #else
-  if (!vc->read.enabled)
+  if (!vc->read.enabled) {
     vc->next_inactivity_timeout_at = 0;
+    Debug("socket", "write_disable updating inactivity_at %" PRId64 ", 
NetVC=%p", vc->next_inactivity_timeout_at, vc);
+  }
 #endif
   vc->write.enabled = 0;
   nh->write_ready_list.remove(vc);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/iocore/net/P_UnixNetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_UnixNetVConnection.h 
b/iocore/net/P_UnixNetVConnection.h
index 355d6a0..eb16e02 100644
--- a/iocore/net/P_UnixNetVConnection.h
+++ b/iocore/net/P_UnixNetVConnection.h
@@ -135,6 +135,8 @@ public:
   virtual void set_inactivity_timeout(ink_hrtime timeout_in);
   virtual void cancel_active_timeout();
   virtual void cancel_inactivity_timeout();
+  virtual void add_to_keep_alive_lru();
+  virtual void remove_from_keep_alive_lru();
 
   // The public interface is VIO::reenable()
   virtual void reenable(VIO *vio);
@@ -203,6 +205,7 @@ public:
   SLINKM(UnixNetVConnection, read, enable_link)
   LINKM(UnixNetVConnection, write, ready_link)
   SLINKM(UnixNetVConnection, write, enable_link)
+  LINK(UnixNetVConnection, keep_alive_link);
 
   ink_hrtime inactivity_timeout_in;
   ink_hrtime active_timeout_in;
@@ -211,6 +214,7 @@ public:
 #else
   ink_hrtime next_inactivity_timeout_at;
 #endif
+
   Event *active_timeout;
   EventIO ep;
   NetHandler *nh;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/iocore/net/UnixConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixConnection.cc b/iocore/net/UnixConnection.cc
index 375ae98..d8daf45 100644
--- a/iocore/net/UnixConnection.cc
+++ b/iocore/net/UnixConnection.cc
@@ -388,5 +388,24 @@ Connection::apply_options(NetVCOptions const& opt)
   uint32_t tos = opt.packet_tos;
   safe_setsockopt(fd, IPPROTO_IP, IP_TOS, reinterpret_cast<char *>(&tos), 
sizeof(uint32_t));
 #endif
+}
 
+void
+UnixNetVConnection::add_to_keep_alive_lru()
+{
+  Debug("socket", "UnixNetVConnection::add_to_keep_alive_lru NetVC=%p", this);
+  if (! nh->keep_alive_list.in(this)) {
+    nh->keep_alive_list.push(this);
+    ++nh->keep_alive_lru_size;
+  }
+}
+
+void
+UnixNetVConnection::remove_from_keep_alive_lru()
+{
+  Debug("socket", "UnixNetVConnection::remove_from_keep_alive_lru NetVC=%p", 
this);
+  if (nh->keep_alive_list.in(this)) {
+    nh->keep_alive_list.remove(this);
+    --nh->keep_alive_lru_size;
+  }
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/iocore/net/UnixNet.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixNet.cc b/iocore/net/UnixNet.cc
index f4ee7e7..c8f70ae 100644
--- a/iocore/net/UnixNet.cc
+++ b/iocore/net/UnixNet.cc
@@ -79,6 +79,26 @@ public:
       if (vc->next_inactivity_timeout_at && vc->next_inactivity_timeout_at < 
now)
         vc->handleEvent(EVENT_IMMEDIATE, e);
     }
+
+    // Keep-alive LRU for incoming connections
+    int32_t max_keep_alive = 0;
+    REC_ReadConfigInt32(max_keep_alive, 
"proxy.config.http.client_max_keep_alive_connections");
+    if (max_keep_alive > 0) {
+      const int event_threads = eventProcessor.n_threads_for_type[ET_NET];
+      const int ssl_threads = (ET_NET == SSLNetProcessor::ET_SSL) ? 0 : 
eventProcessor.n_threads_for_type[SSLNetProcessor::ET_SSL];
+
+      max_keep_alive = max_keep_alive / (event_threads + ssl_threads);
+      Debug("inactivity_cop_verbose", "max_keep_alive: %d lru size: %d net 
threads: %d ssl threads: %d net type: %d "
+            "ssl type: %d", max_keep_alive, nh->keep_alive_lru_size, 
event_threads, ssl_threads, ET_NET,
+            SSLNetProcessor::ET_SSL);
+
+      while (nh->keep_alive_lru_size > max_keep_alive) {
+        UnixNetVConnection *vc = nh->keep_alive_list.pop();
+        Debug("inactivity_cop", "removing keep-alives from the lru NetVC=%p 
size: %u", vc, nh->keep_alive_lru_size);
+        --(nh->keep_alive_lru_size);
+        close_UnixNetVConnection(vc, e->ethread);
+      }
+    }
     return 0;
   }
 private:
@@ -235,7 +255,7 @@ initialize_thread_for_net(EThread *thread)
 
 // NetHandler method definitions
 
-NetHandler::NetHandler():Continuation(NULL), trigger_event(0)
+NetHandler::NetHandler():Continuation(NULL), trigger_event(0), 
keep_alive_lru_size(0)
 {
   SET_HANDLER((NetContHandler) & NetHandler::startNetEvent);
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/iocore/net/UnixNetVConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index c497c2d..3e4c847 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -67,6 +67,7 @@ write_reschedule(NetHandler *nh, UnixNetVConnection *vc)
 void
 net_activity(UnixNetVConnection *vc, EThread *thread)
 {
+  Debug("socket", "net_activity updating inactivity %" PRId64 ", NetVC=%p", 
vc->inactivity_timeout_in, vc);
   (void) thread;
 #ifdef INACTIVITY_TIMEOUT
   if (vc->inactivity_timeout && vc->inactivity_timeout_in && 
vc->inactivity_timeout->ethread == thread)
@@ -616,6 +617,7 @@ UnixNetVConnection::do_io_close(int alerrno /* = -1 */ )
   else
     closed = -1;
 
+  remove_from_keep_alive_lru();
   if (close_inline)
     close_UnixNetVConnection(this, t);
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index 722c518..80b7647 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -459,6 +459,8 @@ static const RecordElement RecordsConfig[] =
   ,
   {RECT_CONFIG, "proxy.config.http.attach_server_session_to_client", RECD_INT, 
"0", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.http.client_max_keep_alive_connections", 
RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  ,
 
   //       ##########################
   //       # HTTP referer filtering #

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/proxy/PluginVC.cc
----------------------------------------------------------------------
diff --git a/proxy/PluginVC.cc b/proxy/PluginVC.cc
index a271312..7b612c2 100644
--- a/proxy/PluginVC.cc
+++ b/proxy/PluginVC.cc
@@ -880,6 +880,18 @@ PluginVC::get_inactivity_timeout()
   return inactive_timeout;
 }
 
+void
+PluginVC::add_to_keep_alive_lru()
+{
+  // do nothing
+}
+
+void
+PluginVC::remove_from_keep_alive_lru()
+{
+  // do nothing
+}
+
 SOCKET
 PluginVC::get_socket()
 {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/proxy/PluginVC.h
----------------------------------------------------------------------
diff --git a/proxy/PluginVC.h b/proxy/PluginVC.h
index 2389842..ecf1da8 100644
--- a/proxy/PluginVC.h
+++ b/proxy/PluginVC.h
@@ -100,6 +100,8 @@ public:
   virtual void set_inactivity_timeout(ink_hrtime timeout_in);
   virtual void cancel_active_timeout();
   virtual void cancel_inactivity_timeout();
+  virtual void add_to_keep_alive_lru();
+  virtual void remove_from_keep_alive_lru();
   virtual ink_hrtime get_active_timeout();
   virtual ink_hrtime get_inactivity_timeout();
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce08ae8a/proxy/http/HttpClientSession.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpClientSession.cc b/proxy/http/HttpClientSession.cc
index 68a9a93..2ea5522 100644
--- a/proxy/http/HttpClientSession.cc
+++ b/proxy/http/HttpClientSession.cc
@@ -134,6 +134,7 @@ HttpClientSession::new_transaction()
   transact_count++;
   DebugHttpSsn("[%" PRId64 "] Starting transaction %d using sm [%" PRId64 "]", 
con_id, transact_count, current_reader->sm_id);
 
+  client_vc->remove_from_keep_alive_lru();
   current_reader->attach_client_session(this, sm_reader);
   if (pi) {
     // it's a plugin VC of some sort with identify information.
@@ -503,6 +504,7 @@ HttpClientSession::release(IOBufferReader * r)
     SET_HANDLER(&HttpClientSession::state_keep_alive);
     ka_vio = this->do_io_read(this, INT64_MAX, read_buffer);
     ink_assert(slave_ka_vio != ka_vio);
+    client_vc->add_to_keep_alive_lru();
     client_vc->set_inactivity_timeout(HRTIME_SECONDS(ka_in));
     client_vc->cancel_active_timeout();
   }

Reply via email to