nghttpx: Use memchunks for HTTP/2 backend
This commit is contained in:
parent
60c0c2dd56
commit
88eaeb5d1c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue