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"
30 * Managers a set of individual helper processes with a common queue of requests.
32 * With respect to load, a helper goes through these states (roughly):
33 * idle: no processes are working on requests (and no requests are queued);
34 * normal: some, but not all processes are working (and no requests are queued);
35 * busy: all processes are working (and some requests are possibly queued);
36 * full: all processes are working and at least 2*#processes requests are queued.
38 * A "busy" helper queues new requests and issues a WARNING every 10 minutes or so.
39 * A "full" helper either drops new requests or keeps queuing them, depending on
40 * whether the caller can handle dropped requests (trySubmit vs helperSubmit APIs).
41 * An attempt to use a "full" helper that has been "full" for 3+ minutes kills worker.
42 * Given enough load, all helpers except for external ACL will make such attempts.
49 inline helper(const char *name
) :
58 retryBrokenHelper(false),
60 memset(&stats
, 0, sizeof(stats
));
64 ///< whether at least one more request can be successfully submitted
65 bool queueFull() const;
67 ///< If not full, submit request. Otherwise, either kill Squid or return false.
68 bool trySubmit(const char *buf
, HLPCB
* callback
, void *data
);
70 /// Submits a request to the helper or add it to the queue if none of
71 /// the servers is available.
72 void submitRequest(Helper::Request
*r
);
74 /// Dump some stats about the helper state to a Packable object
75 void packStatsInto(Packable
*p
, const char *label
= NULL
) const;
82 Helper::ChildConfig childs
; ///< Configuration settings for number running.
85 time_t full_time
; ///< when a full helper became full (zero for non-full helpers)
86 time_t last_queue_warn
;
88 time_t timeout
; ///< Requests timeout
89 bool retryTimedOut
; ///< Whether the timed-out requests must retried
90 bool retryBrokenHelper
; ///< Whether the requests must retried on BH replies
91 SBuf onTimedOutResponse
; ///< The response to use when helper response timedout
92 char eom
; ///< The char which marks the end of (response) message, normally '\n'
103 friend void helperSubmit(helper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
);
105 void submit(const char *buf
, HLPCB
* callback
, void *data
);
108 class statefulhelper
: public helper
110 CBDATA_CLASS(statefulhelper
);
113 inline statefulhelper(const char *name
) : helper(name
), datapool(NULL
), IsAvailable(NULL
), OnEmptyQueue(NULL
) {}
114 inline ~statefulhelper() {}
117 MemAllocator
*datapool
;
118 HLPSAVAIL
*IsAvailable
;
119 HLPSONEQ
*OnEmptyQueue
;
122 friend void helperStatefulSubmit(statefulhelper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
, helper_stateful_server
* lastserver
);
123 void submit(const char *buf
, HLPCB
* callback
, void *data
, helper_stateful_server
*lastserver
);
127 * Fields shared between stateless and stateful helper servers.
129 class HelperServerBase
132 /** Closes pipes to the helper safely.
133 * Handles the case where the read and write pipes are the same FD.
135 * \param name displayed for the helper being shutdown if logging an error
137 void closePipesSafely(const char *name
);
139 /** Closes the reading pipe.
140 * If the read and write sockets are the same the write pipe will
141 * also be closed. Otherwise its left open for later handling.
143 * \param name displayed for the helper being shutdown if logging an error
145 void closeWritePipeSafely(const char *name
);
148 /// Helper program identifier; does not change when contents do,
149 /// including during assignment
150 const InstanceId
<HelperServerBase
> index
;
153 Comm::ConnectionPointer readPipe
;
154 Comm::ConnectionPointer writePipe
;
161 struct timeval dispatch_time
;
162 struct timeval answer_time
;
166 struct _helper_flags
{
173 typedef std::list
<Helper::Request
*> Requests
;
174 Requests requests
; ///< requests in order of submission/expiration
177 uint64_t uses
; //< requests sent to this helper
178 uint64_t replies
; //< replies received from this helper
179 uint64_t pending
; //< queued lookups waiting to be sent to this helper
180 uint64_t releases
; //< times release() has been called on this helper (if stateful)
181 uint64_t timedout
; //< requests which timed-out
187 class CommTimeoutCbParams
;
189 class helper_server
: public HelperServerBase
191 CBDATA_CLASS(helper_server
);
194 uint64_t nextRequestId
;
201 // STL says storing std::list iterators is safe when changing the list
202 typedef std::map
<uint64_t, Requests::iterator
> RequestIndex
;
203 RequestIndex requestsIndex
; ///< maps request IDs to requests
205 /// Run over the active requests lists and forces a retry, or timedout reply
206 /// or the configured "on timeout response" for timedout requests.
207 void checkForTimedOutRequests(bool const retry
);
209 /// Read timeout handler
210 static void requestTimeout(const CommTimeoutCbParams
&io
);
213 class helper_stateful_server
: public HelperServerBase
215 CBDATA_CLASS(helper_stateful_server
);
219 /* MemBuf writebuf; */
221 statefulhelper
*parent
;
223 void *data
; /* State data used by the calling routines */
227 void helperOpenServers(helper
* hlp
);
228 void helperStatefulOpenServers(statefulhelper
* hlp
);
229 void helperSubmit(helper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
);
230 void helperStatefulSubmit(statefulhelper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
, helper_stateful_server
* lastserver
);
231 void helperShutdown(helper
* hlp
);
232 void helperStatefulShutdown(statefulhelper
* hlp
);
233 void helperStatefulReleaseServer(helper_stateful_server
* srv
);
234 void *helperStatefulServerGetData(helper_stateful_server
* srv
);
236 #endif /* SQUID_HELPER_H */