]> git.ipfire.org Git - thirdparty/squid.git/blob - src/helper.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / helper.h
1 /*
2 * Copyright (C) 1996-2015 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 /* DEBUG: section 84 Helper process maintenance */
10
11 #ifndef SQUID_HELPER_H
12 #define SQUID_HELPER_H
13
14 #include "base/AsyncCall.h"
15 #include "base/InstanceId.h"
16 #include "cbdata.h"
17 #include "comm/forward.h"
18 #include "dlink.h"
19 #include "helper/ChildConfig.h"
20 #include "helper/forward.h"
21 #include "ip/Address.h"
22 #include "SBuf.h"
23
24 #include <list>
25 #include <map>
26
27 /**
28 * Managers a set of individual helper processes with a common queue of requests.
29 *
30 * With respect to load, a helper goes through these states (roughly):
31 * idle: no processes are working on requests (and no requests are queued);
32 * normal: some, but not all processes are working (and no requests are queued);
33 * busy: all processes are working (and some requests are possibly queued);
34 * full: all processes are working and at least 2*#processes requests are queued.
35 *
36 * A "busy" helper queues new requests and issues a WARNING every 10 minutes or so.
37 * A "full" helper either drops new requests or keeps queuing them, depending on
38 * whether the caller can handle dropped requests (trySubmit vs helperSubmit APIs).
39 * An attempt to use a "full" helper that has been "full" for 3+ minutes kills worker.
40 * Given enough load, all helpers except for external ACL will make such attempts.
41 */
42 class helper
43 {
44 CBDATA_CLASS(helper);
45
46 public:
47 inline helper(const char *name) :
48 cmdline(NULL),
49 id_name(name),
50 ipc_type(0),
51 full_time(0),
52 last_queue_warn(0),
53 last_restart(0),
54 timeout(0),
55 retryTimedOut(false),
56 retryBrokenHelper(false),
57 eom('\n') {
58 memset(&stats, 0, sizeof(stats));
59 }
60 ~helper();
61
62 ///< whether at least one more request can be successfully submitted
63 bool queueFull() const;
64
65 ///< If not full, submit request. Otherwise, either kill Squid or return false.
66 bool trySubmit(const char *buf, HLPCB * callback, void *data);
67
68 /// Submits a request to the helper or add it to the queue if none of
69 /// the servers is available.
70 void submitRequest(Helper::Request *r);
71 public:
72 wordlist *cmdline;
73 dlink_list servers;
74 dlink_list queue;
75 const char *id_name;
76 Helper::ChildConfig childs; ///< Configuration settings for number running.
77 int ipc_type;
78 Ip::Address addr;
79 time_t full_time; ///< when a full helper became full (zero for non-full helpers)
80 time_t last_queue_warn;
81 time_t last_restart;
82 time_t timeout; ///< Requests timeout
83 bool retryTimedOut; ///< Whether the timed-out requests must retried
84 bool retryBrokenHelper; ///< Whether the requests must retried on BH replies
85 SBuf onTimedOutResponse; ///< The response to use when helper response timedout
86 char eom; ///< The char which marks the end of (response) message, normally '\n'
87
88 struct _stats {
89 int requests;
90 int replies;
91 int timedout;
92 int queue_size;
93 int avg_svc_time;
94 } stats;
95
96 protected:
97 friend void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data);
98 void prepSubmit();
99 void submit(const char *buf, HLPCB * callback, void *data);
100 };
101
102 class statefulhelper : public helper
103 {
104 CBDATA_CLASS(statefulhelper);
105
106 public:
107 inline statefulhelper(const char *name) : helper(name), datapool(NULL), IsAvailable(NULL), OnEmptyQueue(NULL) {}
108 inline ~statefulhelper() {}
109
110 public:
111 MemAllocator *datapool;
112 HLPSAVAIL *IsAvailable;
113 HLPSONEQ *OnEmptyQueue;
114
115 private:
116 friend void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, void *data, helper_stateful_server * lastserver);
117 void submit(const char *buf, HLPCB * callback, void *data, helper_stateful_server *lastserver);
118 };
119
120 /**
121 * Fields shared between stateless and stateful helper servers.
122 */
123 class HelperServerBase
124 {
125 public:
126 /** Closes pipes to the helper safely.
127 * Handles the case where the read and write pipes are the same FD.
128 *
129 * \param name displayed for the helper being shutdown if logging an error
130 */
131 void closePipesSafely(const char *name);
132
133 /** Closes the reading pipe.
134 * If the read and write sockets are the same the write pipe will
135 * also be closed. Otherwise its left open for later handling.
136 *
137 * \param name displayed for the helper being shutdown if logging an error
138 */
139 void closeWritePipeSafely(const char *name);
140
141 public:
142 /// Helper program identifier; does not change when contents do,
143 /// including during assignment
144 const InstanceId<HelperServerBase> index;
145 int pid;
146 Ip::Address addr;
147 Comm::ConnectionPointer readPipe;
148 Comm::ConnectionPointer writePipe;
149 void *hIpc;
150
151 char *rbuf;
152 size_t rbuf_sz;
153 size_t roffset;
154
155 struct timeval dispatch_time;
156 struct timeval answer_time;
157
158 dlink_node link;
159
160 struct _helper_flags {
161 bool writing;
162 bool closing;
163 bool shutdown;
164 bool reserved;
165 } flags;
166
167 struct {
168 uint64_t uses; //< requests sent to this helper
169 uint64_t replies; //< replies received from this helper
170 uint64_t pending; //< queued lookups waiting to be sent to this helper
171 uint64_t releases; //< times release() has been called on this helper (if stateful)
172 uint64_t timedout; //< requests which timed-out
173 } stats;
174 void initStats();
175 };
176
177 class MemBuf;
178 class CommTimeoutCbParams;
179
180 class helper_server : public HelperServerBase
181 {
182 CBDATA_CLASS(helper_server);
183
184 public:
185 uint64_t nextRequestId;
186
187 MemBuf *wqueue;
188 MemBuf *writebuf;
189
190 helper *parent;
191
192 typedef std::list<Helper::Request *> Requests;
193 Requests requests; ///< requests in order of submission/expiration
194
195 // STL says storing std::list iterators is safe when changing the list
196 typedef std::map<uint64_t, Requests::iterator> RequestIndex;
197 RequestIndex requestsIndex; ///< maps request IDs to requests
198
199 /// Run over the active requests lists and forces a retry, or timedout reply
200 /// or the configured "on timeout response" for timedout requests.
201 void checkForTimedOutRequests(bool const retry);
202
203 /// Read timeout handler
204 static void requestTimeout(const CommTimeoutCbParams &io);
205 };
206
207 class helper_stateful_server : public HelperServerBase
208 {
209 CBDATA_CLASS(helper_stateful_server);
210
211 public:
212 /* MemBuf wqueue; */
213 /* MemBuf writebuf; */
214
215 statefulhelper *parent;
216 Helper::Request *request;
217
218 void *data; /* State data used by the calling routines */
219 };
220
221 /* helper.c */
222 void helperOpenServers(helper * hlp);
223 void helperStatefulOpenServers(statefulhelper * hlp);
224 void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data);
225 void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, void *data, helper_stateful_server * lastserver);
226 void helperStats(StoreEntry * sentry, helper * hlp, const char *label = NULL);
227 void helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp, const char *label = NULL);
228 void helperShutdown(helper * hlp);
229 void helperStatefulShutdown(statefulhelper * hlp);
230 void helperStatefulReleaseServer(helper_stateful_server * srv);
231 void *helperStatefulServerGetData(helper_stateful_server * srv);
232
233 #endif /* SQUID_HELPER_H */
234