nghttp: Refactor
This commit is contained in:
parent
f321ee5a61
commit
0f14c93fa4
|
@ -292,18 +292,18 @@ Headers::value_type *Request::get_req_header(int token) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Request::record_request_time() {
|
void Request::record_request_time() {
|
||||||
stat.stage = STAT_ON_REQUEST;
|
timing.state = RequestState::ON_REQUEST;
|
||||||
stat.on_request_time = get_time();
|
timing.on_request_time = get_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Request::record_response_time() {
|
void Request::record_response_time() {
|
||||||
stat.stage = STAT_ON_RESPONSE;
|
timing.state = RequestState::ON_RESPONSE;
|
||||||
stat.on_response_time = get_time();
|
timing.on_response_time = get_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Request::record_complete_time() {
|
void Request::record_complete_time() {
|
||||||
stat.stage = STAT_ON_COMPLETE;
|
timing.state = RequestState::ON_COMPLETE;
|
||||||
stat.on_complete_time = get_time();
|
timing.on_complete_time = get_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -452,7 +452,7 @@ HttpClient::HttpClient(const nghttp2_session_callbacks *callbacks,
|
||||||
struct ev_loop *loop, SSL_CTX *ssl_ctx)
|
struct ev_loop *loop, SSL_CTX *ssl_ctx)
|
||||||
: session(nullptr), callbacks(callbacks), loop(loop), ssl_ctx(ssl_ctx),
|
: session(nullptr), callbacks(callbacks), loop(loop), ssl_ctx(ssl_ctx),
|
||||||
ssl(nullptr), addrs(nullptr), next_addr(nullptr), cur_addr(nullptr),
|
ssl(nullptr), addrs(nullptr), next_addr(nullptr), cur_addr(nullptr),
|
||||||
complete(0), settings_payloadlen(0), state(STATE_IDLE),
|
complete(0), settings_payloadlen(0), state(ClientState::IDLE),
|
||||||
upgrade_response_status_code(0), fd(-1),
|
upgrade_response_status_code(0), fd(-1),
|
||||||
upgrade_response_complete(false) {
|
upgrade_response_complete(false) {
|
||||||
ev_io_init(&wev, writecb, 0, EV_WRITE);
|
ev_io_init(&wev, writecb, 0, EV_WRITE);
|
||||||
|
@ -589,7 +589,7 @@ int HttpClient::initiate_connection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::disconnect() {
|
void HttpClient::disconnect() {
|
||||||
state = STATE_IDLE;
|
state = ClientState::IDLE;
|
||||||
|
|
||||||
ev_timer_stop(loop, &settings_timer);
|
ev_timer_stop(loop, &settings_timer);
|
||||||
|
|
||||||
|
@ -686,13 +686,13 @@ int HttpClient::write_clear() {
|
||||||
int HttpClient::noop() { return 0; }
|
int HttpClient::noop() { return 0; }
|
||||||
|
|
||||||
void HttpClient::on_connect_fail() {
|
void HttpClient::on_connect_fail() {
|
||||||
if (state == STATE_IDLE) {
|
if (state == ClientState::IDLE) {
|
||||||
std::cerr << "[ERROR] Could not connect to the address "
|
std::cerr << "[ERROR] Could not connect to the address "
|
||||||
<< numeric_name(cur_addr) << std::endl;
|
<< numeric_name(cur_addr) << std::endl;
|
||||||
}
|
}
|
||||||
auto cur_state = state;
|
auto cur_state = state;
|
||||||
disconnect();
|
disconnect();
|
||||||
if (cur_state == STATE_IDLE) {
|
if (cur_state == ClientState::IDLE) {
|
||||||
if (initiate_connection() == 0) {
|
if (initiate_connection() == 0) {
|
||||||
std::cerr << "Trying next address " << numeric_name(cur_addr)
|
std::cerr << "Trying next address " << numeric_name(cur_addr)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
@ -711,7 +711,7 @@ int HttpClient::connected() {
|
||||||
}
|
}
|
||||||
|
|
||||||
record_connect_time();
|
record_connect_time();
|
||||||
state = STATE_CONNECTED;
|
state = ClientState::CONNECTED;
|
||||||
|
|
||||||
ev_io_start(loop, &rev);
|
ev_io_start(loop, &rev);
|
||||||
ev_io_stop(loop, &wev);
|
ev_io_stop(loop, &wev);
|
||||||
|
@ -1239,19 +1239,19 @@ bool HttpClient::add_request(const std::string &uri,
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::record_handshake_time() {
|
void HttpClient::record_handshake_time() {
|
||||||
stat.on_handshake_time = get_time();
|
timing.on_handshake_time = get_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::record_started_time() {
|
void HttpClient::record_started_time() {
|
||||||
stat.started_system_time = std::chrono::system_clock::now();
|
timing.started_system_time = std::chrono::system_clock::now();
|
||||||
stat.on_started_time = get_time();
|
timing.on_started_time = get_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::record_dns_complete_time() {
|
void HttpClient::record_dns_complete_time() {
|
||||||
stat.on_dns_complete_time = get_time();
|
timing.on_dns_complete_time = get_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::record_connect_time() { stat.on_connect_time = get_time(); }
|
void HttpClient::record_connect_time() { timing.on_connect_time = get_time(); }
|
||||||
|
|
||||||
void HttpClient::on_request(Request *req) {
|
void HttpClient::on_request(Request *req) {
|
||||||
if (req->pri == 0 && req->dep) {
|
if (req->pri == 0 && req->dep) {
|
||||||
|
@ -1310,7 +1310,7 @@ void HttpClient::output_har(FILE *outfile) {
|
||||||
|
|
||||||
json_object_set_new(
|
json_object_set_new(
|
||||||
page, "startedDateTime",
|
page, "startedDateTime",
|
||||||
json_string(util::format_iso8601(stat.started_system_time).c_str()));
|
json_string(util::format_iso8601(timing.started_system_time).c_str()));
|
||||||
json_object_set_new(page, "id", json_string(PAGE_ID));
|
json_object_set_new(page, "id", json_string(PAGE_ID));
|
||||||
json_object_set_new(page, "title", json_string(""));
|
json_object_set_new(page, "title", json_string(""));
|
||||||
|
|
||||||
|
@ -1321,45 +1321,45 @@ void HttpClient::output_har(FILE *outfile) {
|
||||||
|
|
||||||
auto dns_delta =
|
auto dns_delta =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
stat.on_dns_complete_time - stat.on_started_time).count() /
|
timing.on_dns_complete_time - timing.on_started_time).count() /
|
||||||
1000.0;
|
1000.0;
|
||||||
auto connect_delta =
|
auto connect_delta =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
stat.on_connect_time - stat.on_dns_complete_time).count() /
|
timing.on_connect_time - timing.on_dns_complete_time).count() /
|
||||||
1000.0;
|
1000.0;
|
||||||
|
|
||||||
for (size_t i = 0; i < reqvec.size(); ++i) {
|
for (size_t i = 0; i < reqvec.size(); ++i) {
|
||||||
auto &req = reqvec[i];
|
auto &req = reqvec[i];
|
||||||
|
|
||||||
if (req->stat.stage != STAT_ON_COMPLETE) {
|
if (req->timing.state != RequestState::ON_COMPLETE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto entry = json_object();
|
auto entry = json_object();
|
||||||
json_array_append_new(entries, entry);
|
json_array_append_new(entries, entry);
|
||||||
|
|
||||||
auto &req_stat = req->stat;
|
auto &req_timing = req->timing;
|
||||||
auto request_time =
|
auto request_time =
|
||||||
(i == 0) ? stat.started_system_time
|
(i == 0) ? timing.started_system_time
|
||||||
: stat.started_system_time +
|
: timing.started_system_time +
|
||||||
std::chrono::duration_cast<
|
std::chrono::duration_cast<
|
||||||
std::chrono::system_clock::duration>(
|
std::chrono::system_clock::duration>(
|
||||||
req_stat.on_request_time - stat.on_started_time);
|
req_timing.on_request_time - timing.on_started_time);
|
||||||
|
|
||||||
auto wait_delta =
|
auto wait_delta =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
req_stat.on_response_time - req_stat.on_request_time).count() /
|
req_timing.on_response_time - req_timing.on_request_time).count() /
|
||||||
1000.0;
|
1000.0;
|
||||||
auto receive_delta =
|
auto receive_delta =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
req_stat.on_complete_time - req_stat.on_response_time).count() /
|
req_timing.on_complete_time - req_timing.on_response_time).count() /
|
||||||
1000.0;
|
1000.0;
|
||||||
|
|
||||||
auto time_sum =
|
auto time_sum =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
(i == 0) ? (req_stat.on_complete_time - stat.on_started_time)
|
(i == 0) ? (req_timing.on_complete_time - timing.on_started_time)
|
||||||
: (req_stat.on_complete_time - req_stat.on_request_time))
|
: (req_timing.on_complete_time -
|
||||||
.count() /
|
req_timing.on_request_time)).count() /
|
||||||
1000.0;
|
1000.0;
|
||||||
|
|
||||||
json_object_set_new(
|
json_object_set_new(
|
||||||
|
@ -1865,20 +1865,20 @@ void print_stats(const HttpClient &client) {
|
||||||
std::cout << "#" << ++i << ": " << req->uri << std::endl;
|
std::cout << "#" << ++i << ": " << req->uri << std::endl;
|
||||||
std::cout << " Status: " << req->status << std::endl;
|
std::cout << " Status: " << req->status << std::endl;
|
||||||
std::cout << " Delta (ms) from handshake(HEADERS):" << std::endl;
|
std::cout << " Delta (ms) from handshake(HEADERS):" << std::endl;
|
||||||
if (req->stat.stage >= STAT_ON_RESPONSE) {
|
if (req->timing.state >= RequestState::ON_RESPONSE) {
|
||||||
std::cout << " response HEADERS: "
|
std::cout << " response HEADERS: "
|
||||||
<< time_delta(req->stat.on_response_time,
|
<< time_delta(req->timing.on_response_time,
|
||||||
client.stat.on_handshake_time).count() << "("
|
client.timing.on_handshake_time).count() << "("
|
||||||
<< time_delta(req->stat.on_response_time,
|
<< time_delta(req->timing.on_response_time,
|
||||||
req->stat.on_request_time).count() << ")"
|
req->timing.on_request_time).count() << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
if (req->stat.stage >= STAT_ON_COMPLETE) {
|
if (req->timing.state >= RequestState::ON_COMPLETE) {
|
||||||
std::cout << " Completed: "
|
std::cout << " Completed: "
|
||||||
<< time_delta(req->stat.on_complete_time,
|
<< time_delta(req->timing.on_complete_time,
|
||||||
client.stat.on_handshake_time).count() << "("
|
client.timing.on_handshake_time).count() << "("
|
||||||
<< time_delta(req->stat.on_complete_time,
|
<< time_delta(req->timing.on_complete_time,
|
||||||
req->stat.on_request_time).count() << ")"
|
req->timing.on_request_time).count() << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
23
src/nghttp.h
23
src/nghttp.h
|
@ -85,19 +85,14 @@ struct Config {
|
||||||
bool dep_idle;
|
bool dep_idle;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum StatStage {
|
enum class RequestState { INITIAL, ON_REQUEST, ON_RESPONSE, ON_COMPLETE };
|
||||||
STAT_INITIAL,
|
|
||||||
STAT_ON_REQUEST,
|
|
||||||
STAT_ON_RESPONSE,
|
|
||||||
STAT_ON_COMPLETE
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RequestStat {
|
struct RequestTiming {
|
||||||
std::chrono::steady_clock::time_point on_request_time;
|
std::chrono::steady_clock::time_point on_request_time;
|
||||||
std::chrono::steady_clock::time_point on_response_time;
|
std::chrono::steady_clock::time_point on_response_time;
|
||||||
std::chrono::steady_clock::time_point on_complete_time;
|
std::chrono::steady_clock::time_point on_complete_time;
|
||||||
StatStage stage;
|
RequestState state;
|
||||||
RequestStat() : stage(STAT_INITIAL) {}
|
RequestTiming() : state(RequestState::INITIAL) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Request;
|
struct Request;
|
||||||
|
@ -144,7 +139,7 @@ struct Request {
|
||||||
http_parser_url u;
|
http_parser_url u;
|
||||||
std::shared_ptr<Dependency> dep;
|
std::shared_ptr<Dependency> dep;
|
||||||
nghttp2_priority_spec pri_spec;
|
nghttp2_priority_spec pri_spec;
|
||||||
RequestStat stat;
|
RequestTiming timing;
|
||||||
int64_t data_length;
|
int64_t data_length;
|
||||||
int64_t data_offset;
|
int64_t data_offset;
|
||||||
// Number of bytes received from server
|
// Number of bytes received from server
|
||||||
|
@ -164,7 +159,7 @@ struct Request {
|
||||||
bool expect_final_response;
|
bool expect_final_response;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SessionStat {
|
struct SessionTiming {
|
||||||
// The point in time when download was started.
|
// The point in time when download was started.
|
||||||
std::chrono::system_clock::time_point started_system_time;
|
std::chrono::system_clock::time_point started_system_time;
|
||||||
// The point of time when download was started.
|
// The point of time when download was started.
|
||||||
|
@ -178,7 +173,7 @@ struct SessionStat {
|
||||||
std::chrono::steady_clock::time_point on_handshake_time;
|
std::chrono::steady_clock::time_point on_handshake_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum client_state { STATE_IDLE, STATE_CONNECTED };
|
enum class ClientState { IDLE, CONNECTED };
|
||||||
|
|
||||||
struct HttpClient {
|
struct HttpClient {
|
||||||
HttpClient(const nghttp2_session_callbacks *callbacks, struct ev_loop *loop,
|
HttpClient(const nghttp2_session_callbacks *callbacks, struct ev_loop *loop,
|
||||||
|
@ -238,7 +233,7 @@ struct HttpClient {
|
||||||
std::string hostport;
|
std::string hostport;
|
||||||
// Used for parse the HTTP upgrade response from server
|
// Used for parse the HTTP upgrade response from server
|
||||||
std::unique_ptr<http_parser> htp;
|
std::unique_ptr<http_parser> htp;
|
||||||
SessionStat stat;
|
SessionTiming timing;
|
||||||
ev_io wev;
|
ev_io wev;
|
||||||
ev_io rev;
|
ev_io rev;
|
||||||
ev_timer wt;
|
ev_timer wt;
|
||||||
|
@ -259,7 +254,7 @@ struct HttpClient {
|
||||||
size_t complete;
|
size_t complete;
|
||||||
// The length of settings_payload
|
// The length of settings_payload
|
||||||
size_t settings_payloadlen;
|
size_t settings_payloadlen;
|
||||||
client_state state;
|
ClientState state;
|
||||||
// The HTTP status code of the response message of HTTP Upgrade.
|
// The HTTP status code of the response message of HTTP Upgrade.
|
||||||
unsigned int upgrade_response_status_code;
|
unsigned int upgrade_response_status_code;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
Loading…
Reference in New Issue