h2load: Explicitly count the number of requests left and inflight

This commit is contained in:
Tatsuhiro Tsujikawa 2017-01-26 00:16:12 +09:00
parent 712b08e8ed
commit 7e6eb7e02a
3 changed files with 34 additions and 37 deletions

View File

@ -269,9 +269,7 @@ void conn_timeout_cb(EV_P_ ev_timer *w, int revents) {
namespace {
bool check_stop_client_request_timeout(Client *client, ev_timer *w) {
auto nreq = client->req_todo - client->req_started;
if (nreq == 0 ||
if (client->req_left == 0 ||
client->streams.size() >= client->session->max_concurrent_streams()) {
// no more requests to make, stop timer
ev_timer_stop(client->worker->loop, w);
@ -330,6 +328,8 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo)
reqidx(0),
state(CLIENT_IDLE),
req_todo(req_todo),
req_left(req_todo),
req_inflight(0),
req_started(0),
req_done(0),
id(id),
@ -467,16 +467,13 @@ int Client::try_again_or_fail() {
if (new_connection_requested) {
new_connection_requested = false;
if (req_started < req_todo) {
if (req_left) {
// At the moment, we don't have a facility to re-start request
// already in in-flight. Make them fail.
auto req_abandoned = req_started - req_done;
worker->stats.req_failed += req_inflight;
worker->stats.req_error += req_inflight;
worker->stats.req_failed += req_abandoned;
worker->stats.req_error += req_abandoned;
worker->stats.req_done += req_abandoned;
req_done = req_started;
req_inflight = 0;
// Keep using current address
if (connect() == 0) {
@ -528,16 +525,18 @@ void Client::disconnect() {
}
int Client::submit_request() {
++worker->stats.req_started;
if (session->submit_request() != 0) {
return -1;
}
++worker->stats.req_started;
--req_left;
++req_started;
++req_inflight;
// if an active timeout is set and this is the last request to be submitted
// on this connection, start the active timeout.
if (worker->config->conn_active_timeout > 0. && req_started >= req_todo) {
if (worker->config->conn_active_timeout > 0. && req_left == 0) {
ev_timer_start(worker->loop, &conn_active_watcher);
}
@ -551,34 +550,29 @@ void Client::process_timedout_streams() {
}
}
auto req_timed_out = req_todo - req_done;
worker->stats.req_timedout += req_timed_out;
worker->stats.req_timedout += req_inflight;
process_abandoned_streams();
}
void Client::process_abandoned_streams() {
auto req_abandoned = req_todo - req_done;
auto req_abandoned = req_inflight + req_left;
worker->stats.req_failed += req_abandoned;
worker->stats.req_error += req_abandoned;
worker->stats.req_done += req_abandoned;
req_done = req_todo;
req_inflight = 0;
req_left = 0;
}
void Client::process_request_failure() {
auto req_abandoned = req_todo - req_started;
worker->stats.req_failed += req_left;
worker->stats.req_error += req_left;
worker->stats.req_failed += req_abandoned;
worker->stats.req_error += req_abandoned;
worker->stats.req_done += req_abandoned;
req_left = 0;
req_done += req_abandoned;
if (req_done == req_todo) {
if (req_inflight == 0) {
terminate_session();
return;
}
}
@ -711,6 +705,9 @@ void Client::on_status_code(int32_t stream_id, uint16_t status) {
}
void Client::on_stream_close(int32_t stream_id, bool success, bool final) {
++req_done;
--req_inflight;
auto req_stat = get_req_stat(stream_id);
if (!req_stat) {
return;
@ -741,23 +738,19 @@ void Client::on_stream_close(int32_t stream_id, bool success, bool final) {
}
++worker->stats.req_done;
++req_done;
worker->report_progress();
streams.erase(stream_id);
if (req_done == req_todo) {
if (req_left == 0 && req_inflight == 0) {
terminate_session();
return;
}
if (!config.timing_script && !final) {
if (req_started < req_todo) {
if (submit_request() != 0) {
if (!config.timing_script && !final && req_left > 0 &&
submit_request() != 0) {
process_request_failure();
}
return;
}
}
}
RequestStat *Client::get_req_stat(int32_t stream_id) {
@ -871,8 +864,7 @@ int Client::connection_made() {
record_connect_time();
if (!config.timing_script) {
auto nreq =
std::min(req_todo - req_started, session->max_concurrent_streams());
auto nreq = std::min(req_left, session->max_concurrent_streams());
for (; nreq > 0; --nreq) {
if (submit_request() != 0) {
process_request_failure();

View File

@ -292,6 +292,11 @@ struct Client {
ClientState state;
// The number of requests this client has to issue.
size_t req_todo;
// The number of requests left to issue
size_t req_left;
// The number of requests currently have started, but not abandoned
// or finished.
size_t req_inflight;
// The number of requests this client has issued so far.
size_t req_started;
// The number of requests this client has done so far.

View File

@ -100,7 +100,7 @@ int htp_msg_completecb(http_parser *htp) {
http_parser_pause(htp, 1);
// Connection is going down. If we have still request to do,
// create new connection and keep on doing the job.
if (client->req_started < client->req_todo) {
if (client->req_left) {
client->try_new_connection();
}