MessageDelayPools.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 
11 #if USE_DELAY_POOLS
12 #include "acl/Gadgets.h"
13 #include "cache_cf.h"
14 #include "ConfigParser.h"
15 #include "DelaySpec.h"
16 #include "event.h"
17 #include "MessageBucket.h"
18 #include "MessageDelayPools.h"
19 #include "Parsing.h"
20 #include "Store.h"
21 
22 #include <algorithm>
23 #include <map>
24 
26 {
27  freePools();
28 }
29 
32 {
33  static MessageDelayPools pools;
34  return &pools;
35 }
36 
39 {
40  auto it = std::find_if(pools.begin(), pools.end(),
41  [&name](const MessageDelayPool::Pointer p) { return p->poolName == name; });
42  return it == pools.end() ? nullptr : *it;
43 }
44 
45 void
47 {
48  const auto it = std::find_if(pools.begin(), pools.end(),
49  [&p](const MessageDelayPool::Pointer mp) { return mp->poolName == p->poolName; });
50  if (it != pools.end()) {
51  debugs(3, DBG_CRITICAL, "WARNING: Ignoring duplicate " << p->poolName << " response delay pool");
52  return;
53  }
54  pools.push_back(p);
55 }
56 
57 void
59 {
60  pools.clear();
61 }
62 
63 MessageDelayPool::MessageDelayPool(const SBuf &name, int64_t bucketSpeed, int64_t bucketSize,
64  int64_t aggregateSpeed, int64_t aggregateSize, uint16_t initialBucketPercent):
65  access(nullptr),
66  poolName(name),
67  individualRestore(bucketSpeed),
68  individualMaximum(bucketSize),
69  aggregateRestore(aggregateSpeed),
70  aggregateMaximum(aggregateSize),
71  initialBucketLevel(initialBucketPercent),
72  lastUpdate(squid_curtime)
73 {
75 }
76 
78 {
79  if (access)
81 }
82 
83 void
85 {
86  if (noLimit())
87  return;
88  const int incr = squid_curtime - lastUpdate;
89  if (incr >= 1) {
91  DelaySpec spec;
94  theBucket.update(spec, incr);
95  }
96 }
97 
98 void
100 {
101  SBuf name("response_delay_pool_access ");
102  name.append(poolName);
103  dump_acl_access(entry, name.c_str(), access);
104  storeAppendPrintf(entry, "response_delay_pool parameters %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %d\n",
106  storeAppendPrintf(entry, "\n");
107 }
108 
111 {
113 }
114 
115 void
117 {
118  static const SBuf bucketSpeedLimit("individual-restore");
119  static const SBuf maxBucketSize("individual-maximum");
120  static const SBuf aggregateSpeedLimit("aggregate-restore");
121  static const SBuf maxAggregateSize("aggregate-maximum");
122  static const SBuf initialBucketPercent("initial-bucket-level");
123 
124  static std::map<SBuf, int64_t> params;
125  params[bucketSpeedLimit] = -1;
126  params[maxBucketSize] = -1;
127  params[aggregateSpeedLimit] = -1;
128  params[maxAggregateSize] = -1;
129  params[initialBucketPercent] = 50;
130 
131  const SBuf name(ConfigParser::NextToken());
132  if (name.isEmpty()) {
133  debugs(3, DBG_CRITICAL, "FATAL: response_delay_pool missing required \"name\" parameter.");
134  self_destruct();
135  return;
136  }
137 
138  char *key = nullptr;
139  char *value = nullptr;
140  while (ConfigParser::NextKvPair(key, value)) {
141  if (!value) {
142  debugs(3, DBG_CRITICAL, "FATAL: '" << key << "' option missing value");
143  self_destruct();
144  return;
145  }
146  auto it = params.find(SBuf(key));
147  if (it == params.end()) {
148  debugs(3, DBG_CRITICAL, "FATAL: response_delay_pool unknown option '" << key << "'");
149  self_destruct();
150  return;
151  }
152  it->second = (it->first == initialBucketPercent) ? xatos(value) : xatoll(value, 10);
153  }
154 
155  const char *fatalMsg = nullptr;
156  if ((params[bucketSpeedLimit] < 0) != (params[maxBucketSize] < 0))
157  fatalMsg = "'individual-restore' and 'individual-maximum'";
158  else if ((params[aggregateSpeedLimit] < 0) != (params[maxAggregateSize] < 0))
159  fatalMsg = "'aggregate-restore' and 'aggregate-maximum'";
160 
161  if (fatalMsg) {
162  debugs(3, DBG_CRITICAL, "FATAL: must use " << fatalMsg << " options in conjunction");
163  self_destruct();
164  return;
165  }
166 
167  MessageDelayPool *pool = new MessageDelayPool(name,
168  params[bucketSpeedLimit],
169  params[maxBucketSize],
170  params[aggregateSpeedLimit],
171  params[maxAggregateSize],
172  static_cast<uint16_t>(params[initialBucketPercent])
173  );
175 }
176 
177 void
179  const char *token = ConfigParser::NextToken();
180  if (!token) {
181  debugs(3, DBG_CRITICAL, "ERROR: required pool_name option missing");
182  return;
183  }
185  static ConfigParser parser;
186  if (pool)
187  aclParseAccessLine("response_delay_pool_access", parser, &pool->access);
188 }
189 
190 void
192 {
194 }
195 
196 void
198 {
199  auto &pools = MessageDelayPools::Instance()->pools;
200  for (auto pool: pools)
201  pool->dump(entry);
202 }
203 
204 #endif
205 
MessageDelayPool::Pointer pool(const SBuf &name)
returns a MessageDelayPool with a given name or null otherwise
MessageDelayPool(const SBuf &name, int64_t bucketSpeed, int64_t bucketSize, int64_t aggregateSpeed, int64_t aggregateSize, uint16_t initialBucketPercent)
#define DBG_CRITICAL
Definition: Stream.h:37
void refillBucket()
Increases the aggregate bucket level with the aggregateRestore speed.
DelayBucket theBucket
the aggregate bucket
bool isEmpty() const
Definition: SBuf.h:435
time_t lastUpdate
Time the aggregate bucket level was last refilled.
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:855
int64_t aggregateRestore
the speed limit of the aggregate bucket (bytes/s)
Definition: SBuf.h:93
unsigned short xatos(const char *token)
Definition: Parsing.cc:114
void dumpResponseDelayPoolParameters(StoreEntry *)
void self_destruct(void)
Definition: cache_cf.cc:276
std::vector< MessageDelayPool::Pointer > pools
int restore_bps
Definition: DelaySpec.h:23
void dump_acl_access(StoreEntry *entry, const char *name, acl_access *head)
Definition: cache_cf.cc:1511
bool noLimit() const
whether the aggregate bucket has no limit
void update(DelaySpec const &, int incr)
Definition: DelayBucket.cc:26
int64_t aggregateMaximum
the maximum size of the aggregate bucket
int64_t individualMaximum
the maximum size of an individual bucket
uint16_t initialBucketLevel
the initial bucket size as a percentage of individualMaximum
MessageBucketPointer createBucket()
creates an individual response bucket
~MessageDelayPool() override
void freePools()
memory cleanup, performing during reconfiguration
static bool NextKvPair(char *&key, char *&value)
const char * c_str()
Definition: SBuf.cc:516
acl_access * access
time_t squid_curtime
Definition: stub_libtime.cc:20
SBuf & append(const SBuf &S)
Definition: SBuf.cc:185
static char * NextToken()
void aclDestroyAccessList(acl_access **list)
Definition: Gadgets.cc:223
int64_t xatoll(const char *token, int base, char eov)
Definition: Parsing.cc:86
void dump(StoreEntry *entry) const
int const & level() const
Definition: DelayBucket.h:24
static MessageDelayPools * Instance()
void add(MessageDelayPool *pool)
appends a single MessageDelayPool, created during configuration
#define PRId64
Definition: types.h:104
void aclParseAccessLine(const char *directive, ConfigParser &, acl_access **config)
Parses a single line of a "action followed by acls" directive (e.g., http_access).
Definition: Gadgets.cc:132
int64_t individualRestore
the speed limit of an individual bucket (bytes/s)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
int64_t max_bytes
Definition: DelaySpec.h:24
SBuf poolName
the response delay pool name
Limits Squid-to-client bandwidth for each matching response.
Definition: MessageBucket.h:20

 

Introduction

Documentation

Support

Miscellaneous