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