From: Jim Jagielski Date: Thu, 9 Mar 2006 18:39:16 +0000 (+0000) Subject: Make AJP flushing admin configurable. X-Git-Tag: 2.3.0~2514 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=391472a0500c5836a0da0baeffd0c3eab339e737;p=thirdparty%2Fapache%2Fhttpd.git Make AJP flushing admin configurable. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@384580 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 4eab150829e..4c0b950edf5 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -218,6 +218,26 @@ static const char *set_worker_param(apr_pool_t *p, } } } + else if (!strcasecmp(key, "ajpflushpackets")) { + if (!strcasecmp(val, "on")) + worker->ajp_flush_packets = ajp_flush_on; + else if (!strcasecmp(val, "off")) + worker->ajp_flush_packets = ajp_flush_off; + else if (!strcasecmp(val, "auto")) + worker->ajp_flush_packets = ajp_flush_auto; + else + return "FlushPackets must be On|Off|Auto"; + } + else if (!strcasecmp(key, "ajpflushwait")) { + ival = atoi(val); + if (ival > 1000 || ival < 0) { + return "AJPFlushWait must be <= 1000, or 0 for system default of 10 millseconds."; + } + if (ival == 0) + worker->ajp_flush_wait = AJP_FLUSH_WAIT; + else + worker->ajp_flush_wait = ival * 1000; /* change to microseconds */ + } else { return "unknown Worker parameter"; } diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 7bc092eac04..d54fd45f877 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -301,9 +301,21 @@ struct proxy_worker { #if APR_HAS_THREADS apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */ #endif - void *context; /* general purpose storage */ + void *context; /* general purpose storage */ + enum { + ajp_flush_off, + ajp_flush_on, + ajp_flush_auto + } ajp_flush_packets; /* control AJP flushing */ + int ajp_flush_wait; /* poll wait time in microseconds if flush_auto */ }; +/* + * Wait 10000 microseconds to find out if more data is currently + * available at the backend. Just an arbitrary choose. + */ +#define AJP_FLUSH_WAIT 10000 + struct proxy_balancer { apr_array_header_t *workers; /* array of proxy_workers */ const char *name; /* name of the load balancer */ diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index 3c97162cced..2a7ec32988c 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -90,7 +90,7 @@ static int proxy_ajp_canon(request_rec *r, char *url) } /* - * XXX: Flushing bandaid + * XXX: AJP Auto Flushing * * When processing CMD_AJP13_SEND_BODY_CHUNK AJP messages we will do a poll * with FLUSH_WAIT miliseconds timeout to determine if more data is currently @@ -105,15 +105,6 @@ static int proxy_ajp_canon(request_rec *r, char *url) * For further discussion see PR37100. * http://issues.apache.org/bugzilla/show_bug.cgi?id=37100 */ -#define FLUSHING_BANDAID 1 - -#ifdef FLUSHING_BANDAID -/* - * Wait 10000 microseconds to find out if more data is currently - * available at the backend. Just an arbitrary choose. - */ -#define FLUSH_WAIT 10000 -#endif /* * process the request and write the response. @@ -140,10 +131,8 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, apr_off_t bb_len; int data_sent = 0; int rv = 0; -#ifdef FLUSHING_BANDAID apr_int32_t conn_poll_fd; apr_pollfd_t *conn_poll; -#endif /* * Send the AJP request to the remote server @@ -250,9 +239,8 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, result = ajp_parse_type(r, conn->data); output_brigade = apr_brigade_create(p, r->connection->bucket_alloc); -#ifdef FLUSHING_BANDAID /* - * Prepare apr_pollfd_t struct for later check if there is currently + * Prepare apr_pollfd_t struct for possible later check if there is currently * data available from the backend (do not flush response to client) * or not (flush response to client) */ @@ -260,7 +248,6 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, conn_poll->reqevents = APR_POLLIN; conn_poll->desc_type = APR_POLL_SOCKET; conn_poll->desc.s = conn->sock; -#endif bufsiz = AJP13_MAX_SEND_BODY_SZ; while (isok) { @@ -330,17 +317,14 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, r->connection->bucket_alloc); APR_BRIGADE_INSERT_TAIL(output_brigade, e); -#ifdef FLUSHING_BANDAID - /* - * If there is no more data available from backend side - * currently, flush response to client. - */ - if (apr_poll(conn_poll, 1, &conn_poll_fd, FLUSH_WAIT) - == APR_TIMEUP) { + if ( (conn->worker->ajp_flush_packets == ajp_flush_on) || + ( (conn->worker->ajp_flush_packets == ajp_flush_auto) && + (apr_poll(conn_poll, 1, &conn_poll_fd, + conn->worker->ajp_flush_wait) + == APR_TIMEUP) ) ) { e = apr_bucket_flush_create(r->connection->bucket_alloc); APR_BRIGADE_INSERT_TAIL(output_brigade, e); } -#endif apr_brigade_length(output_brigade, 0, &bb_len); if (bb_len != -1) conn->worker->s->read += bb_len; @@ -366,6 +350,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, "proxy: error processing body"); isok = 0; } + /* XXX: what about flush here? See mod_jk */ data_sent = 1; break; default: diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index a52a146b839..3a8f288a630 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1318,6 +1318,8 @@ PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker, (*worker)->hostname = uri.hostname; (*worker)->port = uri.port; (*worker)->id = proxy_lb_workers; + (*worker)->ajp_flush_packets = ajp_flush_off; + (*worker)->ajp_flush_wait = AJP_FLUSH_WAIT; /* Increase the total worker count */ proxy_lb_workers++; init_conn_pool(p, *worker);