You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2024/05/27 11:04:52 UTC
svn commit: r1918003 - in /httpd/httpd/trunk/modules/http2: h2_c1.c h2_c2.c h2_mplx.c h2_mplx.h h2_session.c h2_session.h h2_version.h
Author: icing
Date: Mon May 27 11:04:52 2024
New Revision: 1918003
URL: http://svn.apache.org/viewvc?rev=1918003&view=rev
Log:
*) mod_http2: sync with module's github.
- on newer HTTPD versions, return connection monitoring
to the event MPM when block on client updates.
2.4.x versions still treat connections in the event
MPM as KeepAlive and purge them on load in the middle
of response processing.
- spelling fixes
- support for yield calls in c2 "network" filter
Modified:
httpd/httpd/trunk/modules/http2/h2_c1.c
httpd/httpd/trunk/modules/http2/h2_c2.c
httpd/httpd/trunk/modules/http2/h2_mplx.c
httpd/httpd/trunk/modules/http2/h2_mplx.h
httpd/httpd/trunk/modules/http2/h2_session.c
httpd/httpd/trunk/modules/http2/h2_session.h
httpd/httpd/trunk/modules/http2/h2_version.h
Modified: httpd/httpd/trunk/modules/http2/h2_c1.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_c1.c?rev=1918003&r1=1918002&r2=1918003&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_c1.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_c1.c Mon May 27 11:04:52 2024
@@ -116,7 +116,7 @@ cleanup:
apr_status_t h2_c1_run(conn_rec *c)
{
apr_status_t status;
- int mpm_state = 0;
+ int mpm_state = 0, keepalive = 0;
h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
ap_assert(conn_ctx);
@@ -127,7 +127,7 @@ apr_status_t h2_c1_run(conn_rec *c)
c->cs->state = CONN_STATE_HANDLER;
}
- status = h2_session_process(conn_ctx->session, async_mpm);
+ status = h2_session_process(conn_ctx->session, async_mpm, &keepalive);
if (APR_STATUS_IS_EOF(status)) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
@@ -153,7 +153,7 @@ apr_status_t h2_c1_run(conn_rec *c)
case H2_SESSION_ST_BUSY:
case H2_SESSION_ST_WAIT:
c->cs->state = CONN_STATE_WRITE_COMPLETION;
- if (c->cs && !conn_ctx->session->remote.emitted_count) {
+ if (!keepalive) {
/* let the MPM know that we are not done and want
* the Timeout behaviour instead of a KeepAliveTimeout
* See PR 63534.
Modified: httpd/httpd/trunk/modules/http2/h2_c2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_c2.c?rev=1918003&r1=1918002&r2=1918003&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_c2.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_c2.c Mon May 27 11:04:52 2024
@@ -370,6 +370,13 @@ static apr_status_t h2_c2_filter_out(ap_
h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
apr_status_t rv;
+ if (bb == NULL) {
+#if !AP_MODULE_MAGIC_AT_LEAST(20180720, 1)
+ f->c->data_in_output_filters = 0;
+#endif
+ return APR_SUCCESS;
+ }
+
ap_assert(conn_ctx);
#if AP_HAS_RESPONSE_BUCKETS
if (!conn_ctx->has_final_response) {
Modified: httpd/httpd/trunk/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.c?rev=1918003&r1=1918002&r2=1918003&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.c Mon May 27 11:04:52 2024
@@ -398,6 +398,7 @@ apr_status_t h2_mplx_c1_streams_do(h2_mp
typedef struct {
int stream_count;
int stream_want_send;
+ int stream_send_win_exhausted;
} stream_iter_aws_t;
static int m_stream_want_send_data(void *ctx, void *stream)
@@ -420,6 +421,29 @@ int h2_mplx_c1_all_streams_want_send_dat
return x.stream_count && (x.stream_count == x.stream_want_send);
}
+static int m_stream_send_win_exh(void *ctx, void *s)
+{
+ h2_stream *stream = s;
+ int win;
+ stream_iter_aws_t *x = ctx;
+ ++x->stream_count;
+ win = nghttp2_session_get_stream_remote_window_size(stream->session->ngh2, stream->id);
+ if (win == 0)
+ ++x->stream_send_win_exhausted;
+ return 1;
+}
+
+int h2_mplx_c1_all_streams_send_win_exhausted(h2_mplx *m)
+{
+ stream_iter_aws_t x;
+ x.stream_count = 0;
+ x.stream_send_win_exhausted = 0;
+ H2_MPLX_ENTER(m);
+ h2_ihash_iter(m->streams, m_stream_send_win_exh, &x);
+ H2_MPLX_LEAVE(m);
+ return x.stream_count && (x.stream_count == x.stream_send_win_exhausted);
+}
+
static int m_report_stream_iter(void *ctx, void *val) {
h2_mplx *m = ctx;
h2_stream *stream = val;
Modified: httpd/httpd/trunk/modules/http2/h2_mplx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.h?rev=1918003&r1=1918002&r2=1918003&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.h Mon May 27 11:04:52 2024
@@ -197,6 +197,11 @@ apr_status_t h2_mplx_c1_streams_do(h2_mp
int h2_mplx_c1_all_streams_want_send_data(h2_mplx *m);
/**
+ * Return != 0 iff all open streams have send window exhausted
+ */
+int h2_mplx_c1_all_streams_send_win_exhausted(h2_mplx *m);
+
+/**
* A stream has been RST_STREAM by the client. Abort
* any processing going on and remove from processing
* queue.
Modified: httpd/httpd/trunk/modules/http2/h2_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_session.c?rev=1918003&r1=1918002&r2=1918003&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_session.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_session.c Mon May 27 11:04:52 2024
@@ -323,8 +323,8 @@ static int on_header_cb(nghttp2_session
(!stream->rtmp ||
stream->rtmp->http_status == H2_HTTP_STATUS_UNSET ||
/* We accept a certain amount of failures in order to reply
- * with an informative HTTP error response like 413. But if the
- * client is too wrong, we fail the request a RESET of the stream */
+ * with an informative HTTP error response like 413. But of the
+ * client is too wrong, we RESET the stream */
stream->request_headers_failed > 100)) {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
@@ -1762,12 +1762,22 @@ static void unblock_c1_out(h2_session *s
}
}
-apr_status_t h2_session_process(h2_session *session, int async)
+static int h2_send_flow_blocked(h2_session *session)
+{
+ /* We are completely send blocked if either the connection window
+ * is 0 or all stream flow windows are 0. */
+ return ((nghttp2_session_get_remote_window_size(session->ngh2) <= 0) ||
+ h2_mplx_c1_all_streams_send_win_exhausted(session->mplx));
+}
+
+apr_status_t h2_session_process(h2_session *session, int async,
+ int *pkeepalive)
{
apr_status_t status = APR_SUCCESS;
conn_rec *c = session->c1;
int rv, mpm_state, trace = APLOGctrace3(c);
+ *pkeepalive = 0;
if (trace) {
ap_log_cerror( APLOG_MARK, APLOG_TRACE3, status, c,
H2_SSSN_MSG(session, "process start, async=%d"), async);
@@ -1922,6 +1932,14 @@ apr_status_t h2_session_process(h2_sessi
break;
case H2_SESSION_ST_WAIT:
+ /* In this state, we might have returned processing to the MPM
+ * before. On a connection socket event, we are invoked again and
+ * need to process any input before proceeding. */
+ h2_c1_read(session);
+ if (session->state != H2_SESSION_ST_WAIT) {
+ break;
+ }
+
status = h2_c1_io_assure_flushed(&session->io);
if (APR_SUCCESS != status) {
h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, status, NULL);
@@ -1934,8 +1952,20 @@ apr_status_t h2_session_process(h2_sessi
break;
}
}
- /* No IO happening and input is exhausted. Make sure we have
- * flushed any possibly pending output and then wait with
+#if AP_MODULE_MAGIC_AT_LEAST(20211221, 19)
+ else if (async && h2_send_flow_blocked(session)) {
+ /* On a recent HTTPD, we can return to mpm c1 monitoring,
+ * as it does not treat all connections as having KeepAlive
+ * timing and being purgeable on load.
+ * By returning to the MPM, we do not block a worker
+ * and async wait for the client send window updates. */
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
+ H2_SSSN_LOG(APLOGNO(10502), session,
+ "BLOCKED, return to mpm c1 monitoring"));
+ goto leaving;
+ }
+#endif
+ /* No IO happening and input is exhausted. Wait with
* the c1 connection timeout for sth to happen in our c1/c2 sockets/pipes */
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, c,
H2_SSSN_MSG(session, "polling timeout=%d, open_streams=%d"),
@@ -1976,9 +2006,13 @@ apr_status_t h2_session_process(h2_sessi
}
leaving:
+ /* entering KeepAlive timing when we have no more open streams AND
+ * we have processed at least one stream. */
+ *pkeepalive = (session->open_streams == 0 && session->remote.emitted_count);
if (trace) {
- ap_log_cerror( APLOG_MARK, APLOG_TRACE3, status, c,
- H2_SSSN_MSG(session, "process returns"));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, c,
+ H2_SSSN_MSG(session, "process returns, keepalive=%d"),
+ *pkeepalive);
}
h2_mplx_c1_going_keepalive(session->mplx);
Modified: httpd/httpd/trunk/modules/http2/h2_session.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_session.h?rev=1918003&r1=1918002&r2=1918003&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_session.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_session.h Mon May 27 11:04:52 2024
@@ -144,8 +144,11 @@ void h2_session_event(h2_session *sessio
* error occurred.
*
* @param session the sessionm to process
+ * @param async if mpm is async
+ * @param pkeepalive on return, != 0 if connection to be put into keepalive
+ * behaviour and timouts
*/
-apr_status_t h2_session_process(h2_session *session, int async);
+apr_status_t h2_session_process(h2_session *session, int async, int *pkeepalive);
/**
* Last chance to do anything before the connection is closed.
Modified: httpd/httpd/trunk/modules/http2/h2_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_version.h?rev=1918003&r1=1918002&r2=1918003&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_version.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_version.h Mon May 27 11:04:52 2024
@@ -27,7 +27,7 @@
* @macro
* Version number of the http2 module as c string
*/
-#define MOD_HTTP2_VERSION "2.0.26"
+#define MOD_HTTP2_VERSION "2.0.27"
/**
* @macro
@@ -35,7 +35,7 @@
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
-#define MOD_HTTP2_VERSION_NUM 0x02001a
+#define MOD_HTTP2_VERSION_NUM 0x02001b
#endif /* mod_h2_h2_version_h */
Re: svn commit: r1918003 - in /httpd/httpd/trunk/modules/http2: h2_c1.c h2_c2.c h2_mplx.c h2_mplx.h h2_session.c h2_session.h h2_version.h
Posted by Yann Ylavic <yl...@gmail.com>.
On Tue, May 28, 2024 at 4:06 PM Stefan Eissing via dev
<de...@httpd.apache.org> wrote:
>
>
>
> > Am 28.05.2024 um 15:45 schrieb Yann Ylavic <yl...@gmail.com>:
> >
> > On Tue, May 28, 2024 at 12:47 PM Stefan Eissing via dev
> > <de...@httpd.apache.org> wrote:
> >>
> >>> Am 27.05.2024 um 14:08 schrieb Yann Ylavic <yl...@gmail.com>:
> >>>
> >>> Per our discussion the other day, if you want to avoid c1 connections
> >>> to be killed by mpm_event on high load in this case, I think you can
> >>> do this here:
> >>>
> >>> Index: modules/http2/h2_c1.c
> >>> ===================================================================
> >>> --- modules/http2/h2_c1.c (revision 1918003)
> >>> +++ modules/http2/h2_c1.c (working copy)
> >>> @@ -147,6 +147,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> >>> && mpm_state != AP_MPMQ_STOPPING);
> >>>
> >>> if (c->cs) {
> >>> + c->clogging_input_filters = 0;
> >>> switch (conn_ctx->session->state) {
> >>> case H2_SESSION_ST_INIT:
> >>> case H2_SESSION_ST_IDLE:
> >>> @@ -159,6 +160,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> >>> * See PR 63534.
> >>> */
> >>> c->cs->sense = CONN_SENSE_WANT_READ;
> >>> + c->clogging_input_filters = 1;
> >>> 03465}
> >>> break;
> >>> case H2_SESSION_ST_CLEANUP:
> >>> --
> >>>
> >>> c->clogging_input_filters = 1 will tell the MPM to always call
> >>> process_connection() hooks after the WRITE_COMPLETION state did the
> >>> poll(), rather than entering the (killable) keepalive state.
> >>>
> >>> Looks like the correct workaround with current mpm_event..
> >>
> >> Just so I get this right. It will return to processing after the
> >> write is done or after a POLLIN happened? In the first case, it
> >> will not have really a positive effect on worker allocations,
> >> seems to me.
> >
> > Yes, it will return to processing after POLLIN happens thanks to
> > CONN_SENSE_WANT_READ, even if there are pending output data.
> > But it's a really convoluted handling of POLLIN/POLLOUT in mpm_event,
> > with the need of that obscure c->clogging_input_filters..
> > So I just created https://github.com/apache/httpd/pull/448 to do that
> > better (and it includes the changes to h2_c1_run() too).
> > The plan could be to merge that to trunk and include it in your
> > backport proposal (if it works for you)?
> >
>
> Great!
Backport PR in https://github.com/apache/httpd/pull/449 ;)
Regards;
Yann.
Re: svn commit: r1918003 - in /httpd/httpd/trunk/modules/http2: h2_c1.c h2_c2.c h2_mplx.c h2_mplx.h h2_session.c h2_session.h h2_version.h
Posted by Stefan Eissing via dev <de...@httpd.apache.org>.
> Am 28.05.2024 um 15:45 schrieb Yann Ylavic <yl...@gmail.com>:
>
> On Tue, May 28, 2024 at 12:47 PM Stefan Eissing via dev
> <de...@httpd.apache.org> wrote:
>>
>>> Am 27.05.2024 um 14:08 schrieb Yann Ylavic <yl...@gmail.com>:
>>>
>>> Per our discussion the other day, if you want to avoid c1 connections
>>> to be killed by mpm_event on high load in this case, I think you can
>>> do this here:
>>>
>>> Index: modules/http2/h2_c1.c
>>> ===================================================================
>>> --- modules/http2/h2_c1.c (revision 1918003)
>>> +++ modules/http2/h2_c1.c (working copy)
>>> @@ -147,6 +147,7 @@ apr_status_t h2_c1_run(conn_rec *c)
>>> && mpm_state != AP_MPMQ_STOPPING);
>>>
>>> if (c->cs) {
>>> + c->clogging_input_filters = 0;
>>> switch (conn_ctx->session->state) {
>>> case H2_SESSION_ST_INIT:
>>> case H2_SESSION_ST_IDLE:
>>> @@ -159,6 +160,7 @@ apr_status_t h2_c1_run(conn_rec *c)
>>> * See PR 63534.
>>> */
>>> c->cs->sense = CONN_SENSE_WANT_READ;
>>> + c->clogging_input_filters = 1;
>>> 03465}
>>> break;
>>> case H2_SESSION_ST_CLEANUP:
>>> --
>>>
>>> c->clogging_input_filters = 1 will tell the MPM to always call
>>> process_connection() hooks after the WRITE_COMPLETION state did the
>>> poll(), rather than entering the (killable) keepalive state.
>>>
>>> Looks like the correct workaround with current mpm_event..
>>
>> Just so I get this right. It will return to processing after the
>> write is done or after a POLLIN happened? In the first case, it
>> will not have really a positive effect on worker allocations,
>> seems to me.
>
> Yes, it will return to processing after POLLIN happens thanks to
> CONN_SENSE_WANT_READ, even if there are pending output data.
> But it's a really convoluted handling of POLLIN/POLLOUT in mpm_event,
> with the need of that obscure c->clogging_input_filters..
> So I just created https://github.com/apache/httpd/pull/448 to do that
> better (and it includes the changes to h2_c1_run() too).
> The plan could be to merge that to trunk and include it in your
> backport proposal (if it works for you)?
>
Great!
>
> Regards;
> Yann.
Re: svn commit: r1918003 - in /httpd/httpd/trunk/modules/http2: h2_c1.c h2_c2.c h2_mplx.c h2_mplx.h h2_session.c h2_session.h h2_version.h
Posted by Yann Ylavic <yl...@gmail.com>.
On Tue, May 28, 2024 at 12:47 PM Stefan Eissing via dev
<de...@httpd.apache.org> wrote:
>
> > Am 27.05.2024 um 14:08 schrieb Yann Ylavic <yl...@gmail.com>:
> >
> > Per our discussion the other day, if you want to avoid c1 connections
> > to be killed by mpm_event on high load in this case, I think you can
> > do this here:
> >
> > Index: modules/http2/h2_c1.c
> > ===================================================================
> > --- modules/http2/h2_c1.c (revision 1918003)
> > +++ modules/http2/h2_c1.c (working copy)
> > @@ -147,6 +147,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> > && mpm_state != AP_MPMQ_STOPPING);
> >
> > if (c->cs) {
> > + c->clogging_input_filters = 0;
> > switch (conn_ctx->session->state) {
> > case H2_SESSION_ST_INIT:
> > case H2_SESSION_ST_IDLE:
> > @@ -159,6 +160,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> > * See PR 63534.
> > */
> > c->cs->sense = CONN_SENSE_WANT_READ;
> > + c->clogging_input_filters = 1;
> > 03465}
> > break;
> > case H2_SESSION_ST_CLEANUP:
> > --
> >
> > c->clogging_input_filters = 1 will tell the MPM to always call
> > process_connection() hooks after the WRITE_COMPLETION state did the
> > poll(), rather than entering the (killable) keepalive state.
> >
> > Looks like the correct workaround with current mpm_event..
>
> Just so I get this right. It will return to processing after the
> write is done or after a POLLIN happened? In the first case, it
> will not have really a positive effect on worker allocations,
> seems to me.
Yes, it will return to processing after POLLIN happens thanks to
CONN_SENSE_WANT_READ, even if there are pending output data.
But it's a really convoluted handling of POLLIN/POLLOUT in mpm_event,
with the need of that obscure c->clogging_input_filters..
So I just created https://github.com/apache/httpd/pull/448 to do that
better (and it includes the changes to h2_c1_run() too).
The plan could be to merge that to trunk and include it in your
backport proposal (if it works for you)?
Regards;
Yann.
Re: svn commit: r1918003 - in /httpd/httpd/trunk/modules/http2: h2_c1.c h2_c2.c h2_mplx.c h2_mplx.h h2_session.c h2_session.h h2_version.h
Posted by Stefan Eissing via dev <de...@httpd.apache.org>.
> Am 27.05.2024 um 14:08 schrieb Yann Ylavic <yl...@gmail.com>:
>
> On Mon, May 27, 2024 at 1:04 PM <ic...@apache.org> wrote:
>>
>> Author: icing
>> Date: Mon May 27 11:04:52 2024
>> New Revision: 1918003
>>
>> URL: http://svn.apache.org/viewvc?rev=1918003&view=rev
>> Log:
>> *) mod_http2: sync with module's github.
>> - on newer HTTPD versions, return connection monitoring
>> to the event MPM when block on client updates.
>> 2.4.x versions still treat connections in the event
>> MPM as KeepAlive and purge them on load in the middle
>> of response processing.
>> - spelling fixes
>> - support for yield calls in c2 "network" filter
> []
>>
>> --- httpd/httpd/trunk/modules/http2/h2_c1.c (original)
>> +++ httpd/httpd/trunk/modules/http2/h2_c1.c Mon May 27 11:04:52 2024
>> @@ -116,7 +116,7 @@ cleanup:
>> apr_status_t h2_c1_run(conn_rec *c)
>> {
>> apr_status_t status;
>> - int mpm_state = 0;
>> + int mpm_state = 0, keepalive = 0;
>> h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
>>
>> ap_assert(conn_ctx);
>> @@ -127,7 +127,7 @@ apr_status_t h2_c1_run(conn_rec *c)
>> c->cs->state = CONN_STATE_HANDLER;
>> }
>>
>> - status = h2_session_process(conn_ctx->session, async_mpm);
>> + status = h2_session_process(conn_ctx->session, async_mpm, &keepalive);
>>
>> if (APR_STATUS_IS_EOF(status)) {
>> ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
>> @@ -153,7 +153,7 @@ apr_status_t h2_c1_run(conn_rec *c)
>> case H2_SESSION_ST_BUSY:
>> case H2_SESSION_ST_WAIT:
>> c->cs->state = CONN_STATE_WRITE_COMPLETION;
>> - if (c->cs && !conn_ctx->session->remote.emitted_count) {
>> + if (!keepalive) {
>> /* let the MPM know that we are not done and want
>> * the Timeout behaviour instead of a KeepAliveTimeout
>> * See PR 63534.
>
> Per our discussion the other day, if you want to avoid c1 connections
> to be killed by mpm_event on high load in this case, I think you can
> do this here:
>
> Index: modules/http2/h2_c1.c
> ===================================================================
> --- modules/http2/h2_c1.c (revision 1918003)
> +++ modules/http2/h2_c1.c (working copy)
> @@ -147,6 +147,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> && mpm_state != AP_MPMQ_STOPPING);
>
> if (c->cs) {
> + c->clogging_input_filters = 0;
> switch (conn_ctx->session->state) {
> case H2_SESSION_ST_INIT:
> case H2_SESSION_ST_IDLE:
> @@ -159,6 +160,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> * See PR 63534.
> */
> c->cs->sense = CONN_SENSE_WANT_READ;
> + c->clogging_input_filters = 1;
> }
> break;
> case H2_SESSION_ST_CLEANUP:
> --
>
> c->clogging_input_filters = 1 will tell the MPM to always call
> process_connection() hooks after the WRITE_COMPLETION state did the
> poll(), rather than entering the (killable) keepalive state.
>
> Looks like the correct workaround with current mpm_event..
Just so I get this right. It will return to processing after the
write is done or after a POLLIN happened? In the first case, it
will not have really a positive effect on worker allocations,
seems to me.
Cheers,
Stefan
>
>
> Regards;
> Yann.
Re: svn commit: r1918003 - in /httpd/httpd/trunk/modules/http2: h2_c1.c h2_c2.c h2_mplx.c h2_mplx.h h2_session.c h2_session.h h2_version.h
Posted by Yann Ylavic <yl...@gmail.com>.
On Mon, May 27, 2024 at 1:04 PM <ic...@apache.org> wrote:
>
> Author: icing
> Date: Mon May 27 11:04:52 2024
> New Revision: 1918003
>
> URL: http://svn.apache.org/viewvc?rev=1918003&view=rev
> Log:
> *) mod_http2: sync with module's github.
> - on newer HTTPD versions, return connection monitoring
> to the event MPM when block on client updates.
> 2.4.x versions still treat connections in the event
> MPM as KeepAlive and purge them on load in the middle
> of response processing.
> - spelling fixes
> - support for yield calls in c2 "network" filter
[]
>
> --- httpd/httpd/trunk/modules/http2/h2_c1.c (original)
> +++ httpd/httpd/trunk/modules/http2/h2_c1.c Mon May 27 11:04:52 2024
> @@ -116,7 +116,7 @@ cleanup:
> apr_status_t h2_c1_run(conn_rec *c)
> {
> apr_status_t status;
> - int mpm_state = 0;
> + int mpm_state = 0, keepalive = 0;
> h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
>
> ap_assert(conn_ctx);
> @@ -127,7 +127,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> c->cs->state = CONN_STATE_HANDLER;
> }
>
> - status = h2_session_process(conn_ctx->session, async_mpm);
> + status = h2_session_process(conn_ctx->session, async_mpm, &keepalive);
>
> if (APR_STATUS_IS_EOF(status)) {
> ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
> @@ -153,7 +153,7 @@ apr_status_t h2_c1_run(conn_rec *c)
> case H2_SESSION_ST_BUSY:
> case H2_SESSION_ST_WAIT:
> c->cs->state = CONN_STATE_WRITE_COMPLETION;
> - if (c->cs && !conn_ctx->session->remote.emitted_count) {
> + if (!keepalive) {
> /* let the MPM know that we are not done and want
> * the Timeout behaviour instead of a KeepAliveTimeout
> * See PR 63534.
Per our discussion the other day, if you want to avoid c1 connections
to be killed by mpm_event on high load in this case, I think you can
do this here:
Index: modules/http2/h2_c1.c
===================================================================
--- modules/http2/h2_c1.c (revision 1918003)
+++ modules/http2/h2_c1.c (working copy)
@@ -147,6 +147,7 @@ apr_status_t h2_c1_run(conn_rec *c)
&& mpm_state != AP_MPMQ_STOPPING);
if (c->cs) {
+ c->clogging_input_filters = 0;
switch (conn_ctx->session->state) {
case H2_SESSION_ST_INIT:
case H2_SESSION_ST_IDLE:
@@ -159,6 +160,7 @@ apr_status_t h2_c1_run(conn_rec *c)
* See PR 63534.
*/
c->cs->sense = CONN_SENSE_WANT_READ;
+ c->clogging_input_filters = 1;
}
break;
case H2_SESSION_ST_CLEANUP:
--
c->clogging_input_filters = 1 will tell the MPM to always call
process_connection() hooks after the WRITE_COMPLETION state did the
poll(), rather than entering the (killable) keepalive state.
Looks like the correct workaround with current mpm_event..
Regards;
Yann.