Commit a52920ce authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

h2load: Perform Sampling for client as well

parent 9cbb8174
......@@ -105,8 +105,9 @@ Stats::Stats(size_t req_todo, size_t nclients)
: req_todo(0), req_started(0), req_done(0), req_success(0),
req_status_success(0), req_failed(0), req_error(0), req_timedout(0),
bytes_total(0), bytes_head(0), bytes_head_decomp(0), bytes_body(0),
status(), client_stats(nclients) {
status() {
req_stats.reserve(std::min(req_todo, MAX_STATS));
client_stats.reserve(std::min(nclients, MAX_STATS));
}
Stream::Stream() : status_success(-1) {}
......@@ -288,7 +289,7 @@ void client_request_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
} // namespace
Client::Client(uint32_t id, Worker *worker, size_t req_todo)
: worker(worker), ssl(nullptr), next_addr(config.addrs),
: cstat{}, worker(worker), ssl(nullptr), next_addr(config.addrs),
current_addr(nullptr), reqidx(0), state(CLIENT_IDLE), req_todo(req_todo),
req_started(0), req_done(0), id(id), fd(-1),
new_connection_requested(false) {
......@@ -316,6 +317,12 @@ Client::~Client() {
if (ssl) {
SSL_free(ssl);
}
if (sampling_should_pick(worker->client_smp)) {
sampling_advance_point(worker->client_smp);
worker->sample_client_stat(&cstat);
}
++worker->client_smp.n;
}
int Client::do_read() { return readfn(*this); }
......@@ -655,7 +662,6 @@ void Client::on_stream_close(int32_t stream_id, bool success, bool final) {
if (success) {
req_stat->completed = true;
++worker->stats.req_success;
auto &cstat = worker->stats.client_stats[id];
++cstat.req_success;
if (streams[stream_id].status_success == 1) {
......@@ -1044,17 +1050,14 @@ void Client::record_request_time(RequestStat *req_stat) {
}
void Client::record_connect_start_time() {
auto &cstat = worker->stats.client_stats[id];
cstat.connect_start_time = std::chrono::steady_clock::now();
}
void Client::record_connect_time() {
auto &cstat = worker->stats.client_stats[id];
cstat.connect_time = std::chrono::steady_clock::now();
}
void Client::record_ttfb() {
auto &cstat = worker->stats.client_stats[id];
if (recorded(cstat.ttfb)) {
return;
}
......@@ -1063,16 +1066,12 @@ void Client::record_ttfb() {
}
void Client::clear_connect_times() {
auto &cstat = worker->stats.client_stats[id];
cstat.connect_start_time = std::chrono::steady_clock::time_point();
cstat.connect_time = std::chrono::steady_clock::time_point();
cstat.ttfb = std::chrono::steady_clock::time_point();
}
void Client::record_client_start_time() {
auto &cstat = worker->stats.client_stats[id];
// Record start time only once at the very first connection is going
// to be made.
if (recorded(cstat.client_start_time)) {
......@@ -1083,8 +1082,6 @@ void Client::record_client_start_time() {
}
void Client::record_client_end_time() {
auto &cstat = worker->stats.client_stats[id];
// Unlike client_start_time, we overwrite client_end_time. This
// handles multiple connect/disconnect for HTTP/1.1 benchmark.
cstat.client_end_time = std::chrono::steady_clock::now();
......@@ -1114,6 +1111,7 @@ Worker::Worker(uint32_t id, SSL_CTX *ssl_ctx, size_t req_todo, size_t nclients,
timeout_watcher.data = this;
sampling_init(request_times_smp, req_todo, MAX_STATS);
sampling_init(client_smp, nclients, MAX_STATS);
}
Worker::~Worker() {
......@@ -1151,6 +1149,11 @@ void Worker::sample_req_stat(RequestStat *req_stat) {
assert(stats.req_stats.size() <= MAX_STATS);
}
void Worker::sample_client_stat(ClientStat *cstat) {
stats.client_stats.push_back(*cstat);
assert(stats.client_stats.size() <= MAX_STATS);
}
void Worker::report_progress() {
if (id != 0 || config->is_rate_mode() || stats.req_done % progress_interval) {
return;
......
......@@ -222,6 +222,7 @@ struct Sampling {
struct Worker {
Stats stats;
Sampling request_times_smp;
Sampling client_smp;
struct ev_loop *loop;
SSL_CTX *ssl_ctx;
Config *config;
......@@ -247,6 +248,7 @@ struct Worker {
Worker(Worker &&o) = default;
void run();
void sample_req_stat(RequestStat *req_stat);
void sample_client_stat(ClientStat *cstat);
void report_progress();
void report_rate_progress();
};
......@@ -259,6 +261,7 @@ struct Stream {
struct Client {
std::unordered_map<int32_t, Stream> streams;
ClientStat cstat;
std::unique_ptr<Session> session;
ev_io wev;
ev_io rev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment