nghttpx: Use memchunks for HTTP/2 backend

This commit is contained in:
Tatsuhiro Tsujikawa 2016-02-07 18:54:44 +09:00
parent 60c0c2dd56
commit 88eaeb5d1c
2 changed files with 22 additions and 33 deletions

View File

@ -57,6 +57,10 @@ const ev_tstamp CONNCHK_TIMEOUT = 5.;
const ev_tstamp CONNCHK_PING_TIMEOUT = 1.; const ev_tstamp CONNCHK_PING_TIMEOUT = 1.;
} // namespace } // namespace
namespace {
constexpr size_t MAX_BUFFER_SIZE = 32_k;
} // namespace
namespace { namespace {
void connchk_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) { void connchk_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
auto http2session = static_cast<Http2Session *>(w->data); auto http2session = static_cast<Http2Session *>(w->data);
@ -150,13 +154,12 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
get_config()->conn.downstream.timeout.read, {}, {}, writecb, readcb, get_config()->conn.downstream.timeout.read, {}, {}, writecb, readcb,
timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold, timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
get_config()->tls.dyn_rec.idle_timeout), get_config()->tls.dyn_rec.idle_timeout),
wb_(worker->get_mcpool()),
worker_(worker), worker_(worker),
connect_blocker_(connect_blocker), connect_blocker_(connect_blocker),
ssl_ctx_(ssl_ctx), ssl_ctx_(ssl_ctx),
addr_(nullptr), addr_(nullptr),
session_(nullptr), session_(nullptr),
data_pending_(nullptr),
data_pendinglen_(0),
group_(group), group_(group),
index_(idx), index_(idx),
state_(DISCONNECTED), state_(DISCONNECTED),
@ -528,11 +531,8 @@ int Http2Session::downstream_connect_proxy() {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
SSLOG(INFO, this) << "HTTP proxy request headers\n" << req; SSLOG(INFO, this) << "HTTP proxy request headers\n" << req;
} }
auto nwrite = wb_.write(req.c_str(), req.size()); wb_.append(req);
if (nwrite != req.size()) {
SSLOG(WARN, this) << "HTTP proxy request is too large";
return -1;
}
on_write_ = &Http2Session::noop; on_write_ = &Http2Session::noop;
signal_write(); signal_write();
@ -1446,19 +1446,6 @@ int Http2Session::downstream_read() {
} }
int Http2Session::downstream_write() { int Http2Session::downstream_write() {
if (data_pending_) {
auto n = std::min(wb_.wleft(), data_pendinglen_);
wb_.write(data_pending_, n);
if (n < data_pendinglen_) {
data_pending_ += n;
data_pendinglen_ -= n;
return 0;
}
data_pending_ = nullptr;
data_pendinglen_ = 0;
}
for (;;) { for (;;) {
const uint8_t *data; const uint8_t *data;
auto datalen = nghttp2_session_mem_send(session_, &data); auto datalen = nghttp2_session_mem_send(session_, &data);
@ -1471,11 +1458,10 @@ int Http2Session::downstream_write() {
if (datalen == 0) { if (datalen == 0) {
break; break;
} }
auto n = wb_.write(data, datalen); wb_.append(data, datalen);
if (n < static_cast<decltype(n)>(datalen)) {
data_pending_ = data + n; if (wb_.rleft() >= MAX_BUFFER_SIZE) {
data_pendinglen_ = datalen - n; break;
return 0;
} }
} }
@ -1700,9 +1686,12 @@ int Http2Session::read_clear() {
int Http2Session::write_clear() { int Http2Session::write_clear() {
ev_timer_again(conn_.loop, &conn_.rt); ev_timer_again(conn_.loop, &conn_.rt);
std::array<struct iovec, MAX_WR_IOVCNT> iov;
for (;;) { for (;;) {
if (wb_.rleft() > 0) { if (wb_.rleft() > 0) {
auto nwrite = conn_.write_clear(wb_.pos, wb_.rleft()); auto iovcnt = wb_.riovec(iov.data(), iov.size());
auto nwrite = conn_.writev_clear(iov.data(), iovcnt);
if (nwrite == 0) { if (nwrite == 0) {
return 0; return 0;
@ -1716,7 +1705,6 @@ int Http2Session::write_clear() {
continue; continue;
} }
wb_.reset();
if (on_write() != 0) { if (on_write() != 0) {
return -1; return -1;
} }
@ -1800,9 +1788,13 @@ int Http2Session::write_tls() {
ERR_clear_error(); ERR_clear_error();
struct iovec iov;
for (;;) { for (;;) {
if (wb_.rleft() > 0) { if (wb_.rleft() > 0) {
auto nwrite = conn_.write_tls(wb_.pos, wb_.rleft()); auto iovcnt = wb_.riovec(&iov, 1);
assert(iovcnt == 1);
auto nwrite = conn_.write_tls(iov.iov_base, iov.iov_len);
if (nwrite == 0) { if (nwrite == 0) {
return 0; return 0;
@ -1816,7 +1808,7 @@ int Http2Session::write_tls() {
continue; continue;
} }
wb_.reset();
if (on_write() != 0) { if (on_write() != 0) {
return -1; return -1;
} }

View File

@ -183,10 +183,10 @@ public:
}; };
using ReadBuf = Buffer<8_k>; using ReadBuf = Buffer<8_k>;
using WriteBuf = Buffer<32768>;
private: private:
Connection conn_; Connection conn_;
DefaultMemchunks wb_;
ev_timer settings_timer_; ev_timer settings_timer_;
// This timer has 2 purpose: when it first timeout, set // This timer has 2 purpose: when it first timeout, set
// connection_check_state_ = CONNECTION_CHECK_REQUIRED. After // connection_check_state_ = CONNECTION_CHECK_REQUIRED. After
@ -206,8 +206,6 @@ private:
// Address of remote endpoint // Address of remote endpoint
const DownstreamAddr *addr_; const DownstreamAddr *addr_;
nghttp2_session *session_; nghttp2_session *session_;
const uint8_t *data_pending_;
size_t data_pendinglen_;
size_t group_; size_t group_;
// index inside group, this is used to pin frontend to certain // index inside group, this is used to pin frontend to certain
// HTTP/2 backend for better throughput. // HTTP/2 backend for better throughput.
@ -215,7 +213,6 @@ private:
int state_; int state_;
int connection_check_state_; int connection_check_state_;
bool flow_control_; bool flow_control_;
WriteBuf wb_;
ReadBuf rb_; ReadBuf rb_;
}; };