]>
Commit | Line | Data |
---|---|---|
51ee7c82 | 1 | /* |
ef57eb7b | 2 | * Copyright (C) 1996-2016 The Squid Software Foundation and contributors |
51ee7c82 | 3 | * |
bbc27441 AJ |
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. | |
51ee7c82 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 84 Helper process maintenance */ |
10 | ||
51ee7c82 | 11 | #ifndef SQUID_HELPER_H |
12 | #define SQUID_HELPER_H | |
13 | ||
37dedc58 | 14 | #include "base/AsyncCall.h" |
e237d339 | 15 | #include "base/InstanceId.h" |
aa839030 | 16 | #include "cbdata.h" |
e0d28505 | 17 | #include "comm/forward.h" |
582c2af2 | 18 | #include "dlink.h" |
76d9b994 | 19 | #include "helper/ChildConfig.h" |
24438ec5 | 20 | #include "helper/forward.h" |
ddc77a2e | 21 | #include "helper/Reply.h" |
c8f9dea2 | 22 | #include "helper/Request.h" |
602d9612 | 23 | #include "ip/Address.h" |
65e41a45 | 24 | #include "sbuf/SBuf.h" |
32fd6d8a CT |
25 | |
26 | #include <list> | |
27 | #include <map> | |
6215dc18 | 28 | #include <queue> |
aa839030 | 29 | |
bf3e8d5a | 30 | class Packable; |
541b581e | 31 | class wordlist; |
bf3e8d5a | 32 | |
ddc77a2e CT |
33 | namespace Helper |
34 | { | |
35 | /// Holds the required data to serve a helper request. | |
36 | class Xaction { | |
37 | MEMPROXY_CLASS(Helper::Xaction); | |
38 | public: | |
39 | Xaction(HLPCB *c, void *d, const char *b): request(c, d, b) {} | |
40 | Helper::Request request; | |
41 | Helper::Reply reply; | |
42 | }; | |
43 | } | |
44 | ||
6825b101 CT |
45 | /** |
46 | * Managers a set of individual helper processes with a common queue of requests. | |
47 | * | |
48 | * With respect to load, a helper goes through these states (roughly): | |
49 | * idle: no processes are working on requests (and no requests are queued); | |
50 | * normal: some, but not all processes are working (and no requests are queued); | |
51 | * busy: all processes are working (and some requests are possibly queued); | |
6082a0e2 | 52 | * overloaded: a busy helper with more than queue-size requests in the queue. |
6825b101 | 53 | * |
6082a0e2 EB |
54 | * A busy helper queues new requests and issues a WARNING every 10 minutes or so. |
55 | * An overloaded helper either drops new requests or keeps queuing them, depending on | |
6825b101 | 56 | * whether the caller can handle dropped requests (trySubmit vs helperSubmit APIs). |
6082a0e2 EB |
57 | * If an overloaded helper has been overloaded for 3+ minutes, an attempt to use |
58 | * it results in on-persistent-overload action, which may kill worker. | |
6825b101 | 59 | */ |
10044c9b A |
60 | class helper |
61 | { | |
5c2f68b7 AJ |
62 | CBDATA_CLASS(helper); |
63 | ||
48d54e4d | 64 | public: |
c8347c53 | 65 | inline helper(const char *name) : |
f53969cc SM |
66 | cmdline(NULL), |
67 | id_name(name), | |
68 | ipc_type(0), | |
6082a0e2 EB |
69 | droppedRequests(0), |
70 | overloadStart(0), | |
f53969cc SM |
71 | last_queue_warn(0), |
72 | last_restart(0), | |
73 | timeout(0), | |
74 | retryTimedOut(false), | |
75 | retryBrokenHelper(false), | |
76 | eom('\n') { | |
c8347c53 AJ |
77 | memset(&stats, 0, sizeof(stats)); |
78 | } | |
48d54e4d AJ |
79 | ~helper(); |
80 | ||
6215dc18 | 81 | /// \returns next request in the queue, or nil. |
ddc77a2e | 82 | Helper::Xaction *nextRequest(); |
6215dc18 | 83 | |
6082a0e2 | 84 | /// If possible, submit request. Otherwise, either kill Squid or return false. |
6825b101 CT |
85 | bool trySubmit(const char *buf, HLPCB * callback, void *data); |
86 | ||
f53969cc | 87 | /// Submits a request to the helper or add it to the queue if none of |
32fd6d8a | 88 | /// the servers is available. |
ddc77a2e | 89 | void submitRequest(Helper::Xaction *r); |
bf3e8d5a AJ |
90 | |
91 | /// Dump some stats about the helper state to a Packable object | |
92 | void packStatsInto(Packable *p, const char *label = NULL) const; | |
6082a0e2 EB |
93 | /// whether the helper will be in "overloaded" state after one more request |
94 | /// already overloaded helpers return true | |
95 | bool willOverload() const; | |
bf3e8d5a | 96 | |
48d54e4d | 97 | public: |
aa839030 | 98 | wordlist *cmdline; |
99 | dlink_list servers; | |
ddc77a2e | 100 | std::queue<Helper::Xaction *> queue; |
aa839030 | 101 | const char *id_name; |
76d9b994 | 102 | Helper::ChildConfig childs; ///< Configuration settings for number running. |
aa839030 | 103 | int ipc_type; |
b7ac5457 | 104 | Ip::Address addr; |
6082a0e2 EB |
105 | unsigned int droppedRequests; ///< requests not sent during helper overload |
106 | time_t overloadStart; ///< when the helper became overloaded (zero if it is not) | |
aa839030 | 107 | time_t last_queue_warn; |
108 | time_t last_restart; | |
32fd6d8a CT |
109 | time_t timeout; ///< Requests timeout |
110 | bool retryTimedOut; ///< Whether the timed-out requests must retried | |
111 | bool retryBrokenHelper; ///< Whether the requests must retried on BH replies | |
112 | SBuf onTimedOutResponse; ///< The response to use when helper response timedout | |
0af9303a | 113 | char eom; ///< The char which marks the end of (response) message, normally '\n' |
aa839030 | 114 | |
48d54e4d | 115 | struct _stats { |
aa839030 | 116 | int requests; |
117 | int replies; | |
32fd6d8a | 118 | int timedout; |
aa839030 | 119 | int queue_size; |
120 | int avg_svc_time; | |
2fadd50d | 121 | } stats; |
6825b101 CT |
122 | |
123 | protected: | |
124 | friend void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data); | |
6082a0e2 EB |
125 | bool queueFull() const; |
126 | bool overloaded() const; | |
127 | void syncQueueStats(); | |
128 | bool prepSubmit(); | |
6825b101 | 129 | void submit(const char *buf, HLPCB * callback, void *data); |
aa839030 | 130 | }; |
131 | ||
10044c9b A |
132 | class statefulhelper : public helper |
133 | { | |
5c2f68b7 AJ |
134 | CBDATA_CLASS(statefulhelper); |
135 | ||
48d54e4d | 136 | public: |
44ada37f | 137 | inline statefulhelper(const char *name) : helper(name), datapool(NULL) {} |
5c2f68b7 | 138 | inline ~statefulhelper() {} |
48d54e4d AJ |
139 | |
140 | public: | |
a3efa961 | 141 | MemAllocator *datapool; |
6825b101 CT |
142 | |
143 | private: | |
144 | friend void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, void *data, helper_stateful_server * lastserver); | |
145 | void submit(const char *buf, HLPCB * callback, void *data, helper_stateful_server *lastserver); | |
6082a0e2 | 146 | bool trySubmit(const char *buf, HLPCB * callback, void *data, helper_stateful_server *lastserver); |
aa839030 | 147 | }; |
148 | ||
1f7ba0b4 | 149 | /** |
48d54e4d AJ |
150 | * Fields shared between stateless and stateful helper servers. |
151 | */ | |
10044c9b A |
152 | class HelperServerBase |
153 | { | |
e0d28505 AJ |
154 | public: |
155 | /** Closes pipes to the helper safely. | |
156 | * Handles the case where the read and write pipes are the same FD. | |
41060bef AJ |
157 | * |
158 | * \param name displayed for the helper being shutdown if logging an error | |
e0d28505 | 159 | */ |
41060bef | 160 | void closePipesSafely(const char *name); |
e0d28505 AJ |
161 | |
162 | /** Closes the reading pipe. | |
163 | * If the read and write sockets are the same the write pipe will | |
164 | * also be closed. Otherwise its left open for later handling. | |
41060bef AJ |
165 | * |
166 | * \param name displayed for the helper being shutdown if logging an error | |
e0d28505 | 167 | */ |
41060bef | 168 | void closeWritePipeSafely(const char *name); |
e0d28505 | 169 | |
48d54e4d | 170 | public: |
e237d339 AJ |
171 | /// Helper program identifier; does not change when contents do, |
172 | /// including during assignment | |
173 | const InstanceId<HelperServerBase> index; | |
aa839030 | 174 | int pid; |
b7ac5457 | 175 | Ip::Address addr; |
e0d28505 AJ |
176 | Comm::ConnectionPointer readPipe; |
177 | Comm::ConnectionPointer writePipe; | |
48d54e4d AJ |
178 | void *hIpc; |
179 | ||
aa839030 | 180 | char *rbuf; |
181 | size_t rbuf_sz; | |
57d55dfa | 182 | size_t roffset; |
aa839030 | 183 | |
184 | struct timeval dispatch_time; | |
aa839030 | 185 | struct timeval answer_time; |
186 | ||
187 | dlink_node link; | |
e0d28505 AJ |
188 | |
189 | struct _helper_flags { | |
be4d35dc FC |
190 | bool writing; |
191 | bool closing; | |
192 | bool shutdown; | |
193 | bool reserved; | |
e0d28505 AJ |
194 | } flags; |
195 | ||
ddc77a2e | 196 | typedef std::list<Helper::Xaction *> Requests; |
bf3e8d5a AJ |
197 | Requests requests; ///< requests in order of submission/expiration |
198 | ||
1f7ba0b4 AJ |
199 | struct { |
200 | uint64_t uses; //< requests sent to this helper | |
201 | uint64_t replies; //< replies received from this helper | |
202 | uint64_t pending; //< queued lookups waiting to be sent to this helper | |
203 | uint64_t releases; //< times release() has been called on this helper (if stateful) | |
32fd6d8a | 204 | uint64_t timedout; //< requests which timed-out |
1f7ba0b4 AJ |
205 | } stats; |
206 | void initStats(); | |
48d54e4d AJ |
207 | }; |
208 | ||
582c2af2 | 209 | class MemBuf; |
32fd6d8a | 210 | class CommTimeoutCbParams; |
582c2af2 | 211 | |
10044c9b A |
212 | class helper_server : public HelperServerBase |
213 | { | |
5c2f68b7 AJ |
214 | CBDATA_CLASS(helper_server); |
215 | ||
48d54e4d | 216 | public: |
32fd6d8a CT |
217 | uint64_t nextRequestId; |
218 | ||
48d54e4d AJ |
219 | MemBuf *wqueue; |
220 | MemBuf *writebuf; | |
221 | ||
aa839030 | 222 | helper *parent; |
32fd6d8a | 223 | |
ddc77a2e CT |
224 | /// The helper request Xaction object for the current reply . |
225 | /// A helper reply may be distributed to more than one of the retrieved | |
226 | /// packets from helper. This member stores the Xaction object as long as | |
227 | /// the end-of-message for current reply is not retrieved. | |
228 | Helper::Xaction *replyXaction; | |
229 | ||
1176e456 CT |
230 | /// Whether to ignore current message, because it is timed-out or other reason |
231 | bool ignoreToEom; | |
232 | ||
32fd6d8a CT |
233 | // STL says storing std::list iterators is safe when changing the list |
234 | typedef std::map<uint64_t, Requests::iterator> RequestIndex; | |
235 | RequestIndex requestsIndex; ///< maps request IDs to requests | |
236 | ||
ddc77a2e CT |
237 | /// Search in queue for the request with requestId, return the related |
238 | /// Xaction object and remove it from queue. | |
239 | /// If concurrency is disabled then the requestId is ignored and the | |
240 | /// Xaction of the next request in queue is retrieved. | |
241 | Helper::Xaction *popRequest(int requestId); | |
242 | ||
32fd6d8a CT |
243 | /// Run over the active requests lists and forces a retry, or timedout reply |
244 | /// or the configured "on timeout response" for timedout requests. | |
245 | void checkForTimedOutRequests(bool const retry); | |
246 | ||
f53969cc | 247 | /// Read timeout handler |
32fd6d8a | 248 | static void requestTimeout(const CommTimeoutCbParams &io); |
aa839030 | 249 | }; |
250 | ||
10044c9b A |
251 | class helper_stateful_server : public HelperServerBase |
252 | { | |
5c2f68b7 AJ |
253 | CBDATA_CLASS(helper_stateful_server); |
254 | ||
48d54e4d | 255 | public: |
aa839030 | 256 | /* MemBuf wqueue; */ |
257 | /* MemBuf writebuf; */ | |
aa839030 | 258 | |
aa839030 | 259 | statefulhelper *parent; |
aa839030 | 260 | |
f53969cc | 261 | void *data; /* State data used by the calling routines */ |
aa839030 | 262 | }; |
51ee7c82 | 263 | |
aa839030 | 264 | /* helper.c */ |
d9c252f2 FC |
265 | void helperOpenServers(helper * hlp); |
266 | void helperStatefulOpenServers(statefulhelper * hlp); | |
267 | void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data); | |
e166785a | 268 | void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, void *data, helper_stateful_server * lastserver); |
d9c252f2 FC |
269 | void helperShutdown(helper * hlp); |
270 | void helperStatefulShutdown(statefulhelper * hlp); | |
271 | void helperStatefulReleaseServer(helper_stateful_server * srv); | |
272 | void *helperStatefulServerGetData(helper_stateful_server * srv); | |
aa839030 | 273 | |
51ee7c82 | 274 | #endif /* SQUID_HELPER_H */ |
f53969cc | 275 |