HappyConnOpener.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2021 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:
161 
162  Attempt(const CallbackMethod method, const char *methodName);
163 
164  explicit operator bool() const { return static_cast<bool>(path); }
165 
167  void finish();
168 
170  void cancel(const char *reason);
171 
173 
176 
178  const char * const callbackMethodName;
179  };
180  friend std::ostream &operator <<(std::ostream &, const Attempt &);
181 
182  /* AsyncJob API */
183  virtual void start() override;
184  virtual bool doneAll() const override;
185  virtual void swanSong() override;
186  virtual const char *status() const override;
187 
190 
194 
198 
201  void handleConnOpenerAnswer(Attempt &, const CommConnectCbParams &, const char *connDescription);
202 
203  void checkForNewConnection();
204 
206 
207  void cancelSpareWait(const char *reason);
208 
209  bool ranOutOfTimeOrAttempts() const;
210 
211  ErrorState *makeError(const err_type type) const;
213  void sendSuccess(const PeerConnectionPointer &conn, bool reused, const char *connKind);
214  void sendFailure();
215  void cancelAttempt(Attempt &, const char *reason);
216 
217  const time_t fwdStart;
218 
220 
223 
226 
229 
233 
236  friend class HappyOrderEnforcer;
237 
239 
240  ErrorState *lastError = nullptr;
242 
245 
247  bool gotSpareAllowance = false;
248 
250  bool allowPconn_ = true;
251 
253  bool retriable_ = true;
254 
256  const char *host_ = nullptr;
257 
260 
262  int n_tries;
263 
265  mutable const char *ranOutOfTimeOrAttemptsEarlier_ = nullptr;
266 };
267 
268 #endif
269 
CbcPointer< Initiator > initiator_
object to deliver the answer to
virtual ~CbDialer()=default
void notePrimeConnectDone(const CommConnectCbParams &)
Comm::ConnOpener callback for the prime connection attempt.
a connection opening attempt in progress (or falsy)
const char * ranOutOfTimeOrAttemptsEarlier_
Reason to ran out of time or attempts.
CbDialer(Method method, Initiator *initiator)
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
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:153
Attempt prime
current connection opening attempt on the prime track (if any)
HappyAbsoluteTime primeStart
the start of the first connection attempt for the currentPeer
void maybeGivePrimeItsChance()
err_type
Definition: forward.h:14
void maybeOpenSpareConnection()
if possible, starts a spare connection attempt
void maybeOpenPrimeConnection()
starts a prime connection attempt if possible or does nothing otherwise
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 &)
ResolvedPeersPointer destinations
Candidate paths. Shared with the initiator. May not be finalized yet.
const char *const callbackMethodName
for callbackMethod debugging
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
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
const CallbackMethod callbackMethod
ConnOpener calls this method.
friend std::ostream & operator<<(std::ostream &, const Attempt &)
HappyConnOpener::Attempt printer for debugging.
JobWait< Comm::ConnOpener > connWait
waits for a connection to the peer to be established/opened
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)
bool retriable_
whether we are opening connections for a request that may be resent
AsyncCall dialer for our callback. Gives us access to callback Answer.
HttpRequestPointer cause
the request that needs a to-server connection
bool reuseOldConnection(PeerConnectionPointer &)
void noteSpareConnectDone(const CommConnectCbParams &)
Comm::ConnOpener callback for the spare connection attempt.
bool reused
whether conn was open earlier, by/for somebody else
Attempt(const CallbackMethod method, const char *methodName)
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
void(HappyConnOpener::*)(const CommConnectCbParams &) CallbackMethod
HappyConnOpener method implementing a ConnOpener callback.
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
void handleConnOpenerAnswer(Attempt &, const CommConnectCbParams &, const char *connDescription)
prime/spare-agnostic processing of a Comm::ConnOpener result
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