HappyConnOpener.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #ifndef SQUID_HAPPYCONNOPENER_H
10 #define SQUID_HAPPYCONNOPENER_H
11 #include "base/RefCount.h"
12 #include "comm.h"
13 #include "comm/Connection.h"
14 #include "comm/ConnOpener.h"
15 #include "http/forward.h"
16 #include "log/forward.h"
17 #include "ResolvedPeers.h"
18 
19 #include <iosfwd>
20 
21 class HappyConnOpener;
22 class HappyOrderEnforcer;
23 class JobGapEnforcer;
25 
27 typedef std::list< CbcPointer<HappyConnOpener> > HappySpareWaitList;
28 
30 typedef double HappyAbsoluteTime;
31 
34 public:
35  explicit operator bool() const { return toGivePrimeItsChance || forSpareAllowance || forPrimesToFail || forNewPeer; }
36 
39  void clear() { *this = HappySpareWait(); }
40 
42 
45 
48  HappySpareWaitList::iterator position;
49 
50  /* The following four fields represent mutually exclusive wait reasons. */
51 
54  bool toGivePrimeItsChance = false;
55 
60  bool forSpareAllowance = false;
61 
64  bool forPrimesToFail = false;
65 
68  bool forNewPeer = false;
69 };
70 
73 {
74 public:
76 
78  bool success() const { return !error; }
79 
83 
84  // answer recipients must clear the error member in order to keep its info
85  // XXX: We should refcount ErrorState instead of cbdata-protecting it.
87 
90  int n_tries = 0;
91 
93  bool reused = false;
94 };
95 
97 std::ostream &operator <<(std::ostream &, const HappyConnOpenerAnswer &);
98 
103 {
105 public:
107 
109  template <class Initiator>
110  class CbDialer: public CallDialer, public Answer {
111  public:
112  // initiator method to receive our answer
113  typedef void (Initiator::*Method)(Answer &);
114 
115  CbDialer(Method method, Initiator *initiator): initiator_(initiator), method_(method) {}
116  virtual ~CbDialer() = default;
117 
118  /* CallDialer API */
119  bool canDial(AsyncCall &) { return initiator_.valid(); }
120  void dial(AsyncCall &) {((*initiator_).*method_)(*this); }
121  virtual void print(std::ostream &os) const override {
122  os << '(' << static_cast<const Answer&>(*this) << ')';
123  }
124 
125  private:
128  };
129 
130 public:
131  HappyConnOpener(const ResolvedPeersPointer &, const AsyncCall::Pointer &, HttpRequestPointer &, const time_t aFwdStart, int tries, const AccessLogEntryPointer &al);
132  virtual ~HappyConnOpener() override;
133 
135  void allowPersistent(bool permitted) { allowPconn_ = permitted; }
136 
138  void setRetriable(bool retriable) { retriable_ = retriable; }
139 
141  void setHost(const char *);
142 
144  void noteCandidatesChange();
145 
147  void noteGavePrimeItsChance();
148 
150  void noteSpareAllowance();
151 
154 
155 private:
157  class Attempt {
158  public:
159  explicit operator bool() const { return static_cast<bool>(path); }
160 
162  void finish() { clear(); }
163 
165  void cancel(const char *reason);
166 
170 
171  private:
173  void clear() { path = nullptr; connector = nullptr; opener = nullptr; }
174  };
175 
176  /* AsyncJob API */
177  virtual void start() override;
178  virtual bool doneAll() const override;
179  virtual void swanSong() override;
180  virtual const char *status() const override;
181 
183 
188 
189  void startConnecting(Attempt &, PeerConnectionPointer &);
190  void openFreshConnection(Attempt &, PeerConnectionPointer &);
192 
193  void connectDone(const CommConnectCbParams &);
194 
195  void checkForNewConnection();
196 
198 
199  void cancelSpareWait(const char *reason);
200 
201  bool ranOutOfTimeOrAttempts() const;
202 
203  ErrorState *makeError(const err_type type) const;
205  void sendSuccess(const PeerConnectionPointer &conn, bool reused, const char *connKind);
206  void sendFailure();
207  void cancelAttempt(Attempt &, const char *reason);
208 
209  const time_t fwdStart;
210 
212 
215 
218 
221 
225 
228  friend class HappyOrderEnforcer;
229 
231 
232  ErrorState *lastError = nullptr;
234 
237 
239  bool gotSpareAllowance = false;
240 
242  bool allowPconn_ = true;
243 
245  bool retriable_ = true;
246 
248  const char *host_ = nullptr;
249 
252 
254  int n_tries;
255 
257  mutable const char *ranOutOfTimeOrAttemptsEarlier_ = nullptr;
258 };
259 
260 #endif
261 
CbcPointer< Initiator > initiator_
object to deliver the answer to
virtual ~CbDialer()=default
a connection opening attempt in progress (or falsy)
const char * ranOutOfTimeOrAttemptsEarlier_
Reason to ran out of time or attempts.
CbDialer(Method method, Initiator *initiator)
Comm::ConnectionPointer currentPeer
void setHost(const char *)
configures the origin server domain name
CbcPointer< ErrorState > error
problem details (nil on success)
ErrorState * lastError
last problem details (or nil)
PeerConnectionPointer path
the destination we are connecting to
void stopGivingPrimeItsChance()
called when the prime attempt has used up its chance for a solo victory
void(Initiator::* Method)(Answer &)
RefCount< ResolvedPeers > ResolvedPeersPointer
Method method_
initiator_ method to call with the answer
virtual ~HappyConnOpener() override
AsyncCall::Pointer callback
a pending noteGavePrimeItsChance() or noteSpareAllowance() call
virtual void print(std::ostream &os) const override
void checkForNewConnection()
ErrorState * makeError(const err_type type) const
void cancelAttempt(Attempt &, const char *reason)
cancels the in-progress attempt, making its path a future candidate
HappyConnOpenerAnswer Answer
virtual void start() override
called by AsyncStart; do not call directly
int n_tries
number of connection opening attempts, including those in the requestor
int type
Definition: errorpage.cc:152
Attempt prime
current connection opening attempt on the prime track (if any)
void connectDone(const CommConnectCbParams &)
HappyAbsoluteTime primeStart
the start of the first connection attempt for the currentPeer
void maybeGivePrimeItsChance()
void clear()
cleans up after the attempt ends (successfully or otherwise)
void maybeOpenSpareConnection()
if possible, starts a spare connection attempt
Comm::ConnOpener::Pointer opener
connects to path and calls us
void setRetriable(bool retriable)
configures whether the request may be retried later if things go wrong
void updateSpareWaitAfterPrimeFailure()
reacts to a prime attempt failure
Attempt spare
current connection opening attempt on the spare track (if any)
HappySpareWaitList::iterator position
Answer * futureAnswer(const PeerConnectionPointer &)
void maybeOpenAnotherPrimeConnection()
starts a prime connection attempt if possible or does nothing otherwise
ResolvedPeersPointer destinations
Candidate paths. Shared with the initiator. May not be finalized yet.
HappyConnOpener(const ResolvedPeersPointer &, const AsyncCall::Pointer &, HttpRequestPointer &, const time_t aFwdStart, int tries, const AccessLogEntryPointer &al)
bool allowPconn_
whether persistent connections are allowed
bool canDial(AsyncCall &)
bool success() const
whether HappyConnOpener succeeded, returning a usable connection
CBDATA_CHILD(HappyConnOpener)
double HappyAbsoluteTime
absolute time in fractional seconds; compatible with current_timed
void noteGavePrimeItsChance()
reacts to expired happy_eyeballs_connect_timeout
void startConnecting(Attempt &, PeerConnectionPointer &)
starts opening (or reusing) a connection to the given destination
std::list< CbcPointer< HappyConnOpener > > HappySpareWaitList
A FIFO queue of HappyConnOpener jobs waiting to open a spare connection.
virtual bool doneAll() const override
whether positive goal has been reached
err_type
Definition: err_type.h:12
AccessLogEntryPointer ale
transaction details
void sendSuccess(const PeerConnectionPointer &conn, bool reused, const char *connKind)
send a successful result to the initiator (if it still needs an answer)
virtual void swanSong() override
bool ranOutOfTimeOrAttempts() const
Check for maximum connection tries and forwarding time restrictions.
void finish()
reacts to a natural attempt completion (successful or otherwise)
std::ostream & operator<<(std::ostream &, const HappyConnOpenerAnswer &)
reports Answer details (for AsyncCall parameter debugging)
int conn
the current server connection FD
Definition: Transport.cc:26
Final result (an open connection or an error) sent to the job initiator.
void allowPersistent(bool permitted)
configures reuse of old connections
PeerConnectionPointer conn
keeps track of HappyConnOpener spare track waiting state
bool gotSpareAllowance
whether we have received a permission to open a spare while spares are limited
const char * host_
origin server domain name (or equivalent)
size_t HttpReply *STUB StoreEntry const KeyScope scope const HttpRequestMethod & method
Definition: stub_store.cc:108
bool retriable_
whether we are opening connections for a request that may be resent
AsyncCall::Pointer connector
our opener callback
AsyncCall dialer for our callback. Gives us access to callback Answer.
HttpRequestPointer cause
the request that needs a to-server connection
bool reuseOldConnection(PeerConnectionPointer &)
bool reused
whether conn was open earlier, by/for somebody else
bool ignoreSpareRestrictions
whether spare connection attempts disregard happy_eyeballs_* settings
virtual const char * status() const override
internal cleanup; do not call directly
void noteSpareAllowance()
reacts to satisfying happy_eyeballs_connect_gap and happy_eyeballs_connect_limit
void noteCandidatesChange()
reacts to changes in the destinations list
void stopWaitingForSpareAllowance()
called when the spare attempt should no longer obey spare connection limits
void cancelSpareWait(const char *reason)
stops waiting for the right conditions to open a spare connection
PeerConnectionPointer lastFailedConnection
nil if none has failed
HappySpareWait spareWaiting
preconditions for an attempt to open a spare connection
AsyncCall::Pointer callback_
handler to be called on connection completion.
CodeContext::Pointer codeContext
requestor's context
const time_t fwdStart
requestor start time
void cancel(const char *reason)
aborts an in-progress attempt
void sendFailure()
inform the initiator about our failure to connect (if needed)
void openFreshConnection(Attempt &, PeerConnectionPointer &)

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors