HappyConnOpener.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2022 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
21class HappyConnOpener;
23class JobGapEnforcer;
25
27typedef std::list< CbcPointer<HappyConnOpener> > HappySpareWaitList;
28
30typedef double HappyAbsoluteTime;
31
34public:
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
55
60 bool forSpareAllowance = false;
61
64 bool forPrimesToFail = false;
65
68 bool forNewPeer = false;
69};
70
73{
74public:
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
97std::ostream &operator <<(std::ostream &, const HappyConnOpenerAnswer &);
98
103{
105public:
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
130public:
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
145
148
150 void noteSpareAllowance();
151
154
155private:
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
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
242
245
247 bool gotSpareAllowance = false;
248
250 bool allowPconn_ = true;
251
253 bool retriable_ = true;
254
256 const char *host_ = nullptr;
257
260
264
266 mutable const char *ranOutOfTimeOrAttemptsEarlier_ = nullptr;
267};
268
269#endif
270
RefCount< ResolvedPeers > ResolvedPeersPointer
std::list< CbcPointer< HappyConnOpener > > HappySpareWaitList
A FIFO queue of HappyConnOpener jobs waiting to open a spare connection.
double HappyAbsoluteTime
absolute time in fractional seconds; compatible with current_timed
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
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
Final result (an open connection or an error) sent to the job initiator.
bool success() const
whether HappyConnOpener succeeded, returning a usable connection
bool reused
whether conn was open earlier, by/for somebody else
PeerConnectionPointer conn
CbcPointer< ErrorState > error
problem details (nil on success)
a connection opening attempt in progress (or falsy)
void finish()
reacts to a natural attempt completion (successful or otherwise)
const char *const callbackMethodName
for callbackMethod debugging
void(HappyConnOpener::*)(const CommConnectCbParams &) CallbackMethod
HappyConnOpener method implementing a ConnOpener callback.
JobWait< Comm::ConnOpener > connWait
waits for a connection to the peer to be established/opened
void cancel(const char *reason)
aborts an in-progress attempt
const CallbackMethod callbackMethod
ConnOpener calls this method.
PeerConnectionPointer path
the destination we are connecting to
Attempt(const CallbackMethod method, const char *methodName)
AsyncCall dialer for our callback. Gives us access to callback Answer.
Method method_
initiator_ method to call with the answer
virtual ~CbDialer()=default
void(Initiator::* Method)(Answer &)
CbcPointer< Initiator > initiator_
object to deliver the answer to
virtual void print(std::ostream &os) const override
CbDialer(Method method, Initiator *initiator)
bool canDial(AsyncCall &)
virtual bool doneAll() const override
whether positive goal has been reached
void noteSpareConnectDone(const CommConnectCbParams &)
Comm::ConnOpener callback for the spare connection attempt.
bool ignoreSpareRestrictions
whether spare connection attempts disregard happy_eyeballs_* settings
bool gotSpareAllowance
whether we have received a permission to open a spare while spares are limited
PeerConnectionPointer lastFailedConnection
nil if none has failed
virtual void start() override
called by AsyncStart; do not call directly
void noteGavePrimeItsChance()
reacts to expired happy_eyeballs_connect_timeout
bool retriable_
whether we are opening connections for a request that may be resent
virtual const char * status() const override
internal cleanup; do not call directly
void cancelAttempt(Attempt &, const char *reason)
cancels the in-progress attempt, making its path a future candidate
Comm::ConnectionPointer currentPeer
void maybeGivePrimeItsChance()
void setHost(const char *)
configures the origin server domain name
const char * ranOutOfTimeOrAttemptsEarlier_
Reason to ran out of time or attempts.
void sendSuccess(const PeerConnectionPointer &conn, bool reused, const char *connKind)
send a successful result to the initiator (if it still needs an answer)
void updateSpareWaitAfterPrimeFailure()
reacts to a prime attempt failure
virtual ~HappyConnOpener() override
CBDATA_CHILD(HappyConnOpener)
HttpRequestPointer cause
the request that needs a to-server connection
void stopGivingPrimeItsChance()
called when the prime attempt has used up its chance for a solo victory
friend std::ostream & operator<<(std::ostream &, const Attempt &)
HappyConnOpener::Attempt printer for debugging.
AccessLogEntryPointer ale
transaction details
void maybeOpenSpareConnection()
if possible, starts a spare connection attempt
Answer * futureAnswer(const PeerConnectionPointer &)
const time_t fwdStart
requestor start time
void checkForNewConnection()
void allowPersistent(bool permitted)
configures reuse of old connections
void handleConnOpenerAnswer(Attempt &, const CommConnectCbParams &, const char *connDescription)
prime/spare-agnostic processing of a Comm::ConnOpener result
bool ranOutOfTimeOrAttempts() const
Check for maximum connection tries and forwarding time restrictions.
void stopWaitingForSpareAllowance()
called when the spare attempt should no longer obey spare connection limits
HappyConnOpenerAnswer Answer
ErrorState * makeError(const err_type type) const
void noteSpareAllowance()
reacts to satisfying happy_eyeballs_connect_gap and happy_eyeballs_connect_limit
HappySpareWait spareWaiting
preconditions for an attempt to open a spare connection
HappyConnOpener(const ResolvedPeersPointer &, const AsyncCall::Pointer &, HttpRequestPointer &, const time_t aFwdStart, int tries, const AccessLogEntryPointer &al)
void sendFailure()
inform the initiator about our failure to connect (if needed)
virtual void swanSong() override
void setRetriable(bool retriable)
configures whether the request may be retried later if things go wrong
ErrorState * lastError
last problem details (or nil)
bool reuseOldConnection(PeerConnectionPointer &)
void startConnecting(Attempt &, PeerConnectionPointer &)
starts opening (or reusing) a connection to the given destination
bool allowPconn_
whether persistent connections are allowed
const char * host_
origin server domain name (or equivalent)
Attempt spare
current connection opening attempt on the spare track (if any)
ResolvedPeersPointer destinations
Candidate paths. Shared with the initiator. May not be finalized yet.
AsyncCall::Pointer callback_
handler to be called on connection completion.
HappyAbsoluteTime primeStart
the start of the first connection attempt for the currentPeer
void maybeOpenPrimeConnection()
starts a prime connection attempt if possible or does nothing otherwise
void openFreshConnection(Attempt &, PeerConnectionPointer &)
void notePrimeConnectDone(const CommConnectCbParams &)
Comm::ConnOpener callback for the prime connection attempt.
void cancelSpareWait(const char *reason)
stops waiting for the right conditions to open a spare connection
void noteCandidatesChange()
reacts to changes in the destinations list
Attempt prime
current connection opening attempt on the prime track (if any)
keeps track of HappyConnOpener spare track waiting state
HappySpareWaitList::iterator position
CodeContext::Pointer codeContext
requestor's context
AsyncCall::Pointer callback
a pending noteGavePrimeItsChance() or noteSpareAllowance() call
err_type
Definition: forward.h:14
int type
Definition: errorpage.cc:152

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors