2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 84 Helper process maintenance */
11 #ifndef SQUID_HELPER_H
12 #define SQUID_HELPER_H
14 #include "base/AsyncCall.h"
15 #include "base/InstanceId.h"
17 #include "comm/forward.h"
19 #include "helper/ChildConfig.h"
20 #include "helper/forward.h"
21 #include "ip/Address.h"
22 #include "sbuf/SBuf.h"
31 * Managers a set of individual helper processes with a common queue of requests.
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.
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.
50 inline helper(const char *name
) :
59 retryBrokenHelper(false),
61 memset(&stats
, 0, sizeof(stats
));
65 ///< whether at least one more request can be successfully submitted
66 bool queueFull() const;
68 ///< If not full, submit request. Otherwise, either kill Squid or return false.
69 bool trySubmit(const char *buf
, HLPCB
* callback
, void *data
);
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
);
75 /// Dump some stats about the helper state to a Packable object
76 void packStatsInto(Packable
*p
, const char *label
= NULL
) const;
83 Helper::ChildConfig childs
; ///< Configuration settings for number running.
86 time_t full_time
; ///< when a full helper became full (zero for non-full helpers)
87 time_t last_queue_warn
;
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'
104 friend void helperSubmit(helper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
);
106 void submit(const char *buf
, HLPCB
* callback
, void *data
);
109 class statefulhelper
: public helper
111 CBDATA_CLASS(statefulhelper
);
114 inline statefulhelper(const char *name
) : helper(name
), datapool(NULL
) {}
115 inline ~statefulhelper() {}
118 MemAllocator
*datapool
;
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
);
126 * Fields shared between stateless and stateful helper servers.
128 class HelperServerBase
131 /** Closes pipes to the helper safely.
132 * Handles the case where the read and write pipes are the same FD.
134 * \param name displayed for the helper being shutdown if logging an error
136 void closePipesSafely(const char *name
);
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.
142 * \param name displayed for the helper being shutdown if logging an error
144 void closeWritePipeSafely(const char *name
);
147 /// Helper program identifier; does not change when contents do,
148 /// including during assignment
149 const InstanceId
<HelperServerBase
> index
;
152 Comm::ConnectionPointer readPipe
;
153 Comm::ConnectionPointer writePipe
;
160 struct timeval dispatch_time
;
161 struct timeval answer_time
;
165 struct _helper_flags
{
172 typedef std::list
<Helper::Request
*> Requests
;
173 Requests requests
; ///< requests in order of submission/expiration
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
186 class CommTimeoutCbParams
;
188 class helper_server
: public HelperServerBase
190 CBDATA_CLASS(helper_server
);
193 uint64_t nextRequestId
;
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
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
);
208 /// Read timeout handler
209 static void requestTimeout(const CommTimeoutCbParams
&io
);
212 class helper_stateful_server
: public HelperServerBase
214 CBDATA_CLASS(helper_stateful_server
);
218 /* MemBuf writebuf; */
220 statefulhelper
*parent
;
222 void *data
; /* State data used by the calling routines */
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
);
235 #endif /* SQUID_HELPER_H */