]> git.ipfire.org Git - thirdparty/squid.git/blame - src/MessageDelayPools.cc
Bug 5428: Warn if pkg-config is not found (#1902)
[thirdparty/squid.git] / src / MessageDelayPools.cc
CommitLineData
b27668ec 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
b27668ec
EB
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"
b27668ec
EB
20#include "Store.h"
21
22#include <algorithm>
23#include <map>
24
25MessageDelayPools::~MessageDelayPools()
26{
27 freePools();
28}
29
30MessageDelayPools *
31MessageDelayPools::Instance()
32{
33 static MessageDelayPools pools;
34 return &pools;
35}
36
37MessageDelayPool::Pointer
38MessageDelayPools::pool(const SBuf &name)
39{
40 auto it = std::find_if(pools.begin(), pools.end(),
41 [&name](const MessageDelayPool::Pointer p) { return p->poolName == name; });
aee3523a 42 return it == pools.end() ? nullptr : *it;
b27668ec
EB
43}
44
45void
46MessageDelayPools::add(MessageDelayPool *p)
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
57void
58MessageDelayPools::freePools()
59{
60 pools.clear();
61}
62
63MessageDelayPool::MessageDelayPool(const SBuf &name, int64_t bucketSpeed, int64_t bucketSize,
64 int64_t aggregateSpeed, int64_t aggregateSize, uint16_t initialBucketPercent):
aee3523a 65 access(nullptr),
b27668ec
EB
66 poolName(name),
67 individualRestore(bucketSpeed),
68 individualMaximum(bucketSize),
69 aggregateRestore(aggregateSpeed),
70 aggregateMaximum(aggregateSize),
71 initialBucketLevel(initialBucketPercent),
72 lastUpdate(squid_curtime)
73{
74 theBucket.level() = aggregateMaximum;
75}
76
77MessageDelayPool::~MessageDelayPool()
78{
79 if (access)
80 aclDestroyAccessList(&access);
81}
82
83void
84MessageDelayPool::refillBucket()
85{
86 if (noLimit())
87 return;
88 const int incr = squid_curtime - lastUpdate;
89 if (incr >= 1) {
90 lastUpdate = squid_curtime;
91 DelaySpec spec;
92 spec.restore_bps = aggregateRestore;
93 spec.max_bytes = aggregateMaximum;
94 theBucket.update(spec, incr);
95 }
96}
97
98void
99MessageDelayPool::dump(StoreEntry *entry) const
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",
105 individualRestore, individualMaximum, aggregateRestore, aggregateMaximum, initialBucketLevel);
106 storeAppendPrintf(entry, "\n");
107}
108
109MessageBucket::Pointer
110MessageDelayPool::createBucket()
111{
112 return new MessageBucket(individualRestore, initialBucketLevel, individualMaximum, this);
113}
114
115void
116MessageDelayConfig::parseResponseDelayPool()
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();
941bcba7 135 return;
b27668ec
EB
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();
941bcba7 144 return;
b27668ec
EB
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();
941bcba7 150 return;
b27668ec
EB
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();
941bcba7 164 return;
b27668ec
EB
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 );
174 MessageDelayPools::Instance()->add(pool);
175}
176
177void
178MessageDelayConfig::parseResponseDelayPoolAccess() {
179 const char *token = ConfigParser::NextToken();
180 if (!token) {
181 debugs(3, DBG_CRITICAL, "ERROR: required pool_name option missing");
182 return;
183 }
184 MessageDelayPool::Pointer pool = MessageDelayPools::Instance()->pool(SBuf(token));
185 static ConfigParser parser;
186 if (pool)
187 aclParseAccessLine("response_delay_pool_access", parser, &pool->access);
188}
189
190void
191MessageDelayConfig::freePools()
192{
193 MessageDelayPools::Instance()->freePools();
194}
195
196void
8b082ed9 197MessageDelayConfig::dumpResponseDelayPoolParameters(StoreEntry *entry)
b27668ec
EB
198{
199 auto &pools = MessageDelayPools::Instance()->pools;
200 for (auto pool: pools)
201 pool->dump(entry);
202}
203
204#endif
205