#include "squid.h"
#include "base/AsyncCbdataCalls.h"
+#include "base/Packable.h"
#include "comm.h"
#include "comm/Connection.h"
#include "comm/Read.h"
static void helperStatefulKickQueue(statefulhelper * hlp);
static void helperStatefulServerDone(helper_stateful_server * srv);
static void StatefulEnqueue(statefulhelper * hlp, Helper::Request * r);
-static bool helperStartStats(StoreEntry *sentry, void *hlp, const char *label);
CBDATA_CLASS_INIT(helper);
CBDATA_CLASS_INIT(helper_server);
if ((buf != NULL) && lastserver) {
debugs(84, 5, "StatefulSubmit with lastserver " << lastserver);
assert(lastserver->flags.reserved);
- assert(!(lastserver->request));
+ assert(!lastserver->requests.size());
debugs(84, 5, "StatefulSubmit dispatching");
helperStatefulDispatch(lastserver, r);
return srv->data;
}
-/**
- * Dump some stats about the helper states to a StoreEntry
- */
void
-helperStats(StoreEntry * sentry, helper * hlp, const char *label)
+helper::packStatsInto(Packable *p, const char *label) const
{
- if (!helperStartStats(sentry, hlp, label))
- return;
-
- storeAppendPrintf(sentry, "program: %s\n",
- hlp->cmdline->key);
- storeAppendPrintf(sentry, "number active: %d of %d (%d shutting down)\n",
- hlp->childs.n_active, hlp->childs.n_max, (hlp->childs.n_running - hlp->childs.n_active) );
- storeAppendPrintf(sentry, "requests sent: %d\n",
- hlp->stats.requests);
- storeAppendPrintf(sentry, "replies received: %d\n",
- hlp->stats.replies);
- storeAppendPrintf(sentry, "requests timedout: %d\n",
- hlp->stats.timedout);
- storeAppendPrintf(sentry, "queue length: %d\n",
- hlp->stats.queue_size);
- storeAppendPrintf(sentry, "avg service time: %d msec\n",
- hlp->stats.avg_svc_time);
- storeAppendPrintf(sentry, "\n");
- storeAppendPrintf(sentry, "%7s\t%7s\t%7s\t%11s\t%11s\t%11s\t%s\t%7s\t%7s\t%7s\n",
+ if (label)
+ p->appendf("%s:\n", label);
+
+ p->appendf(" program: %s\n", cmdline->key);
+ p->appendf(" number active: %d of %d (%d shutting down)\n", childs.n_active, childs.n_max, (childs.n_running - childs.n_active));
+ p->appendf(" requests sent: %d\n", stats.requests);
+ p->appendf(" replies received: %d\n", stats.replies);
+ p->appendf(" requests timedout: %d\n", stats.timedout);
+ p->appendf(" queue length: %d\n", stats.queue_size);
+ p->appendf(" avg service time: %d msec\n", stats.avg_svc_time);
+ p->append("\n",1);
+ p->appendf("%7s\t%7s\t%7s\t%11s\t%11s\t%11s\t%6s\t%7s\t%7s\t%7s\n",
"ID #",
"FD",
"PID",
"Offset",
"Request");
- for (dlink_node *link = hlp->servers.head; link; link = link->next) {
- helper_server *srv = (helper_server*)link->data;
+ for (dlink_node *link = servers.head; link; link = link->next) {
+ HelperServerBase *srv = static_cast<HelperServerBase *>(link->data);
+ assert(srv);
Helper::Request *request = srv->requests.empty() ? NULL : srv->requests.front();
double tt = 0.001 * (request ? tvSubMsec(request->dispatch_time, current_time) : tvSubMsec(srv->dispatch_time, srv->answer_time));
- storeAppendPrintf(sentry, "%7u\t%7d\t%7d\t%11" PRIu64 "\t%11" PRIu64 "\t%11" PRIu64 "\t%c%c%c%c\t%7.3f\t%7d\t%s\n",
+ p->appendf("%7u\t%7d\t%7d\t%11" PRIu64 "\t%11" PRIu64 "\t%11" PRIu64 "\t%c%c%c%c%c%c\t%7.3f\t%7d\t%s\n",
srv->index.value,
srv->readPipe->fd,
srv->pid,
srv->stats.pending ? 'B' : ' ',
srv->flags.writing ? 'W' : ' ',
srv->flags.closing ? 'C' : ' ',
- srv->flags.shutdown ? 'S' : ' ',
- tt < 0.0 ? 0.0 : tt,
- (int) srv->roffset,
- request ? Format::QuoteMimeBlob(request->buf) : "(none)");
- }
-
- storeAppendPrintf(sentry, "\nFlags key:\n\n");
- storeAppendPrintf(sentry, " B = BUSY\n");
- storeAppendPrintf(sentry, " W = WRITING\n");
- storeAppendPrintf(sentry, " C = CLOSING\n");
- storeAppendPrintf(sentry, " S = SHUTDOWN PENDING\n");
-}
-
-void
-helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp, const char *label)
-{
- if (!helperStartStats(sentry, hlp, label))
- return;
-
- storeAppendPrintf(sentry, "program: %s\n",
- hlp->cmdline->key);
- storeAppendPrintf(sentry, "number active: %d of %d (%d shutting down)\n",
- hlp->childs.n_active, hlp->childs.n_max, (hlp->childs.n_running - hlp->childs.n_active) );
- storeAppendPrintf(sentry, "requests sent: %d\n",
- hlp->stats.requests);
- storeAppendPrintf(sentry, "replies received: %d\n",
- hlp->stats.replies);
- storeAppendPrintf(sentry, "queue length: %d\n",
- hlp->stats.queue_size);
- storeAppendPrintf(sentry, "avg service time: %d msec\n",
- hlp->stats.avg_svc_time);
- storeAppendPrintf(sentry, "\n");
- storeAppendPrintf(sentry, "%7s\t%7s\t%7s\t%11s\t%11s\t%6s\t%7s\t%7s\t%7s\n",
- "ID #",
- "FD",
- "PID",
- "# Requests",
- "# Replies",
- "Flags",
- "Time",
- "Offset",
- "Request");
-
- for (dlink_node *link = hlp->servers.head; link; link = link->next) {
- helper_stateful_server *srv = (helper_stateful_server *)link->data;
- double tt = 0.001 * tvSubMsec(srv->dispatch_time, srv->stats.pending ? current_time : srv->answer_time);
- storeAppendPrintf(sentry, "%7u\t%7d\t%7d\t%11" PRIu64 "\t%11" PRIu64 "\t%c%c%c%c%c\t%7.3f\t%7d\t%s\n",
- srv->index.value,
- srv->readPipe->fd,
- srv->pid,
- srv->stats.uses,
- srv->stats.replies,
- srv->stats.pending ? 'B' : ' ',
- srv->flags.closing ? 'C' : ' ',
srv->flags.reserved ? 'R' : ' ',
srv->flags.shutdown ? 'S' : ' ',
- srv->request ? (srv->request->placeholder ? 'P' : ' ') : ' ',
+ request && request->placeholder ? 'P' : ' ',
tt < 0.0 ? 0.0 : tt,
(int) srv->roffset,
- srv->request ? Format::QuoteMimeBlob(srv->request->buf) : "(none)");
+ request ? Format::QuoteMimeBlob(request->buf) : "(none)");
}
- storeAppendPrintf(sentry, "\nFlags key:\n\n");
- storeAppendPrintf(sentry, " B = BUSY\n");
- storeAppendPrintf(sentry, " C = CLOSING\n");
- storeAppendPrintf(sentry, " R = RESERVED\n");
- storeAppendPrintf(sentry, " S = SHUTDOWN PENDING\n");
- storeAppendPrintf(sentry, " P = PLACEHOLDER\n");
+ p->append("\nFlags key:\n"
+ " B\tBUSY\n"
+ " W\tWRITING\n"
+ " C\tCLOSING\n"
+ " R\tRESERVED\n"
+ " S\tSHUTDOWN PENDING\n"
+ " P\tPLACEHOLDER\n", 101);
}
void
helperServerFree(helper_server *srv)
{
helper *hlp = srv->parent;
- Helper::Request *r;
int concurrency = hlp->childs.concurrency;
if (!concurrency)
while (!srv->requests.empty()) {
// XXX: re-schedule these on another helper?
- r = srv->requests.front();
+ Helper::Request *r = srv->requests.front();
srv->requests.pop_front();
void *cbdata;
helperStatefulServerFree(helper_stateful_server *srv)
{
statefulhelper *hlp = srv->parent;
- Helper::Request *r;
if (srv->rbuf) {
memFreeBuf(srv->rbuf_sz, srv->rbuf);
}
}
- if ((r = srv->request)) {
+ while (!srv->requests.empty()) {
+ // XXX: re-schedule these on another helper?
+ Helper::Request *r = srv->requests.front();
+ srv->requests.pop_front();
void *cbdata;
if (cbdataReferenceValidDone(r->data, &cbdata)) {
Helper::Reply nilReply;
- nilReply.whichServer = srv;
r->callback(cbdata, nilReply);
}
delete r;
-
- srv->request = NULL;
}
if (srv->data != NULL)
{
char *t = NULL;
helper_stateful_server *srv = (helper_stateful_server *)data;
- Helper::Request *r;
statefulhelper *hlp = srv->parent;
assert(cbdataReferenceValid(data));
srv->roffset += len;
srv->rbuf[srv->roffset] = '\0';
- r = srv->request;
+ Helper::Request *r = srv->requests.front();
debugs(84, DBG_DATA, Raw("accumulated", srv->rbuf, srv->roffset));
if (r == NULL) {
if ((t = strchr(srv->rbuf, hlp->eom))) {
/* end of reply found */
+ srv->requests.pop_front(); // we already have it in 'r'
int called = 1;
int skip = 1;
debugs(84, 3, "helperStatefulHandleRead: end of reply found");
*/
srv->roffset = 0;
delete r;
- srv->request = NULL;
-- srv->stats.pending;
++ srv->stats.replies;
/* and push the queue. Note that the callback may have submitted a new
* request to the helper which is why we test for the request */
- if (srv->request == NULL)
+ if (!srv->requests.size())
helperStatefulServerDone(srv);
return;
}
srv->flags.reserved = true;
- srv->request = r;
+ srv->requests.push_back(r);
srv->dispatch_time = current_time;
AsyncCall::Pointer call = commCbCall(5,5, "helperStatefulDispatchWriteDone",
CommIoCbPtrFun(helperStatefulDispatchWriteDone, hlp));
}
}
-// TODO: should helper_ and helper_stateful_ have a common parent?
-static bool
-helperStartStats(StoreEntry *sentry, void *hlp, const char *label)
-{
- if (!hlp) {
- if (label)
- storeAppendPrintf(sentry, "%s: unavailable\n", label);
- return false;
- }
-
- if (label)
- storeAppendPrintf(sentry, "%s:\n", label);
-
- return true;
-}
-
void
helper_server::checkForTimedOutRequests(bool const retry)
{