2 * Copyright (C) 1996-2018 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 "helper/Reply.h"
22 #include "helper/Request.h"
23 #include "ip/Address.h"
24 #include "sbuf/SBuf.h"
35 /// Holds the required data to serve a helper request.
37 MEMPROXY_CLASS(Helper::Xaction
);
39 Xaction(HLPCB
*c
, void *d
, const char *b
): request(c
, d
, b
) {}
40 Helper::Request request
;
46 * Managers a set of individual helper processes with a common queue of requests.
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);
52 * overloaded: a busy helper with more than queue-size requests in the queue.
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
56 * whether the caller can handle dropped requests (trySubmit vs helperSubmit APIs).
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.
65 inline helper(const char *name
) :
75 retryBrokenHelper(false),
77 memset(&stats
, 0, sizeof(stats
));
81 /// \returns next request in the queue, or nil.
82 Helper::Xaction
*nextRequest();
84 /// If possible, submit request. Otherwise, either kill Squid or return false.
85 bool trySubmit(const char *buf
, HLPCB
* callback
, void *data
);
87 /// Submits a request to the helper or add it to the queue if none of
88 /// the servers is available.
89 void submitRequest(Helper::Xaction
*r
);
91 /// Dump some stats about the helper state to a Packable object
92 void packStatsInto(Packable
*p
, const char *label
= NULL
) const;
93 /// whether the helper will be in "overloaded" state after one more request
94 /// already overloaded helpers return true
95 bool willOverload() const;
100 std::queue
<Helper::Xaction
*> queue
;
102 Helper::ChildConfig childs
; ///< Configuration settings for number running.
105 unsigned int droppedRequests
; ///< requests not sent during helper overload
106 time_t overloadStart
; ///< when the helper became overloaded (zero if it is not)
107 time_t last_queue_warn
;
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
113 char eom
; ///< The char which marks the end of (response) message, normally '\n'
124 friend void helperSubmit(helper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
);
125 bool queueFull() const;
126 bool overloaded() const;
127 void syncQueueStats();
129 void submit(const char *buf
, HLPCB
* callback
, void *data
);
132 class statefulhelper
: public helper
134 CBDATA_CLASS(statefulhelper
);
137 inline statefulhelper(const char *name
) : helper(name
) {}
138 inline ~statefulhelper() {}
141 friend void helperStatefulSubmit(statefulhelper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
, helper_stateful_server
* lastserver
);
142 void submit(const char *buf
, HLPCB
* callback
, void *data
, helper_stateful_server
*lastserver
);
143 bool trySubmit(const char *buf
, HLPCB
* callback
, void *data
, helper_stateful_server
*lastserver
);
147 * Fields shared between stateless and stateful helper servers.
149 class HelperServerBase
152 /** Closes pipes to the helper safely.
153 * Handles the case where the read and write pipes are the same FD.
155 * \param name displayed for the helper being shutdown if logging an error
157 void closePipesSafely(const char *name
);
159 /** Closes the reading pipe.
160 * If the read and write sockets are the same the write pipe will
161 * also be closed. Otherwise its left open for later handling.
163 * \param name displayed for the helper being shutdown if logging an error
165 void closeWritePipeSafely(const char *name
);
168 /// Helper program identifier; does not change when contents do,
169 /// including during assignment
170 const InstanceId
<HelperServerBase
> index
;
173 Comm::ConnectionPointer readPipe
;
174 Comm::ConnectionPointer writePipe
;
181 struct timeval dispatch_time
;
182 struct timeval answer_time
;
186 struct _helper_flags
{
193 typedef std::list
<Helper::Xaction
*> Requests
;
194 Requests requests
; ///< requests in order of submission/expiration
197 uint64_t uses
; //< requests sent to this helper
198 uint64_t replies
; //< replies received from this helper
199 uint64_t pending
; //< queued lookups waiting to be sent to this helper
200 uint64_t releases
; //< times release() has been called on this helper (if stateful)
201 uint64_t timedout
; //< requests which timed-out
207 class CommTimeoutCbParams
;
209 class helper_server
: public HelperServerBase
211 CBDATA_CLASS(helper_server
);
214 uint64_t nextRequestId
;
221 /// The helper request Xaction object for the current reply .
222 /// A helper reply may be distributed to more than one of the retrieved
223 /// packets from helper. This member stores the Xaction object as long as
224 /// the end-of-message for current reply is not retrieved.
225 Helper::Xaction
*replyXaction
;
227 /// Whether to ignore current message, because it is timed-out or other reason
230 // STL says storing std::list iterators is safe when changing the list
231 typedef std::map
<uint64_t, Requests::iterator
> RequestIndex
;
232 RequestIndex requestsIndex
; ///< maps request IDs to requests
234 /// Search in queue for the request with requestId, return the related
235 /// Xaction object and remove it from queue.
236 /// If concurrency is disabled then the requestId is ignored and the
237 /// Xaction of the next request in queue is retrieved.
238 Helper::Xaction
*popRequest(int requestId
);
240 /// Run over the active requests lists and forces a retry, or timedout reply
241 /// or the configured "on timeout response" for timedout requests.
242 void checkForTimedOutRequests(bool const retry
);
244 /// Read timeout handler
245 static void requestTimeout(const CommTimeoutCbParams
&io
);
248 class helper_stateful_server
: public HelperServerBase
250 CBDATA_CLASS(helper_stateful_server
);
253 statefulhelper
*parent
;
257 void helperOpenServers(helper
* hlp
);
258 void helperStatefulOpenServers(statefulhelper
* hlp
);
259 void helperSubmit(helper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
);
260 void helperStatefulSubmit(statefulhelper
* hlp
, const char *buf
, HLPCB
* callback
, void *data
, helper_stateful_server
* lastserver
);
261 void helperShutdown(helper
* hlp
);
262 void helperStatefulShutdown(statefulhelper
* hlp
);
263 void helperStatefulReleaseServer(helper_stateful_server
* srv
);
265 #endif /* SQUID_HELPER_H */