History.cc
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 #include "squid.h"
10 #include "adaptation/Config.h"
11 #include "adaptation/History.h"
13 #include "base/TextException.h"
14 #include "debug/Stream.h"
15 #include "globals.h"
16 #include "time/gadgets.h"
17 
19 const static char *TheNullServices = ",null,";
20 
21 Adaptation::History::Entry::Entry(const String &serviceId, const timeval &when):
22  service(serviceId), start(when), theRptm(-1), retried(false)
23 {
24 }
25 
27  start(current_time), theRptm(-1), retried(false)
28 {
29 }
30 
32 {
33  // theRptm may already be set if the access log entry has already been made
34  (void)rptm(); // will cache result in theRptm if not set already
35 }
36 
38 {
39  if (theRptm < 0)
40  theRptm = tvSubMsec(start, current_time);
41  return theRptm;
42 }
43 
48 {
49 }
50 
51 int Adaptation::History::recordXactStart(const String &serviceId, const timeval &when, bool retrying)
52 {
53  // the history will be empty on retries if it was enabled after the failure
54  if (retrying && !theEntries.empty())
55  theEntries.back().retried = true;
56 
57  theEntries.push_back(Adaptation::History::Entry(serviceId, when));
58  return theEntries.size() - 1; // record position becomes history ID
59 }
60 
62 {
63  Must(0 <= hid && hid < static_cast<int>(theEntries.size()));
64  theEntries[hid].stop();
65 }
66 
67 void Adaptation::History::allLogString(const char *serviceId, SBuf &s)
68 {
69  s.clear();
70  bool prevWasRetried = false;
71  for (auto &i : theEntries) {
72  // TODO: here and below, optimize service ID comparison?
73  if (!serviceId || i.service == serviceId) {
74  if (!s.isEmpty()) // not the first logged time, must delimit
75  s.append(prevWasRetried ? '+' : ',');
76  s.appendf("%d", i.rptm());
77  // continue; we may have two identical services (e.g., for retries)
78  }
79  prevWasRetried = i.retried;
80  }
81 }
82 
83 void Adaptation::History::sumLogString(const char *serviceId, SBuf &s)
84 {
85  s.clear();
86  int retriedRptm = 0; // sum of rptm times of retried transactions
87  for (auto & i : theEntries) {
88  if (i.retried) { // do not log retried xact but accumulate their time
89  retriedRptm += i.rptm();
90  } else if (!serviceId || i.service == serviceId) {
91  if (!s.isEmpty()) // not the first logged time, must delimit
92  s.append(',');
93  s.appendf("%d", retriedRptm + i.rptm());
94  // continue; we may have two identical services (e.g., for retries)
95  }
96 
97  if (!i.retried)
98  retriedRptm = 0;
99  }
100 
101  // the last transaction is never retried or it would not be the last
102  Must(!retriedRptm);
103 }
104 
105 void Adaptation::History::updateXxRecord(const char *name, const String &value)
106 {
107  theXxName = name;
108  theXxValue = value;
109 }
110 
112 {
113  if (theXxName.size() <= 0)
114  return false;
115 
116  name = theXxName;
117  value = theXxValue;
118  return true;
119 }
120 
122 {
123  if (theNextServices != TheNullServices)
124  debugs(93,3, "old services: " << theNextServices);
125  debugs(93,3, "new services: " << services);
126  Must(services != TheNullServices);
127  theNextServices = services;
128 }
129 
131 {
132  if (theNextServices == TheNullServices)
133  return false;
134 
135  value = theNextServices;
136  theNextServices = TheNullServices; // prevents resetting the plan twice
137  return true;
138 }
139 
141 {
142  lastMeta.clean();
143  lastMeta.update(lm);
144 
145  allMeta.update(lm);
146  allMeta.compact();
147 }
148 
149 void
151 {
152  theAdaptationServices.push_back(srvId);
153 }
154 
155 void
157 {
158  if (!theFutureServices.empty())
159  debugs(93,3, "old future services: " << theFutureServices);
160  debugs(93,3, "new future services: " << services);
161  theFutureServices = services; // may be empty
162 }
163 
166 {
167  DynamicGroupCfg current, future;
168  DynamicServiceChain::Split(filter, theFutureServices.serviceIds(), current, future);
169  theFutureServices = future; // may already be the same
170  return current; // may be empty
171 }
172 
@ hoReply
Definition: HttpHeader.h:37
DynamicGroupCfg extractCurrentServices(const ServiceFilter &)
returns and forgets planned/future services matching the given filter
Definition: History.cc:165
HttpHeader allMeta
All REQMOD and RESPMOD meta headers merged. Last field wins conflicts.
Definition: History.h:63
const static char * TheNullServices
impossible services value to identify unset theNextServices
Definition: History.cc:19
bool isEmpty() const
Definition: SBuf.h:435
information used to search for adaptation services
Definition: ServiceFilter.h:22
void updateXxRecord(const char *name, const String &value)
sets or resets a cross-transactional database record
Definition: History.cc:105
void updateNextServices(const String &services)
sets or resets next services for the Adaptation::Iterator to notice
Definition: History.cc:121
Definition: SBuf.h:93
bool getXxRecord(String &name, String &value) const
returns true and fills the record fields iff there is a db record
Definition: History.cc:111
DynamicServiceGroup configuration to remember future dynamic chains.
void clear()
Definition: SBuf.cc:175
int tvSubMsec(struct timeval t1, struct timeval t2)
Definition: gadgets.cc:51
void recordXactFinish(int hid)
record the end of a xact identified by its history ID
Definition: History.cc:61
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:18
bool extractNextServices(String &value)
returns true, fills the value, and resets iff next services were set
Definition: History.cc:130
void stop()
updates stats on transaction end
Definition: History.cc:31
void allLogString(const char *serviceId, SBuf &)
dump individual xaction times to a string
Definition: History.cc:67
SBuf & append(const SBuf &S)
Definition: SBuf.cc:185
static void Split(const ServiceFilter &filter, const String &ids, DynamicGroupCfg &current, DynamicGroupCfg &future)
separates dynamic services matching current location from future ones
void sumLogString(const char *serviceId, SBuf &)
dump xaction times, merging retried and retry times together
Definition: History.cc:83
String theNextServices
services Adaptation::Iterator must use next
Definition: History.h:105
#define Must(condition)
Definition: TextException.h:75
int rptm()
returns response time [msec], calculates it if needed
Definition: History.cc:37
void recordAdaptationService(SBuf &srvId)
Definition: History.cc:150
SBuf & appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Definition: SBuf.cc:229
void recordMeta(const HttpHeader *lm)
store the last meta header fields received from the adaptation service
Definition: History.cc:140
int recordXactStart(const String &serviceId, const timeval &when, bool retrying)
record the start of a xact, return xact history ID
Definition: History.cc:51
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
single Xaction stats (i.e., a historical record entry)
Definition: History.h:79
HttpHeader lastMeta
Last received meta header (REQMOD or RESPMOD, whichever comes last).
Definition: History.h:61
void setFutureServices(const DynamicGroupCfg &services)
sets future services for the Adaptation::AccessCheck to notice
Definition: History.cc:156

 

Introduction

Documentation

Support

Miscellaneous