Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ylavic committed Apr 5, 2022
1 parent d6d86a2 commit 57d5dc6
Show file tree
Hide file tree
Showing 9 changed files with 1,179 additions and 896 deletions.
1 change: 1 addition & 0 deletions include/scoreboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ struct process_score {
apr_uint32_t keep_alive; /* async connections in keep alive */
apr_uint32_t suspended; /* connections suspended by some module */
apr_uint32_t read_line; /* async connections doing read line */
apr_uint32_t pending; /* connections waiting a worker */
};

/* Scoreboard is now in 'local' memory, since it isn't updated once created,
Expand Down
40 changes: 23 additions & 17 deletions modules/filters/mod_reqtimeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ static void extend_timeout(reqtimeout_con_cfg *ccfg, apr_bucket_brigade *bb)
}
}

static apr_status_t check_time_left(reqtimeout_con_cfg *ccfg,
apr_time_t now)
static apr_status_t check_and_update_time_left(reqtimeout_con_cfg *ccfg,
apr_time_t now)
{
if (!now)
now = apr_time_now();
Expand Down Expand Up @@ -209,11 +209,11 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,
/* set new timeout */
now = apr_time_now();
ccfg->timeout_at = now + apr_time_from_sec(ccfg->cur_stage.timeout);
ccfg->cur_stage.timeout = 0;
if (ccfg->cur_stage.max_timeout > 0) {
ccfg->max_timeout_at = now + apr_time_from_sec(ccfg->cur_stage.max_timeout);
ccfg->cur_stage.max_timeout = 0;
}
ccfg->cur_stage.timeout = 0;
}
else if (ccfg->timeout_at == 0) {
/* no timeout set, or in between requests */
Expand All @@ -227,25 +227,27 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,
rv = apr_socket_timeout_get(ccfg->socket, &saved_sock_timeout);
AP_DEBUG_ASSERT(rv == APR_SUCCESS);

rv = check_time_left(ccfg, now);
rv = check_and_update_time_left(ccfg, now);
if (rv != APR_SUCCESS)
goto cleanup;

if (mode == AP_MODE_GETLINE && block == APR_BLOCK_READ) {
apr_off_t remaining = HUGE_STRING_LEN;
#if APR_MAJOR_VERSION < 2
apr_int32_t nsds;
apr_interval_time_t poll_timeout;
apr_pollfd_t pollset;
pollset.p = NULL;
#endif

/*
* For a blocking AP_MODE_GETLINE read, apr_brigade_split_line()
* would loop until a whole line has been read. As this would make it
* impossible to enforce a total timeout, we only do non-blocking
* reads.
*/
apr_off_t remaining = HUGE_STRING_LEN;
do {
apr_off_t bblen;
#if APR_MAJOR_VERSION < 2
apr_int32_t nsds;
apr_interval_time_t poll_timeout;
apr_pollfd_t pollset;
#endif

rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, APR_NONBLOCK_READ, remaining);
if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
Expand Down Expand Up @@ -282,10 +284,12 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,

/* ... and wait for more */
#if APR_MAJOR_VERSION < 2
pollset.p = f->c->pool;
pollset.desc_type = APR_POLL_SOCKET;
pollset.reqevents = APR_POLLIN|APR_POLLHUP;
pollset.desc.s = ccfg->socket;
if (pollset.p == NULL) {
pollset.p = f->c->pool;
pollset.desc_type = APR_POLL_SOCKET;
pollset.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;
pollset.desc.s = ccfg->socket;
}
apr_socket_timeout_get(ccfg->socket, &poll_timeout);
rv = apr_poll(&pollset, 1, &nsds, poll_timeout);
#else
Expand All @@ -294,7 +298,7 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,
if (rv != APR_SUCCESS)
break;

rv = check_time_left(ccfg, 0);
rv = check_and_update_time_left(ccfg, 0);
if (rv != APR_SUCCESS)
break;

Expand All @@ -306,12 +310,14 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,
}
else { /* mode != AP_MODE_GETLINE */
rv = ap_get_brigade(f->next, bb, mode, block, readbytes);

/* Don't extend the timeout in speculative mode, wait for
* the real (relevant) bytes to be asked later, within the
* currently allotted time.
*/
if (ccfg->cur_stage.rate_factor && rv == APR_SUCCESS
&& mode != AP_MODE_SPECULATIVE) {
if (rv == APR_SUCCESS
&& mode != AP_MODE_SPECULATIVE
&& ccfg->cur_stage.rate_factor) {
extend_timeout(ccfg, bb);
}
}
Expand Down
21 changes: 15 additions & 6 deletions modules/generators/mod_status.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,8 @@ static int status_handler(request_rec *r)
ap_rputs("</dl>", r);

if (is_async) {
int read_line = 0, write_completion = 0, lingering_close = 0, keep_alive = 0,
int read_line = 0, write_completion = 0,
pending = 0, keep_alive = 0, lingering_close = 0,
connections = 0, stopping = 0, procs = 0;
/*
* These differ from 'busy' and 'ready' in how gracefully finishing
Expand All @@ -574,13 +575,15 @@ static int status_handler(request_rec *r)
"<th colspan=\"3\">Async connections</th></tr>\n"
"<tr><th>total</th><th>accepting</th>"
"<th>busy</th><th>idle</th>"
"<th>reading</th><th>writing</th><th>keep-alive</th><th>closing</th></tr>\n", r);
"<th>reading</th><th>writing</th>"
"<th>pending</th><th>keep-alive</th><th>closing</th></tr>\n", r);
for (i = 0; i < server_limit; ++i) {
ps_record = ap_get_scoreboard_process(i);
if (ps_record->pid) {
connections += ps_record->connections;
read_line += ps_record->read_line;
write_completion += ps_record->write_completion;
pending += ps_record->pending;
keep_alive += ps_record->keep_alive;
lingering_close += ps_record->lingering_close;
busy_workers += thread_busy_buffer[i];
Expand All @@ -601,7 +604,8 @@ static int status_handler(request_rec *r)
"<td>%s%s</td>"
"<td>%u</td><td>%s</td>"
"<td>%u</td><td>%u</td>"
"<td>%u</td><td>%u</td><td>%u</td><td>%u</td>"
"<td>%u</td><td>%u</td>"
"<td>%u</td><td>%u</td><td>%u</td>"
"</tr>\n",
i, ps_record->pid,
dying, old,
Expand All @@ -611,6 +615,7 @@ static int status_handler(request_rec *r)
thread_idle_buffer[i],
ps_record->read_line,
ps_record->write_completion,
ps_record->pending,
ps_record->keep_alive,
ps_record->lingering_close);
}
Expand All @@ -621,12 +626,14 @@ static int status_handler(request_rec *r)
"<td>%d</td><td>%d</td>"
"<td>%d</td><td>&nbsp;</td>"
"<td>%d</td><td>%d</td>"
"<td>%d</td><td>%d</td><td>%d</td><td>%d</td>"
"<td>%d</td><td>%d</td>"
"<td>%d</td><td>%d</td><td>%d</td>"
"</tr>\n</table>\n",
procs, stopping,
connections,
busy_workers, idle_workers,
read_line, write_completion, keep_alive, lingering_close);
read_line, write_completion,
pending, keep_alive, lingering_close);
}
else {
ap_rprintf(r, "Processes: %d\n"
Expand All @@ -636,12 +643,14 @@ static int status_handler(request_rec *r)
"ConnsTotal: %d\n"
"ConnsAsyncReading: %d\n"
"ConnsAsyncWriting: %d\n"
"ConnsAsyncPending: %d\n"
"ConnsAsyncKeepAlive: %d\n"
"ConnsAsyncClosing: %d\n",
procs, stopping,
busy_workers, idle_workers,
connections,
read_line, write_completion, keep_alive, lingering_close);
read_line, write_completion,
pending, keep_alive, lingering_close);
}
}

Expand Down
8 changes: 8 additions & 0 deletions modules/lua/lua_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1264,10 +1264,18 @@ static int lua_ap_scoreboard_process(lua_State *L)
lua_pushnumber(L, ps_record->suspended);
lua_settable(L, -3);

lua_pushstring(L, "read_line");
lua_pushnumber(L, ps_record->read_line);
lua_settable(L, -3);

lua_pushstring(L, "write_completion");
lua_pushnumber(L, ps_record->write_completion);
lua_settable(L, -3);

lua_pushstring(L, "pending");
lua_pushnumber(L, ps_record->pending);
lua_settable(L, -3);

lua_pushstring(L, "not_accepting");
lua_pushnumber(L, ps_record->not_accepting);
lua_settable(L, -3);
Expand Down
Loading

0 comments on commit 57d5dc6

Please sign in to comment.