nghttpx: Fix affinity retry

This commit is contained in:
Tatsuhiro Tsujikawa 2017-11-04 15:46:47 +09:00
parent fa7945c627
commit 16e9036568
3 changed files with 38 additions and 9 deletions

View File

@ -1057,11 +1057,31 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
it = std::begin(affinity_hash); it = std::begin(affinity_hash);
} }
auto aff_idx = std::distance(std::begin(affinity_hash), it);
auto idx = (*it).idx; auto idx = (*it).idx;
auto addr = &shared_addr->addrs[idx];
auto &addr = shared_addr->addrs[idx]; if (addr->connect_blocker->blocked()) {
if (addr.proto == PROTO_HTTP2) { size_t i;
auto http2session = select_http2_session_with_affinity(group, &addr); for (i = aff_idx + 1; i != aff_idx; ++i) {
if (i == shared_addr->affinity_hash.size()) {
i = 0;
}
addr = &shared_addr->addrs[shared_addr->affinity_hash[i].idx];
if (addr->connect_blocker->blocked()) {
continue;
}
break;
}
if (i == aff_idx) {
err = -1;
return nullptr;
}
aff_idx = i;
}
if (addr->proto == PROTO_HTTP2) {
auto http2session = select_http2_session_with_affinity(group, addr);
auto dconn = make_unique<Http2DownstreamConnection>(http2session); auto dconn = make_unique<Http2DownstreamConnection>(http2session);
@ -1070,11 +1090,11 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
return std::move(dconn); return std::move(dconn);
} }
auto &dconn_pool = addr.dconn_pool; auto &dconn_pool = addr->dconn_pool;
auto dconn = dconn_pool->pop_downstream_connection(); auto dconn = dconn_pool->pop_downstream_connection();
if (!dconn) { if (!dconn) {
dconn = make_unique<HttpDownstreamConnection>(group, idx, conn_.loop, dconn = make_unique<HttpDownstreamConnection>(group, aff_idx, conn_.loop,
worker_); worker_);
} }

View File

@ -270,10 +270,16 @@ int HttpDownstreamConnection::initiate_connection() {
assert(addr->dns); assert(addr->dns);
} else { } else {
assert(addr_ == nullptr); assert(addr_ == nullptr);
addr = &addrs[next_downstream]; if (shared_addr->affinity.type == AFFINITY_NONE) {
addr = &addrs[next_downstream];
if (++next_downstream >= addrs.size()) { if (++next_downstream >= addrs.size()) {
next_downstream = 0; next_downstream = 0;
}
} else {
addr = &addrs[shared_addr->affinity_hash[next_downstream].idx];
if (++next_downstream >= shared_addr->affinity_hash.size()) {
next_downstream = 0;
}
} }
if (addr->proto != PROTO_HTTP1) { if (addr->proto != PROTO_HTTP1) {

View File

@ -108,6 +108,9 @@ private:
std::unique_ptr<DNSQuery> dns_query_; std::unique_ptr<DNSQuery> dns_query_;
IOControl ioctrl_; IOControl ioctrl_;
http_parser response_htp_; http_parser response_htp_;
// Index to backend address. If client affinity is enabled, it is
// the index to affinity_hash. Otherwise, it is the index to the
// backend addresses.
ssize_t initial_addr_idx_; ssize_t initial_addr_idx_;
// true if first write of reused connection succeeded. For // true if first write of reused connection succeeded. For
// convenience, this is initialized as true. // convenience, this is initialized as true.