HappyConnOpener.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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_SRC_HAPPYCONNOPENER_H
10 #define SQUID_SRC_HAPPYCONNOPENER_H
11 #include "base/AsyncCallbacks.h"
12 #include "base/JobWait.h"
13 #include "base/RefCount.h"
14 #include "comm.h"
15 #include "comm/Connection.h"
16 #include "comm/ConnOpener.h"
17 #include "errorpage.h"
18 #include "http/forward.h"
19 #include "log/forward.h"
20 #include "ResolvedPeers.h"
21 
22 #include <iosfwd>
23 
24 class HappyConnOpener;
25 class HappyOrderEnforcer;
26 class JobGapEnforcer;
28 
30 typedef std::list< CbcPointer<HappyConnOpener> > HappySpareWaitList;
31 
33 typedef double HappyAbsoluteTime;
34 
37 public:
38  explicit operator bool() const { return toGivePrimeItsChance || forSpareAllowance || forPrimesToFail || forNewPeer; }
39 
42  void clear() { *this = HappySpareWait(); }
43 
45 
48 
51  HappySpareWaitList::iterator position;
52 
53  /* The following four fields represent mutually exclusive wait reasons. */
54 
57  bool toGivePrimeItsChance = false;
58 
63  bool forSpareAllowance = false;
64 
67  bool forPrimesToFail = false;
68 
71  bool forNewPeer = false;
72 };
73 
76 {
77 public:
79 
81  bool success() const { return !error; }
82 
86 
87  // answer recipients must clear the error member in order to keep its info
88  // XXX: We should refcount ErrorState instead of cbdata-protecting it.
90 
93  int n_tries = 0;
94 
96  bool reused = false;
97 };
98 
100 std::ostream &operator <<(std::ostream &, const HappyConnOpenerAnswer &);
101 
106 {
108 public:
110 
111 public:
112  HappyConnOpener(const ResolvedPeersPointer &, const AsyncCallback<Answer> &, const HttpRequestPointer &, time_t aFwdStart, int tries, const AccessLogEntryPointer &);
113  ~HappyConnOpener() override;
114 
116  void allowPersistent(bool permitted) { allowPconn_ = permitted; }
117 
119  void setRetriable(bool retriable) { retriable_ = retriable; }
120 
122  void setHost(const char *);
123 
125  void noteCandidatesChange();
126 
128  void noteGavePrimeItsChance();
129 
131  void noteSpareAllowance();
132 
135 
136 private:
138  class Attempt {
139  public:
142 
143  Attempt(const CallbackMethod method, const char *methodName);
144 
145  explicit operator bool() const { return static_cast<bool>(path); }
146 
148  void finish();
149 
151  void cancel(const char *reason);
152 
154 
157 
159  const char * const callbackMethodName;
160  };
161  friend std::ostream &operator <<(std::ostream &, const Attempt &);
162 
163  /* AsyncJob API */
164  void start() override;
165  bool doneAll() const override;
166  void swanSong() override;
167  const char *status() const override;
168 
171 
175 
179 
182  void handleConnOpenerAnswer(Attempt &, const CommConnectCbParams &, const char *connDescription);
183 
184  void checkForNewConnection();
185 
187 
188  void cancelSpareWait(const char *reason);
189 
190  bool ranOutOfTimeOrAttempts() const;
191 
192  ErrorState *makeError(const err_type type) const;
194  void sendSuccess(const PeerConnectionPointer &conn, bool reused, const char *connKind);
195  void sendFailure();
196  void cancelAttempt(Attempt &, const char *reason);
197 
198  const time_t fwdStart;
199 
202 
205 
208 
211 
215 
218  friend class HappyOrderEnforcer;
219 
221 
222  ErrorState *lastError = nullptr;
224 
227 
229  bool gotSpareAllowance = false;
230 
232  bool allowPconn_ = true;
233 
235  bool retriable_ = true;
236 
238  const char *host_ = nullptr;
239 
242 
245  int n_tries;
246 
248  mutable const char *ranOutOfTimeOrAttemptsEarlier_ = nullptr;
249 };
250 
251 #endif /* SQUID_SRC_HAPPYCONNOPENER_H */
252 
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.
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
RefCount< ResolvedPeers > ResolvedPeersPointer
~HappyConnOpener() override
AsyncCall::Pointer callback
a pending noteGavePrimeItsChance() or noteSpareAllowance() call
void checkForNewConnection()
ErrorState * makeError(const err_type type) const
a smart AsyncCall pointer for delivery of future results
void cancelAttempt(Attempt &, const char *reason)
cancels the in-progress attempt, making its path a future candidate
HappyConnOpenerAnswer Answer
void start() override
called by AsyncStart; do not call directly
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
bool allowPconn_
whether persistent connections are allowed
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.
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)
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)
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
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
const char * status() const override
internal cleanup; do not call directly
AsyncCallback< Answer > callback_
answer destination
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
HappyConnOpener(const ResolvedPeersPointer &, const AsyncCallback< Answer > &, const HttpRequestPointer &, time_t aFwdStart, int tries, const AccessLogEntryPointer &)
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
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