MessageDelayPools.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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 "SquidTime.h"
21 #include "Store.h"
22 
23 #include <algorithm>
24 #include <map>
25 
27 {
28  freePools();
29 }
30 
33 {
34  static MessageDelayPools pools;
35  return &pools;
36 }
37 
40 {
41  auto it = std::find_if(pools.begin(), pools.end(),
42  [&name](const MessageDelayPool::Pointer p) { return p->poolName == name; });
43  return it == pools.end() ? 0 : *it;
44 }
45 
46 void
48 {
49  const auto it = std::find_if(pools.begin(), pools.end(),
50  [&p](const MessageDelayPool::Pointer mp) { return mp->poolName == p->poolName; });
51  if (it != pools.end()) {
52  debugs(3, DBG_CRITICAL, "WARNING: Ignoring duplicate " << p->poolName << " response delay pool");
53  return;
54  }
55  pools.push_back(p);
56 }
57 
58 void
60 {
61  pools.clear();
62 }
63 
64 MessageDelayPool::MessageDelayPool(const SBuf &name, int64_t bucketSpeed, int64_t bucketSize,
65  int64_t aggregateSpeed, int64_t aggregateSize, uint16_t initialBucketPercent):
66  access(0),
67  poolName(name),
68  individualRestore(bucketSpeed),
69  individualMaximum(bucketSize),
70  aggregateRestore(aggregateSpeed),
71  aggregateMaximum(aggregateSize),
72  initialBucketLevel(initialBucketPercent),
73  lastUpdate(squid_curtime)
74 {
76 }
77 
79 {
80  if (access)
82 }
83 
84 void
86 {
87  if (noLimit())
88  return;
89  const int incr = squid_curtime - lastUpdate;
90  if (incr >= 1) {
91  lastUpdate = squid_curtime;
92  DelaySpec spec;
95  theBucket.update(spec, incr);
96  }
97 }
98 
99 void
101 {
102  SBuf name("response_delay_pool_access ");
103  name.append(poolName);
104  dump_acl_access(entry, name.c_str(), access);
105  storeAppendPrintf(entry, "response_delay_pool parameters %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %d\n",
107  storeAppendPrintf(entry, "\n");
108 }
109 
112 {
114 }
115 
116 void
118 {
119  static const SBuf bucketSpeedLimit("individual-restore");
120  static const SBuf maxBucketSize("individual-maximum");
121  static const SBuf aggregateSpeedLimit("aggregate-restore");
122  static const SBuf maxAggregateSize("aggregate-maximum");
123  static const SBuf initialBucketPercent("initial-bucket-level");
124 
125  static std::map<SBuf, int64_t> params;
126  params[bucketSpeedLimit] = -1;
127  params[maxBucketSize] = -1;
128  params[aggregateSpeedLimit] = -1;
129  params[maxAggregateSize] = -1;
130  params[initialBucketPercent] = 50;
131 
132  const SBuf name(ConfigParser::NextToken());
133  if (name.isEmpty()) {
134  debugs(3, DBG_CRITICAL, "FATAL: response_delay_pool missing required \"name\" parameter.");
135  self_destruct();
136  return;
137  }
138 
139  char *key = nullptr;
140  char *value = nullptr;
141  while (ConfigParser::NextKvPair(key, value)) {
142  if (!value) {
143  debugs(3, DBG_CRITICAL, "FATAL: '" << key << "' option missing value");
144  self_destruct();
145  return;
146  }
147  auto it = params.find(SBuf(key));
148  if (it == params.end()) {
149  debugs(3, DBG_CRITICAL, "FATAL: response_delay_pool unknown option '" << key << "'");
150  self_destruct();
151  return;
152  }
153  it->second = (it->first == initialBucketPercent) ? xatos(value) : xatoll(value, 10);
154  }
155 
156  const char *fatalMsg = nullptr;
157  if ((params[bucketSpeedLimit] < 0) != (params[maxBucketSize] < 0))
158  fatalMsg = "'individual-restore' and 'individual-maximum'";
159  else if ((params[aggregateSpeedLimit] < 0) != (params[maxAggregateSize] < 0))
160  fatalMsg = "'aggregate-restore' and 'aggregate-maximum'";
161 
162  if (fatalMsg) {
163  debugs(3, DBG_CRITICAL, "FATAL: must use " << fatalMsg << " options in conjunction");
164  self_destruct();
165  return;
166  }
167 
168  MessageDelayPool *pool = new MessageDelayPool(name,
169  params[bucketSpeedLimit],
170  params[maxBucketSize],
171  params[aggregateSpeedLimit],
172  params[maxAggregateSize],
173  static_cast<uint16_t>(params[initialBucketPercent])
174  );
176 }
177 
178 void
180  const char *token = ConfigParser::NextToken();
181  if (!token) {
182  debugs(3, DBG_CRITICAL, "ERROR: required pool_name option missing");
183  return;
184  }
186  static ConfigParser parser;
187  if (pool)
188  aclParseAccessLine("response_delay_pool_access", parser, &pool->access);
189 }
190 
191 void
193 {
195 }
196 
197 void
199 {
200  auto &pools = MessageDelayPools::Instance()->pools;
201  for (auto pool: pools)
202  pool->dump(entry);
203 }
204 
205 #endif
206 
void update(DelaySpec const &, int incr)
Definition: DelayBucket.cc:26
int const & level() const
Definition: DelayBucket.h:24
MessageDelayPool(const SBuf &name, int64_t bucketSpeed, int64_t bucketSize, int64_t aggregateSpeed, int64_t aggregateSize, uint16_t initialBucketPercent)
void dump_acl_access(StoreEntry *entry, const char *name, acl_access *head)
Definition: cache_cf.cc:1398
Definition: SBuf.h:86
bool noLimit() const
whether the aggregate bucket has no limit
void self_destruct(void)
Definition: cache_cf.cc:257
DelayBucket theBucket
the aggregate bucket
void add(MessageDelayPool *pool)
appends a single MessageDelayPool, created during configuration
#define PRId64
Definition: types.h:110
SBuf & append(const SBuf &S)
Definition: SBuf.cc:195
int64_t aggregateMaximum
the maximum size of the aggregate bucket
SBuf poolName
the response delay pool name
Limits Squid-to-client bandwidth for each matching response.
Definition: MessageBucket.h:20
bool isEmpty() const
Definition: SBuf.h:420
#define DBG_CRITICAL
Definition: Debug.h:45
int64_t xatoll(const char *token, int base, char eov)
Definition: Parsing.cc:89
char * p
Definition: membanger.c:43
time_t squid_curtime
Definition: stub_time.cc:17
void freePools()
memory cleanup, performing during reconfiguration
int64_t individualRestore
the speed limit of an individual bucket (bytes/s)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
int restore_bps
Definition: DelaySpec.h:23
static char * NextToken()
void aclDestroyAccessList(acl_access **list)
Definition: Gadgets.cc:275
const char * c_str()
Definition: SBuf.cc:526
acl_access * access
unsigned short xatos(const char *token)
Definition: Parsing.cc:108
void refillBucket()
Increases the aggregate bucket level with the aggregateRestore speed.
static MessageDelayPools * Instance()
void dump(StoreEntry *entry) const
uint16_t initialBucketLevel
the initial bucket size as a percentage of individualMaximum
time_t lastUpdate
Time the aggregate bucket level was last refilled.
MessageBucketPointer createBucket()
creates an individual response bucket
int64_t aggregateRestore
the speed limit of the aggregate bucket (bytes/s)
MessageDelayPool::Pointer pool(const SBuf &name)
returns a MessageDelayPool with a given name or null otherwise
static bool NextKvPair(char *&key, char *&value)
std::vector< MessageDelayPool::Pointer > pools
int64_t individualMaximum
the maximum size of an individual bucket
void dumpResponseDelayPoolParameters(StoreEntry *e, const char *name)
int64_t max_bytes
Definition: DelaySpec.h:24
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:875
void aclParseAccessLine(const char *directive, ConfigParser &, acl_access **treep)
Definition: Gadgets.cc:136

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors