This is an automated email from the ASF dual-hosted git repository.
cmcfarlen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 2456d4c21b hostdb: remove latency with cache misses (#11764)
2456d4c21b is described below
commit 2456d4c21b4bcc47d8341f6845588959b1da2896
Author: Chris McFarlen <[email protected]>
AuthorDate: Mon Sep 16 14:58:55 2024 -0500
hostdb: remove latency with cache misses (#11764)
Co-authored-by: Chris McFarlen <[email protected]>
---
src/iocore/hostdb/HostDB.cc | 111 +++++++++++++++++++---------------
src/iocore/hostdb/P_HostDBProcessor.h | 35 +++++------
2 files changed, 79 insertions(+), 67 deletions(-)
diff --git a/src/iocore/hostdb/HostDB.cc b/src/iocore/hostdb/HostDB.cc
index c5d593a381..361f79e83d 100644
--- a/src/iocore/hostdb/HostDB.cc
+++ b/src/iocore/hostdb/HostDB.cc
@@ -489,6 +489,38 @@ db_mark_for(IpAddr const &ip)
return ip.isIp6() ? HOSTDB_MARK_IPV6 : HOSTDB_MARK_IPV4;
}
+HostDBRecord::Handle
+probe_ip(HostDBHash const &hash)
+{
+ HostDBRecord::Handle result;
+
+ if (hash.is_byname()) {
+ Dbg(dbg_ctl_hostdb, "DNS %.*s", int(hash.host_name.size()),
hash.host_name.data());
+ IpAddr tip;
+ if (0 == tip.load(hash.host_name)) {
+ result =
HostDBRecord::Handle{HostDBRecord::alloc(hash.host_name, 1)};
+ result->af_family = tip.family();
+ auto &info = result->rr_info()[0];
+ info.assign(tip);
+ }
+ }
+
+ return result;
+}
+
+HostDBRecord::Handle
+probe_hostfile(HostDBHash const &hash)
+{
+ HostDBRecord::Handle result;
+ // Check if this can be fulfilled by the host file
+ //
+ if (auto static_hosts = hostDB.acquire_host_file(); static_hosts) {
+ result = static_hosts->lookup(hash);
+ }
+
+ return result;
+}
+
HostDBRecord::Handle
probe(HostDBHash const &hash, bool ignore_timeout)
{
@@ -511,6 +543,10 @@ probe(HostDBHash const &hash, bool ignore_timeout)
record = hostDB.refcountcache->get(folded_hash);
// If there was nothing in the cache-- this is a miss
if (record.get() == nullptr) {
+ record = probe_ip(hash);
+ if (!record) {
+ record = probe_hostfile(hash);
+ }
return record;
}
@@ -555,9 +591,10 @@ probe(HostDBHash const &hash, bool ignore_timeout)
Action *
HostDBProcessor::getby(Continuation *cont, cb_process_result_pfn
cb_process_result, HostDBHash &hash, Options const &opt)
{
- bool force_dns = false;
- EThread *thread = this_ethread();
- Ptr<ProxyMutex> mutex = thread->mutex;
+ bool force_dns = false;
+ bool delay_reschedule = false;
+ EThread *thread = this_ethread();
+ Ptr<ProxyMutex> mutex = thread->mutex;
ip_text_buffer ipb;
if (opt.flags & HOSTDB_FORCE_DNS_ALWAYS) {
@@ -579,6 +616,7 @@ HostDBProcessor::getby(Continuation *cont,
cb_process_result_pfn cb_process_resu
} else {
MUTEX_TRY_LOCK(lock, cont->mutex, thread);
if (!lock.is_locked()) {
+ delay_reschedule = true;
goto Lretry;
}
cont->handleEvent(EVENT_HOST_DB_LOOKUP, nullptr);
@@ -650,7 +688,11 @@ Lretry:
c->init(hash, copt);
SET_CONTINUATION_HANDLER(c, &HostDBContinuation::probeEvent);
- c->timeout = thread->schedule_in(c, MUTEX_RETRY_DELAY);
+ if (delay_reschedule) {
+ c->timeout = thread->schedule_in(c, MUTEX_RETRY_DELAY);
+ } else {
+ thread->schedule_imm(c);
+ }
return &c->action;
}
@@ -784,9 +826,9 @@ HostDBContinuation::lookup_done(TextView query_name,
ts_seconds answer_ttl, SRVH
{
ink_assert(record);
if (query_name.empty()) {
- if (is_byname()) {
+ if (hash.is_byname()) {
Dbg(dbg_ctl_hostdb, "lookup_done() failed for '%.*s'",
int(hash.host_name.size()), hash.host_name.data());
- } else if (is_srv()) {
+ } else if (hash.is_srv()) {
Dbg(dbg_ctl_dns_srv, "SRV failed for '%.*s'",
int(hash.host_name.size()), hash.host_name.data());
} else {
ip_text_buffer b;
@@ -795,9 +837,9 @@ HostDBContinuation::lookup_done(TextView query_name,
ts_seconds answer_ttl, SRVH
record->ip_timestamp = hostdb_current_timestamp;
record->ip_timeout_interval =
ts_seconds(std::clamp(hostdb_ip_fail_timeout_interval, 1u, HOST_DB_MAX_TTL));
- if (is_srv()) {
+ if (hash.is_srv()) {
record->record_type = HostDBType::SRV;
- } else if (!is_byname()) {
+ } else if (!hash.is_byname()) {
record->record_type = HostDBType::HOST;
}
@@ -829,9 +871,9 @@ HostDBContinuation::lookup_done(TextView query_name,
ts_seconds answer_ttl, SRVH
record->ip_timestamp = hostdb_current_timestamp;
record->ip_timeout_interval = std::clamp(answer_ttl, ts_seconds(1),
ts_seconds(HOST_DB_MAX_TTL));
- if (is_byname()) {
+ if (hash.is_byname()) {
Dbg_bw(dbg_ctl_hostdb, "done {} TTL {}", hash.host_name, answer_ttl);
- } else if (is_srv()) {
+ } else if (hash.is_srv()) {
ink_assert(srv && srv->hosts.size() && srv->hosts.size() <=
hostdb_round_robin_max_count);
record->record_type = HostDBType::SRV;
@@ -935,7 +977,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
// Find the first record and total number of records.
if (!failed) {
- if (is_srv()) {
+ if (hash.is_srv()) {
valid_records = e->srv_hosts.hosts.size();
} else {
void *ptr; // tmp for current entry.
@@ -978,9 +1020,9 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
if (failed && old_r && old_r->serve_stale_but_revalidate()) {
r = old_r;
serve_stale = true;
- } else if (is_byname()) {
+ } else if (hash.is_byname()) {
lookup_done(hash.host_name, ttl, failed ? nullptr : &e->srv_hosts, r);
- } else if (is_srv()) {
+ } else if (hash.is_srv()) {
lookup_done(hash.host_name, /* hostname */
ttl, /* ttl in seconds */
failed ? nullptr : &e->srv_hosts, r);
@@ -993,7 +1035,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
if (!failed) { // implies r != old_r
auto rr_info = r->rr_info();
// Fill in record type specific data.
- if (is_srv()) {
+ if (hash.is_srv()) {
char *pos = rr_info.rebind<char>().end();
SRV *q[valid_records];
ink_assert(valid_records <= (int)hostdb_round_robin_max_count);
@@ -1067,7 +1109,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
if (action.continuation->mutex) {
ink_release_assert(action.continuation->mutex == action.mutex);
}
- reply_to_cont(action.continuation, r.get(), is_srv());
+ reply_to_cont(action.continuation, r.get(), hash.is_srv());
}
need_to_reschedule = false;
}
@@ -1190,14 +1232,14 @@ HostDBContinuation::probeEvent(int /* event ATS_UNUSED
*/, Event *e)
if (!force_dns) {
// Do the probe
//
- Ptr<HostDBRecord> r = probe(hash, false);
+ HostDBRecord::Handle r = probe(hash, false);
if (r) {
Metrics::Counter::increment(hostdb_rsb.total_hits);
}
if (action.continuation && r) {
- reply_to_cont(action.continuation, r.get(), is_srv());
+ reply_to_cont(action.continuation, r.get(), hash.is_srv());
}
// If it succeeds or it was a remote probe, we are done
@@ -1283,37 +1325,6 @@ void
HostDBContinuation::do_dns()
{
ink_assert(!action.cancelled);
- if (is_byname()) {
- Dbg(dbg_ctl_hostdb, "DNS %.*s", int(hash.host_name.size()),
hash.host_name.data());
- IpAddr tip;
- if (0 == tip.load(hash.host_name)) {
- // Need to consider if this is necessary - could the record in
ResolveInfo be left null and
- // just the resolved address set?
- if (action.continuation) {
- HostDBRecord::Handle r{HostDBRecord::alloc(hash.host_name, 1)};
- r->af_family = tip.family();
- auto &info = r->rr_info()[0];
- info.assign(tip);
- // tricksy - @a reply_to_cont must use an intrusive pointer to @a r if
it needs to persist
- // @a r doesn't go out of scope until after this returns. This
continuation shares the mutex
- // of the target continuation therefore this is always dispatched
synchronously.
- reply_to_cont(action.continuation, r.get());
- }
- hostdb_cont_free(this);
- return;
- }
- }
-
- // Check if this can be fulfilled by the host file
- if (auto static_hosts = hostDB.acquire_host_file(); static_hosts) {
- if (auto r = static_hosts->lookup(hash); r && action.continuation) {
- // Set the TTL based on how often we stat() the host file
- r = lookup_done(r->name_view(), static_hosts->ttl, nullptr, r);
- reply_to_cont(action.continuation, r.get());
- hostdb_cont_free(this);
- return;
- }
- }
if (hostdb_lookup_timeout) {
EThread *thread = this_ethread();
@@ -1326,12 +1337,12 @@ HostDBContinuation::do_dns()
opt.timeout = dns_lookup_timeout;
opt.host_res_style = host_res_style_for(hash.db_mark);
SET_HANDLER(&HostDBContinuation::dnsEvent);
- if (is_byname()) {
+ if (hash.is_byname()) {
if (hash.dns_server) {
opt.handler = hash.dns_server->x_dnsH;
}
pending_action = dnsProcessor.gethostbyname(this, hash.host_name, opt);
- } else if (is_srv()) {
+ } else if (hash.is_srv()) {
Dbg(dbg_ctl_dns_srv, "SRV lookup of %.*s", int(hash.host_name.size()),
hash.host_name.data());
pending_action = dnsProcessor.getSRVbyname(this, hash.host_name, opt);
} else {
diff --git a/src/iocore/hostdb/P_HostDBProcessor.h
b/src/iocore/hostdb/P_HostDBProcessor.h
index e93812cfc1..9b6d4c9547 100644
--- a/src/iocore/hostdb/P_HostDBProcessor.h
+++ b/src/iocore/hostdb/P_HostDBProcessor.h
@@ -197,6 +197,24 @@ struct HostDBHash {
{
return this->set_host(swoc::TextView{name, strlen(name)});
}
+
+ bool
+ is_byname() const
+ {
+ return db_mark == HOSTDB_MARK_IPV4 || db_mark == HOSTDB_MARK_IPV6;
+ }
+
+ bool
+ is_srv() const
+ {
+ return db_mark == HOSTDB_MARK_SRV;
+ }
+
+ bool
+ is_reverse() const
+ {
+ return !is_byname() && !is_srv();
+ }
};
//
@@ -239,23 +257,6 @@ struct HostDBContinuation : public Continuation {
/// Recompute the hash and update ancillary values.
void refresh_hash();
void do_dns();
- bool
- is_byname()
- {
- return hash.db_mark == HOSTDB_MARK_IPV4 || hash.db_mark ==
HOSTDB_MARK_IPV6;
- }
- bool
- is_srv()
- {
- return hash.db_mark == HOSTDB_MARK_SRV;
- }
-
- bool
- is_reverse()
- {
- return !is_byname() && !is_srv();
- }
-
Ptr<HostDBRecord>
lookup_done(const char *query_name, ts_seconds answer_ttl, SRVHosts *s =
nullptr, Ptr<HostDBRecord> record = Ptr<HostDBRecord>{})
{