On Mon, May 13, 2024 at 9:02 PM Yann Ylavic <ylavic....@gmail.com> wrote: > > On Mon, May 13, 2024 at 6:31 PM Stefan Eissing <ste...@eissing.org> wrote: > > > > > Am 13.05.2024 um 17:41 schrieb Yann Ylavic <ylavic....@gmail.com>: > > > > > > On Mon, May 13, 2024 at 1:32 PM Stefan Eissing > > >> > > >> With the change in PR 280, we return on being flow blocked. The > > >> response(s) are *not* finished. If MPM now closes such a connection > > >> under load, the client will most likely try again. This seems counter > > >> productive. > > > > > > AFAICT the CONN_STATE_WRITE_COMPLETION state is different depending on > > > CONN_SENSE_WANT_READ and CONN_SENSE_WANT_WRITE/DEFAULT. > > > With CONN_SENSE_WANT_WRITE/DEFAULT, mpm_event will indeed assume flush > > > (nonblocking) before close, > > It's actually a flush before *keepalive* (unless !AP_CONN_KEEPALIVE), > though it's not what you want anyway. > > > > but with CONN_SENSE_WANT_READ it will poll > > > for read on the connection and come back to the process_connection > > > hooks when something is in. > > > > > > When mod_h2 waits for some WINDOW_UPDATE it wants the MPM to POLLIN > > > (right?), h2_c1_hook_process_connection() should recover/continue with > > > the new data from the client. And since it's a c1 connection I don't > > > think there needs to be some new pollset/queues sizing adjustment to > > > do either, so we should be good? > > > > Yes, mod_h2 does CONN_STATE_WRITE_COMPLETION and CONN_SENSE_WANT_READ and > > it works nicely. The only thing is that, when I open many connections, > > unfinished ones get dropped very fast. Like after a few milliseconds. > > What do you mean by unfinished ones, which state are they in (i.e. how > do they end up in the MPM with a keepalive state which is the only one > where connections are "early" killed under high load)? > I think this can only happen when mpm_event gets a connection with > c->cs->state == CONN_STATE_WRITE_COMPLETION but c->cs->sense != > CONN_SENSE_WANT_READ, is that a mod_h2 possible thing?
Hm, I think I figured this out by myself. As I said above CONN_STATE_WRITE_COMPLETION leads to CONN_STATE_CHECK_REQUEST_LINE_READABLE (i.e keepalive state) once the completion is done (or the POLLIN with c->cs->sense == CONN_SENSE_WANT_READ) and if there is no input data already pending. This is really not what mod_h2 wants but rather ap_run_process_connection() to always be called after POLLIN. We could handle that specifically for the CONN_SENSE_WANT_READ case but it's yet more abuse of CONN_STATE_WRITE_COMPLETION imho. Let's see how CONN_STATE_PROCESS (from PR 294 below) works to take the relevant bits in trunk eventually. > > > >> > > >> Therefore I am hesitant if this change is beneficial for us. It frees up > > >> a worker thread - that is good - but. Do we need a new "connection > > >> state" here? > > >> > > >> WDYT? > > > > > > I think the semantics of CONN_STATE_WRITE_COMPLETION with > > > CONN_SENSE_WANT_* are quite unintuitive (for the least), so we > > > probably should have different states for CONN_STATE_WRITE_COMPLETION > > > (flush before close) and CONN_STATE_POLL_READ/POLL_WRITE/POLL_RW which > > > would be how a process_connection hook would return to the MPM just > > > for poll()ing. > > > > I think that would be excellent, yes. Trigger polling with the connection > > Timeout value. > > There is https://github.com/apache/httpd/pull/294 with quite some > changes to mpm_event. Sorry this is still WIP and needs to be split > more, probably in multiple PRs too, but it works for the tests I've > done so far (I just rebased it on latest trunk). > This change starts with Graham's AGAIN return code (from > process_connection hooks) for letting the MPM do the polling for SSL > handshakes that'd block for instance. It then expanded to a > CONN_STATE_PROCESS state (renamed from CONN_STATE_READ_REQUEST_LINE) > where mpm_event receiving AGAIN from ap_run_process_connection() will > simply poll according to the c->cs->sense value > (WANT_READ/WANT_WRITE). > This PR also removes all keepalive kills, though I don't think mod_h2 > should rely on this state? > > Could you try running your mod_h2 changes on top of it and with > h2_c1_run() doing something like: > c->cs->state = CONN_STATE_PROCESS; > c->cs->state = CONN_SENSE_WANT_READ; /* or _WRITE */ This should be c->cs->sense = CONN_SENSE_WANT_READ of course.. > return AGAIN; > where you want mpm_event to simply poll() for read (or write)? > > > Regards; > Yann.