2 * Copyright (C) 1996-2015 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"
28 * Managers a set of individual helper processes with a common queue of requests.
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.
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.
47 inline helper(const char *name
) :
56 retryBrokenHelper(false),
58 memset(&stats
, 0, sizeof(stats
));
62 ///< whether at least one more request can be successfully submitted
63 bool queueFull() const;
65 ///< If not full, submit request. Otherwise, either kill Squid or return false.
66 bool trySubmit(const char *buf
, HLPCB
* callback
, void *data
);
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
);
76 Helper::ChildConfig childs
; ///< Configuration settings for number running.
79 time_t full_time
; ///< when a full helper became full (zero for non-full helpers)
80 time_t last_queue_warn
;
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'
97 friend void helperSubmit(helper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
);
99 void submit(const char *buf
, HLPCB
* callback
, void *data
);
102 class statefulhelper
: public helper
104 CBDATA_CLASS(statefulhelper
);
107 inline statefulhelper(const char *name
) : helper(name
), datapool(NULL
), IsAvailable(NULL
), OnEmptyQueue(NULL
) {}
108 inline ~statefulhelper() {}
111 MemAllocator
*datapool
;
112 HLPSAVAIL
*IsAvailable
;
113 HLPSONEQ
*OnEmptyQueue
;
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
);
121 * Fields shared between stateless and stateful helper servers.
123 class HelperServerBase
126 /** Closes pipes to the helper safely.
127 * Handles the case where the read and write pipes are the same FD.
129 * \param name displayed for the helper being shutdown if logging an error
131 void closePipesSafely(const char *name
);
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.
137 * \param name displayed for the helper being shutdown if logging an error
139 void closeWritePipeSafely(const char *name
);
142 /// Helper program identifier; does not change when contents do,
143 /// including during assignment
144 const InstanceId
<HelperServerBase
> index
;
147 Comm::ConnectionPointer readPipe
;
148 Comm::ConnectionPointer writePipe
;
155 struct timeval dispatch_time
;
156 struct timeval answer_time
;
160 struct _helper_flags
{
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
178 class CommTimeoutCbParams
;
180 class helper_server
: public HelperServerBase
182 CBDATA_CLASS(helper_server
);
185 uint64_t nextRequestId
;
192 typedef std::list
<Helper::Request
*> Requests
;
193 Requests requests
; ///< requests in order of submission/expiration
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
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
);
203 /// Read timeout handler
204 static void requestTimeout(const CommTimeoutCbParams
&io
);
207 class helper_stateful_server
: public HelperServerBase
209 CBDATA_CLASS(helper_stateful_server
);
213 /* MemBuf writebuf; */
215 statefulhelper
*parent
;
216 Helper::Request
*request
;
218 void *data
; /* State data used by the calling routines */
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
);
233 #endif /* SQUID_HELPER_H */