]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/History.cc
2 #include "adaptation/Config.h"
3 #include "adaptation/History.h"
4 #include "base/TextException.h"
8 /// impossible services value to identify unset theNextServices
9 const static char *TheNullServices
= ",null,";
11 Adaptation::History::Entry::Entry(const String
&serviceId
, const timeval
&when
):
12 service(serviceId
), start(when
), theRptm(-1), retried(false)
16 Adaptation::History::Entry::Entry():
17 start(current_time
), theRptm(-1), retried(false)
21 void Adaptation::History::Entry::stop()
23 // theRptm may already be set if the access log entry has already been made
24 (void)rptm(); // will cache result in theRptm if not set already
27 int Adaptation::History::Entry::rptm()
30 theRptm
= tvSubMsec(start
, current_time
);
35 Adaptation::History::History():
38 theNextServices(TheNullServices
)
42 int Adaptation::History::recordXactStart(const String
&serviceId
, const timeval
&when
, bool retrying
)
44 // the history will be empty on retries if it was enabled after the failure
45 if (retrying
&& !theEntries
.empty())
46 theEntries
.back().retried
= true;
48 theEntries
.push_back(Adaptation::History::Entry(serviceId
, when
));
49 return theEntries
.size() - 1; // record position becomes history ID
52 void Adaptation::History::recordXactFinish(int hid
)
54 Must(0 <= hid
&& hid
< static_cast<int>(theEntries
.size()));
55 theEntries
[hid
].stop();
58 void Adaptation::History::allLogString(const char *serviceId
, String
&s
)
61 bool prevWasRetried
= false;
62 // XXX: Fix Vector<> so that we can use const_iterator here
63 typedef Adaptation::History::Entries::iterator ECI
;
64 for (ECI i
= theEntries
.begin(); i
!= theEntries
.end(); ++i
) {
65 // TODO: here and below, optimize service ID comparison?
66 if (!serviceId
|| i
->service
== serviceId
) {
67 if (s
.size() > 0) // not the first logged time, must delimit
68 s
.append(prevWasRetried
? "+" : ",");
71 snprintf(buf
, sizeof(buf
), "%d", i
->rptm());
74 // continue; we may have two identical services (e.g., for retries)
76 prevWasRetried
= i
->retried
;
80 void Adaptation::History::sumLogString(const char *serviceId
, String
&s
)
83 int retriedRptm
= 0; // sum of rptm times of retried transactions
84 typedef Adaptation::History::Entries::iterator ECI
;
85 for (ECI i
= theEntries
.begin(); i
!= theEntries
.end(); ++i
) {
86 if (i
->retried
) { // do not log retried xact but accumulate their time
87 retriedRptm
+= i
->rptm();
88 } else if (!serviceId
|| i
->service
== serviceId
) {
89 if (s
.size() > 0) // not the first logged time, must delimit
93 snprintf(buf
, sizeof(buf
), "%d", retriedRptm
+ i
->rptm());
96 // continue; we may have two identical services (e.g., for retries)
103 // the last transaction is never retried or it would not be the last
107 void Adaptation::History::updateXxRecord(const char *name
, const String
&value
)
113 bool Adaptation::History::getXxRecord(String
&name
, String
&value
) const
115 if (theXxName
.size() <= 0)
123 void Adaptation::History::updateNextServices(const String
&services
)
125 if (theNextServices
!= TheNullServices
)
126 debugs(93,3, HERE
<< "old services: " << theNextServices
);
127 debugs(93,3, HERE
<< "new services: " << services
);
128 Must(services
!= TheNullServices
);
129 theNextServices
= services
;
132 bool Adaptation::History::extractNextServices(String
&value
)
134 if (theNextServices
== TheNullServices
)
137 value
= theNextServices
;
138 theNextServices
= TheNullServices
; // prevents resetting the plan twice
142 void Adaptation::History::recordMeta(const HttpHeader
*lm
)
145 lastMeta
.update(lm
, NULL
);
147 allMeta
.update(lm
, NULL
);
152 Adaptation::History::setFutureServices(const DynamicGroupCfg
&services
)
154 if (!theFutureServices
.empty())
155 debugs(93,3, HERE
<< "old future services: " << theFutureServices
);
156 debugs(93,3, HERE
<< "new future services: " << services
);
157 theFutureServices
= services
; // may be empty
160 bool Adaptation::History::extractFutureServices(DynamicGroupCfg
&value
)
162 if (theFutureServices
.empty())
165 value
= theFutureServices
;
166 theFutureServices
.clear();