]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/History.cc
2 * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
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.
10 #include "adaptation/Config.h"
11 #include "adaptation/History.h"
12 #include "base/TextException.h"
15 #include "SquidTime.h"
17 /// impossible services value to identify unset theNextServices
18 const static char *TheNullServices
= ",null,";
20 Adaptation::History::Entry::Entry(const String
&serviceId
, const timeval
&when
):
21 service(serviceId
), start(when
), theRptm(-1), retried(false)
25 Adaptation::History::Entry::Entry():
26 start(current_time
), theRptm(-1), retried(false)
30 void Adaptation::History::Entry::stop()
32 // theRptm may already be set if the access log entry has already been made
33 (void)rptm(); // will cache result in theRptm if not set already
36 int Adaptation::History::Entry::rptm()
39 theRptm
= tvSubMsec(start
, current_time
);
43 Adaptation::History::History():
46 theNextServices(TheNullServices
)
50 int Adaptation::History::recordXactStart(const String
&serviceId
, const timeval
&when
, bool retrying
)
52 // the history will be empty on retries if it was enabled after the failure
53 if (retrying
&& !theEntries
.empty())
54 theEntries
.back().retried
= true;
56 theEntries
.push_back(Adaptation::History::Entry(serviceId
, when
));
57 return theEntries
.size() - 1; // record position becomes history ID
60 void Adaptation::History::recordXactFinish(int hid
)
62 Must(0 <= hid
&& hid
< static_cast<int>(theEntries
.size()));
63 theEntries
[hid
].stop();
66 void Adaptation::History::allLogString(const char *serviceId
, SBuf
&s
)
69 bool prevWasRetried
= false;
70 for (auto &i
: theEntries
) {
71 // TODO: here and below, optimize service ID comparison?
72 if (!serviceId
|| i
.service
== serviceId
) {
73 if (!s
.isEmpty()) // not the first logged time, must delimit
74 s
.append(prevWasRetried
? '+' : ',');
75 s
.appendf("%d", i
.rptm());
76 // continue; we may have two identical services (e.g., for retries)
78 prevWasRetried
= i
.retried
;
82 void Adaptation::History::sumLogString(const char *serviceId
, SBuf
&s
)
85 int retriedRptm
= 0; // sum of rptm times of retried transactions
86 for (auto & i
: theEntries
) {
87 if (i
.retried
) { // do not log retried xact but accumulate their time
88 retriedRptm
+= i
.rptm();
89 } else if (!serviceId
|| i
.service
== serviceId
) {
90 if (!s
.isEmpty()) // not the first logged time, must delimit
92 s
.appendf("%d", retriedRptm
+ i
.rptm());
93 // continue; we may have two identical services (e.g., for retries)
100 // the last transaction is never retried or it would not be the last
104 void Adaptation::History::updateXxRecord(const char *name
, const String
&value
)
110 bool Adaptation::History::getXxRecord(String
&name
, String
&value
) const
112 if (theXxName
.size() <= 0)
120 void Adaptation::History::updateNextServices(const String
&services
)
122 if (theNextServices
!= TheNullServices
)
123 debugs(93,3, HERE
<< "old services: " << theNextServices
);
124 debugs(93,3, HERE
<< "new services: " << services
);
125 Must(services
!= TheNullServices
);
126 theNextServices
= services
;
129 bool Adaptation::History::extractNextServices(String
&value
)
131 if (theNextServices
== TheNullServices
)
134 value
= theNextServices
;
135 theNextServices
= TheNullServices
; // prevents resetting the plan twice
139 void Adaptation::History::recordMeta(const HttpHeader
*lm
)
149 Adaptation::History::recordAdaptationService(SBuf
&srvId
)
151 theAdaptationServices
.push_back(srvId
);
155 Adaptation::History::setFutureServices(const DynamicGroupCfg
&services
)
157 if (!theFutureServices
.empty())
158 debugs(93,3, HERE
<< "old future services: " << theFutureServices
);
159 debugs(93,3, HERE
<< "new future services: " << services
);
160 theFutureServices
= services
; // may be empty
163 bool Adaptation::History::extractFutureServices(DynamicGroupCfg
&value
)
165 if (theFutureServices
.empty())
168 value
= theFutureServices
;
169 theFutureServices
.clear();