proxygen
wangle::ConnectionManager Class Reference

#include <ConnectionManager.h>

Inheritance diagram for wangle::ConnectionManager:
folly::DelayedDestruction wangle::ManagedConnection::Callback folly::DelayedDestructionBase

Classes

class  Callback
 
class  DrainHelper
 

Public Types

typedef std::unique_ptr< ConnectionManager, DestructorUniquePtr
 
typedef folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ >::iterator ConnectionIterator
 

Public Member Functions

 ConnectionManager (folly::EventBase *eventBase, std::chrono::milliseconds timeout, Callback *callback=nullptr)
 
void addConnection (ManagedConnection *connection, bool timeout=false)
 
void scheduleTimeout (ManagedConnection *const connection, std::chrono::milliseconds timeout)
 
void scheduleTimeout (folly::HHWheelTimer::Callback *callback, std::chrono::milliseconds timeout)
 
void removeConnection (ManagedConnection *connection)
 
void initiateGracefulShutdown (std::chrono::milliseconds idleGrace)
 
void drainConnections (double pct, std::chrono::milliseconds idleGrace)
 
void dropAllConnections ()
 
void dropConnections (double pct)
 
size_t getNumConnections () const
 
template<typename F >
void iterateConns (F func)
 
std::chrono::milliseconds getDefaultTimeout () const
 
void setLoweredIdleTimeout (std::chrono::milliseconds timeout)
 
size_t dropIdleConnections (size_t num)
 
void onActivated (ManagedConnection &conn) override
 
void onDeactivated (ManagedConnection &conn) override
 
- Public Member Functions inherited from folly::DelayedDestruction
virtual void destroy ()
 
bool getDestroyPending () const
 
- Public Member Functions inherited from folly::DelayedDestructionBase
virtual ~DelayedDestructionBase ()=default
 

Static Public Member Functions

template<typename... Args>
static UniquePtr makeUnique (Args &&...args)
 

Private Types

enum  ShutdownState : uint8_t {
  ShutdownState::NONE = 0, ShutdownState::NOTIFY_PENDING_SHUTDOWN = 1, ShutdownState::NOTIFY_PENDING_SHUTDOWN_COMPLETE = 2, ShutdownState::CLOSE_WHEN_IDLE = 3,
  ShutdownState::CLOSE_WHEN_IDLE_COMPLETE = 4
}
 

Private Member Functions

 ~ConnectionManager () override=default
 
 ConnectionManager (const ConnectionManager &)=delete
 
ConnectionManageroperator= (ConnectionManager &)=delete
 
void drainAllConnections ()
 
void stopDrainingForShutdown ()
 
void idleGracefulTimeoutExpired ()
 
- Private Member Functions inherited from wangle::ManagedConnection::Callback
virtual ~Callback ()=default
 

Private Attributes

folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_conns_
 
Callbackcallback_
 
folly::EventBaseeventBase_
 
ConnectionIterator drainIterator_
 
ConnectionIterator idleIterator_
 
DrainHelper drainHelper_
 
bool notifyPendingShutdown_ {true}
 
std::chrono::milliseconds timeout_
 
std::chrono::milliseconds idleConnEarlyDropThreshold_
 

Additional Inherited Members

- Protected Member Functions inherited from folly::DelayedDestruction
 ~DelayedDestruction () override=default
 
 DelayedDestruction ()
 
- Protected Member Functions inherited from folly::DelayedDestructionBase
 DelayedDestructionBase ()
 
uint32_t getDestructorGuardCount () const
 

Detailed Description

A ConnectionManager keeps track of ManagedConnections.

Definition at line 34 of file ConnectionManager.h.

Member Typedef Documentation

Definition at line 63 of file ConnectionManager.h.

Member Enumeration Documentation

Enumerator
NONE 
NOTIFY_PENDING_SHUTDOWN 
NOTIFY_PENDING_SHUTDOWN_COMPLETE 
CLOSE_WHEN_IDLE 
CLOSE_WHEN_IDLE_COMPLETE 

Definition at line 174 of file ConnectionManager.h.

174  : uint8_t {
175  NONE = 0,
176  // All ManagedConnections receive notifyPendingShutdown
177  NOTIFY_PENDING_SHUTDOWN = 1,
178  // All ManagedConnections have received notifyPendingShutdown
179  NOTIFY_PENDING_SHUTDOWN_COMPLETE = 2,
180  // All ManagedConnections receive closeWhenIdle
181  CLOSE_WHEN_IDLE = 3,
182  // All ManagedConnections have received closeWhenIdle
183  CLOSE_WHEN_IDLE_COMPLETE = 4,
184  };

Constructor & Destructor Documentation

wangle::ConnectionManager::ConnectionManager ( folly::EventBase eventBase,
std::chrono::milliseconds  timeout,
Callback callback = nullptr 
)

Constructor not to be used by itself.

Referenced by makeUnique().

wangle::ConnectionManager::~ConnectionManager ( )
overrideprivatedefault
wangle::ConnectionManager::ConnectionManager ( const ConnectionManager )
privatedelete

Member Function Documentation

void wangle::ConnectionManager::addConnection ( ManagedConnection connection,
bool  timeout = false 
)

Add a connection to the set of connections managed by this ConnectionManager.

Parameters
connectionThe connection to add.
timeoutWhether to immediately register this connection for an idle timeout callback.

Definition at line 40 of file ConnectionManager.cpp.

References callback_, wangle::ManagedConnection::fireCloseWhenIdle(), wangle::ManagedConnection::fireNotifyPendingShutdown(), wangle::ManagedConnection::getConnectionManager(), wangle::ManagedConnection::listHook_, removeConnection(), and wangle::ManagedConnection::setConnectionManager().

Referenced by makeUnique().

41  {
42  CHECK_NOTNULL(connection);
43  ConnectionManager* oldMgr = connection->getConnectionManager();
44  if (oldMgr != this) {
45  if (oldMgr) {
46  // 'connection' was being previously managed in a different thread.
47  // We must remove it from that manager before adding it to this one.
48  oldMgr->removeConnection(connection);
49  }
50 
51  // put the connection into busy part first. This should not matter at all
52  // because the last callback for an idle connection must be onDeactivated(),
53  // so the connection must be moved to idle part then.
54  conns_.push_front(*connection);
55 
56  connection->setConnectionManager(this);
57  if (callback_) {
58  callback_->onConnectionAdded(connection);
59  }
60  }
61  if (timeout) {
62  scheduleTimeout(connection, timeout_);
63  }
64 
68  connection->fireNotifyPendingShutdown();
69  }
70 
72  // closeWhenIdle can delete the connection (it was just created, so it's
73  // probably idle). Delay the closeWhenIdle call until the end of the loop
74  // where it will be safer to terminate the conn.
75  // Hold a DestructorGuard to the end of the loop for this
76  auto cmDg = new DestructorGuard(this);
77  auto connDg = new DestructorGuard(connection);
78  eventBase_->runInLoop([connection, this, cmDg, connDg] {
79  if (connection->listHook_.is_linked()) {
80  auto it = conns_.iterator_to(*connection);
81  DCHECK(it != conns_.end());
82  connection->fireCloseWhenIdle(!notifyPendingShutdown_);
83  }
84  delete connDg;
85  delete cmDg;
86  });
87  }
88 }
folly::EventBase * eventBase_
ConnectionManager(folly::EventBase *eventBase, std::chrono::milliseconds timeout, Callback *callback=nullptr)
void runInLoop(LoopCallback *callback, bool thisIteration=false)
Definition: EventBase.cpp:520
void scheduleTimeout(ManagedConnection *const connection, std::chrono::milliseconds timeout)
std::chrono::milliseconds timeout_
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
virtual void onConnectionAdded(const ManagedConnection *conn)=0
void wangle::ConnectionManager::drainAllConnections ( )
private

Destroy all connections managed by this ConnectionManager that are currently idle, as determined by a call to each ManagedConnection's isBusy() method.

void wangle::ConnectionManager::drainConnections ( double  pct,
std::chrono::milliseconds  idleGrace 
)

Gracefully shutdown certain percentage of persistent client connections and leave the rest intact.

Definition at line 141 of file ConnectionManager.cpp.

References wangle::NONE.

Referenced by makeUnique(), wangle::ConnectionManager::DrainHelper::runLoopCallback(), and wangle::ConnectionManager::DrainHelper::timeoutExpired().

142  {
144  VLOG(3) << "Ignoring partial drain with full drain in progress";
145  return;
146  }
147  drainHelper_.startDrainPartial(pct, idleGrace);
148 }
void startDrainPartial(double pct, std::chrono::milliseconds idleGrace)
void wangle::ConnectionManager::dropAllConnections ( )

Destroy all connections Managed by this ConnectionManager, even the ones that are busy.

Definition at line 255 of file ConnectionManager.cpp.

References callback_, folly::HHWheelTimer::Callback::cancelTimeout(), wangle::ManagedConnection::dropConnection(), wangle::ManagedConnection::dumpConnectionState(), g(), i, and wangle::ManagedConnection::setConnectionManager().

Referenced by makeUnique().

255  {
256  DestructorGuard g(this);
257 
258  // Signal the drain helper in case that has not happened before.
260 
261  // Iterate through our connection list, and drop each connection.
262  VLOG_IF(4, conns_.empty()) << "no connections to drop";
263  VLOG_IF(2, !conns_.empty()) << "connections to drop: " << conns_.size();
264 
265  unsigned i = 0;
266  while (!conns_.empty()) {
267  ManagedConnection& conn = conns_.front();
268  conns_.pop_front();
269  conn.cancelTimeout();
270  conn.setConnectionManager(nullptr);
271  // For debugging purposes, dump information about the first few
272  // connections.
273  static const unsigned MAX_CONNS_TO_DUMP = 2;
274  if (++i <= MAX_CONNS_TO_DUMP) {
275  conn.dumpConnectionState(3);
276  }
277  conn.dropConnection();
278  }
279  drainIterator_ = conns_.end();
280  idleIterator_ = conns_.end();
282 
283  if (callback_) {
284  callback_->onEmpty(*this);
285  }
286 }
virtual void onEmpty(const ConnectionManager &cm)=0
ConnectionIterator drainIterator_
ConnectionIterator idleIterator_
g_t g(f_t)
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
void wangle::ConnectionManager::dropConnections ( double  pct)

Force-stop "pct" (0.0 to 1.0) of remaining client connections, regardless of whether they are busy or idle.

Definition at line 289 of file ConnectionManager.cpp.

References wangle::ManagedConnection::dropConnection(), g(), and i.

Referenced by makeUnique().

289  {
290  DestructorGuard g(this);
291 
292  // Signal the drain helper in case that has not happened before.
294 
295  const size_t N = conns_.size();
296  const size_t numToDrop = std::max<size_t>(0, std::min<size_t>(N, N * pct));
297  for (size_t i = 0; i < numToDrop && !conns_.empty(); i++) {
298  ManagedConnection& conn = conns_.front();
299  removeConnection(&conn);
300  conn.dropConnection();
301  }
302 }
void removeConnection(ManagedConnection *connection)
g_t g(f_t)
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
size_t wangle::ConnectionManager::dropIdleConnections ( size_t  num)

try to drop num idle connections to release system resources. Return the actual number of dropped idle connections

Definition at line 333 of file ConnectionManager.cpp.

References count, and wangle::ManagedConnection::dropConnection().

Referenced by setLoweredIdleTimeout().

333  {
334  VLOG(4) << "attempt to drop " << num << " idle connections";
336  return 0;
337  }
338 
339  size_t count = 0;
340  while(count < num) {
341  auto it = idleIterator_;
342  if (it == conns_.end()) {
343  return count; // no more idle session
344  }
345  auto idleTime = it->getIdleTime();
346  if (idleTime == std::chrono::milliseconds(0) ||
347  idleTime <= idleConnEarlyDropThreshold_) {
348  VLOG(4) << "conn's idletime: " << idleTime.count()
349  << ", earlyDropThreshold: " << idleConnEarlyDropThreshold_.count()
350  << ", attempt to drop " << count << "/" << num;
351  return count; // idleTime cannot be further reduced
352  }
353  ManagedConnection& conn = *it;
354  idleIterator_++;
355  conn.dropConnection();
356  count++;
357  }
358 
359  return count;
360 }
ConnectionIterator idleIterator_
int * count
std::chrono::milliseconds timeout_
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
std::chrono::milliseconds idleConnEarlyDropThreshold_
std::chrono::milliseconds wangle::ConnectionManager::getDefaultTimeout ( ) const
inline

Definition at line 149 of file ConnectionManager.h.

References timeout_.

Referenced by wangle::ManagedConnection::resetTimeout().

149  {
150  return timeout_;
151  }
std::chrono::milliseconds timeout_
size_t wangle::ConnectionManager::getNumConnections ( ) const
inline

Definition at line 138 of file ConnectionManager.h.

References conns_.

138 { return conns_.size(); }
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
void wangle::ConnectionManager::idleGracefulTimeoutExpired ( )
private
void wangle::ConnectionManager::initiateGracefulShutdown ( std::chrono::milliseconds  idleGrace)

Definition at line 131 of file ConnectionManager.cpp.

References wangle::NONE.

Referenced by makeUnique().

132  {
133  VLOG(3) << this << " initiateGracefulShutdown with nconns=" << conns_.size();
135  VLOG(3) << "Ignoring redundant call to initiateGracefulShutdown";
136  return;
137  }
138  drainHelper_.startDrainAll(idleGrace);
139 }
void startDrainAll(std::chrono::milliseconds idleGrace)
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
template<typename F >
void wangle::ConnectionManager::iterateConns ( func)
inline

Definition at line 141 of file ConnectionManager.h.

References conns_.

141  {
142  auto it = conns_.begin();
143  while ( it != conns_.end()) {
144  func(&(*it));
145  it++;
146  }
147  }
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
template<typename... Args>
static UniquePtr wangle::ConnectionManager::makeUnique ( Args &&...  args)
inlinestatic

Returns a new instance of ConnectionManager wrapped in a unique_ptr

Definition at line 71 of file ConnectionManager.h.

References addConnection(), ConnectionManager(), drainConnections(), dropAllConnections(), dropConnections(), initiateGracefulShutdown(), removeConnection(), scheduleTimeout(), and folly::detail::timeout.

Referenced by wangle::Acceptor::initDownstreamConnectionManager(), and TEST_F().

71  {
72  return UniquePtr(new ConnectionManager(std::forward<Args>(args)...));
73  }
ConnectionManager(folly::EventBase *eventBase, std::chrono::milliseconds timeout, Callback *callback=nullptr)
std::unique_ptr< ConnectionManager, Destructor > UniquePtr
void wangle::ConnectionManager::onActivated ( ManagedConnection conn)
overridevirtual

ManagedConnection::Callbacks

Implements wangle::ManagedConnection::Callback.

Definition at line 305 of file ConnectionManager.cpp.

Referenced by proxygen::HTTPSession::createTransaction(), and setLoweredIdleTimeout().

305  {
306  auto it = conns_.iterator_to(conn);
307  if (it == idleIterator_) {
308  idleIterator_++;
309  }
310  conns_.erase(it);
311  conns_.push_front(conn);
312 }
ConnectionIterator idleIterator_
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
void wangle::ConnectionManager::onDeactivated ( ManagedConnection conn)
overridevirtual

Implements wangle::ManagedConnection::Callback.

Definition at line 315 of file ConnectionManager.cpp.

Referenced by proxygen::HTTPSession::detach(), and setLoweredIdleTimeout().

315  {
316  auto it = conns_.iterator_to(conn);
317  bool moveDrainIter = false;
318  if (it == drainIterator_) {
319  drainIterator_++;
320  moveDrainIter = true;
321  }
322  conns_.erase(it);
323  conns_.push_back(conn);
324  if (idleIterator_ == conns_.end()) {
325  idleIterator_--;
326  }
327  if (moveDrainIter && drainIterator_ == conns_.end()) {
328  drainIterator_--;
329  }
330 }
ConnectionIterator drainIterator_
ConnectionIterator idleIterator_
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
ConnectionManager& wangle::ConnectionManager::operator= ( ConnectionManager )
privatedelete
void wangle::ConnectionManager::removeConnection ( ManagedConnection connection)

Remove a connection from this ConnectionManager and, if applicable, cancel the pending timeout callback that the ConnectionManager has scheduled for the connection.

Note
This method does NOT destroy the connection.

Definition at line 105 of file ConnectionManager.cpp.

References callback_, folly::HHWheelTimer::Callback::cancelTimeout(), wangle::ManagedConnection::getConnectionManager(), wangle::SimpleConnectionCounter::getNumConnections(), and wangle::ManagedConnection::setConnectionManager().

Referenced by addConnection(), makeUnique(), and wangle::ManagedConnection::~ManagedConnection().

105  {
106  if (connection->getConnectionManager() == this) {
107  connection->cancelTimeout();
108  connection->setConnectionManager(nullptr);
109 
110  // Un-link the connection from our list, being careful to keep the iterator
111  // that we're using for idle shedding valid
112  auto it = conns_.iterator_to(*connection);
113  if (it == drainIterator_) {
114  ++drainIterator_;
115  }
116  if (it == idleIterator_) {
117  ++idleIterator_;
118  }
119  conns_.erase(it);
120 
121  if (callback_) {
122  callback_->onConnectionRemoved(connection);
123  if (getNumConnections() == 0) {
124  callback_->onEmpty(*this);
125  }
126  }
127  }
128 }
virtual void onEmpty(const ConnectionManager &cm)=0
virtual void onConnectionRemoved(const ManagedConnection *conn)=0
ConnectionIterator drainIterator_
size_t getNumConnections() const
ConnectionIterator idleIterator_
folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_ > conns_
void wangle::ConnectionManager::scheduleTimeout ( ManagedConnection *const  connection,
std::chrono::milliseconds  timeout 
)

Schedule a timeout callback for a connection.

Definition at line 91 of file ConnectionManager.cpp.

Referenced by makeUnique(), wangle::ManagedConnection::resetTimeoutTo(), wangle::ManagedConnection::scheduleTimeout(), and wangle::AcceptorHandshakeManager::startHandshakeTimeout().

92  {
93  if (timeout > std::chrono::milliseconds(0)) {
94  eventBase_->timer().scheduleTimeout(connection, timeout);
95  }
96 }
folly::EventBase * eventBase_
void scheduleTimeout(Callback *callback, std::chrono::milliseconds timeout)
HHWheelTimer & timer()
Definition: EventBase.h:526
void wangle::ConnectionManager::scheduleTimeout ( folly::HHWheelTimer::Callback callback,
std::chrono::milliseconds  timeout 
)

Definition at line 98 of file ConnectionManager.cpp.

100  {
101  eventBase_->timer().scheduleTimeout(callback, timeout);
102 }
folly::EventBase * eventBase_
void scheduleTimeout(Callback *callback, std::chrono::milliseconds timeout)
HHWheelTimer & timer()
Definition: EventBase.h:526
void wangle::ConnectionManager::setLoweredIdleTimeout ( std::chrono::milliseconds  timeout)
inline

Definition at line 153 of file ConnectionManager.h.

References dropIdleConnections(), idleConnEarlyDropThreshold_, onActivated(), onDeactivated(), and timeout_.

153  {
154  CHECK(timeout >= std::chrono::milliseconds(0));
155  CHECK(timeout <= timeout_);
157  }
std::chrono::milliseconds timeout_
std::chrono::milliseconds idleConnEarlyDropThreshold_
void wangle::ConnectionManager::stopDrainingForShutdown ( )
private

Signal the drain helper that we are about to start dropping connections.

Definition at line 249 of file ConnectionManager.cpp.

Member Data Documentation

Callback* wangle::ConnectionManager::callback_
private

Optional callback to notify of state changes

Definition at line 272 of file ConnectionManager.h.

folly::CountedIntrusiveList< ManagedConnection,&ManagedConnection::listHook_> wangle::ConnectionManager::conns_
private

All the managed connections. idleIterator_ seperates them into two parts: idle and busy ones. [conns_.begin(), idleIterator_) are the busy ones, while [idleIterator_, conns_.end()) are the idle one. Moreover, the idle ones are organized in the decreasing idle time order.

Definition at line 269 of file ConnectionManager.h.

Referenced by getNumConnections(), and iterateConns().

DrainHelper wangle::ConnectionManager::drainHelper_
private

Definition at line 280 of file ConnectionManager.h.

ConnectionIterator wangle::ConnectionManager::drainIterator_
private

Iterator to the next connection to shed; used by drainAllConnections()

Definition at line 278 of file ConnectionManager.h.

folly::EventBase* wangle::ConnectionManager::eventBase_
private

Event base in which we run

Definition at line 275 of file ConnectionManager.h.

std::chrono::milliseconds wangle::ConnectionManager::idleConnEarlyDropThreshold_
private

The idle connections can be closed earlier that their idle timeout when any system resource limit is reached. This feature can be considerred as a pre load shedding stage for the system, and can be easily disabled by setting idleConnEarlyDropThreshold_ to defaultIdleTimeout_. Also, idleConnEarlyDropThreshold_ can be used to bottom the idle timeout. That is, connection manager will not early drop the idle connections whose idle time is less than idleConnEarlyDropThreshold_.

Definition at line 298 of file ConnectionManager.h.

Referenced by setLoweredIdleTimeout().

ConnectionIterator wangle::ConnectionManager::idleIterator_
private

Definition at line 279 of file ConnectionManager.h.

bool wangle::ConnectionManager::notifyPendingShutdown_ {true}
private

Definition at line 281 of file ConnectionManager.h.

std::chrono::milliseconds wangle::ConnectionManager::timeout_
private

the default idle timeout for downstream sessions when no system resource limit is reached

Definition at line 287 of file ConnectionManager.h.

Referenced by getDefaultTimeout(), and setLoweredIdleTimeout().


The documentation for this class was generated from the following files: