Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Unified Diff: net/base/async_host_resolver.cc

Issue 7466031: AsyncHostResolver: integrated HostCache, temporarily, until we have RR cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed comment. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/base/async_host_resolver.cc
diff --git a/net/base/async_host_resolver.cc b/net/base/async_host_resolver.cc
index 8aa98181d15edef092bdc76e39110738721a76a8..e00f342d3bcc568b056f015cb1b59a76b84a834c 100644
--- a/net/base/async_host_resolver.cc
+++ b/net/base/async_host_resolver.cc
@@ -66,6 +66,17 @@ class RequestParameters : public NetLog::EventParameters {
const NetLog::Source source_;
};
+HostCache* CreateDefaultCache() {
cbentzel 2011/07/21 15:31:10 This should be shared with the one in host_resolve
agayev 2011/07/21 17:48:03 Done.
+ static const size_t kMaxHostCacheEntries = 100;
+
+ HostCache* cache = new HostCache(
+ kMaxHostCacheEntries,
+ base::TimeDelta::FromMinutes(1),
+ base::TimeDelta::FromSeconds(0)); // Disable caching of failed DNS.
+
+ return cache;
+}
+
} // namespace
HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves,
@@ -80,6 +91,7 @@ HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves,
max_transactions,
max_pending_requests,
base::Bind(&base::RandInt),
+ CreateDefaultCache(),
NULL,
net_log);
return resolver;
@@ -111,7 +123,7 @@ class AsyncHostResolver::Request {
RequestPriority priority() const { return info_.priority(); }
const BoundNetLog& source_net_log() const { return source_net_log_; }
const BoundNetLog& request_net_log() const { return request_net_log_; }
- const AddressList* addresses() const { return addresses_; }
+ void set_addresses(const AddressList& addresses) { *addresses_ = addresses; }
void OnComplete(int result, const IPAddressList& ip_addresses) {
DCHECK(callback_);
@@ -136,22 +148,31 @@ AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server,
size_t max_transactions,
size_t max_pending_requests,
const RandIntCallback& rand_int_cb,
+ HostCache* cache,
ClientSocketFactory* factory,
NetLog* net_log)
: max_transactions_(max_transactions),
max_pending_requests_(max_pending_requests),
dns_server_(dns_server),
rand_int_cb_(rand_int_cb),
+ cache_(cache),
factory_(factory),
next_request_id_(0),
net_log_(net_log) {
}
AsyncHostResolver::~AsyncHostResolver() {
+ // Destroy request lists.
for (KeyRequestListMap::iterator it = requestlist_map_.begin();
it != requestlist_map_.end(); ++it)
STLDeleteElements(&it->second);
+
+ // Destroy transactions.
STLDeleteElements(&transactions_);
+
+ // Destroy pending requests.
+ for (size_t i = 0; i < arraysize(pending_requests_); ++i)
+ STLDeleteElements(&pending_requests_[i]);
}
int AsyncHostResolver::Resolve(const RequestInfo& info,
@@ -160,7 +181,6 @@ int AsyncHostResolver::Resolve(const RequestInfo& info,
RequestHandle* out_req,
const BoundNetLog& source_net_log) {
DCHECK(addresses);
-
IPAddressNumber ip_number;
std::string dns_name;
int rv = ERR_UNEXPECTED;
@@ -170,22 +190,26 @@ int AsyncHostResolver::Resolve(const RequestInfo& info,
rv = ResolveAsIp(info, ip_number, addresses);
else if (!DNSDomainFromDot(info.hostname(), &dns_name))
rv = ERR_NAME_NOT_RESOLVED;
- else if (info.only_use_cached_response()) // TODO(agayev): support caching
- rv = ERR_NAME_NOT_RESOLVED;
Request* request = CreateNewRequest(
info, dns_name, callback, addresses, source_net_log);
OnStart(request);
+ if (rv == ERR_UNEXPECTED) {
+ if (ServeFromCache(request))
+ rv = OK;
+ else if (info.only_use_cached_response())
+ rv = ERR_NAME_NOT_RESOLVED;
+ }
+
if (rv != ERR_UNEXPECTED) {
OnFinish(request, rv);
delete request;
- return rv;
+ return rv; // Synchronous resolution ends here.
}
if (out_req)
*out_req = reinterpret_cast<RequestHandle>(request);
-
if (AttachToRequestList(request))
return ERR_IO_PENDING;
if (transactions_.size() < max_transactions_)
@@ -279,7 +303,6 @@ void AsyncHostResolver::OnTransactionComplete(
int result,
const DnsTransaction* transaction,
const IPAddressList& ip_addresses) {
-
DCHECK(std::find(transactions_.begin(), transactions_.end(), transaction)
!= transactions_.end());
DCHECK(requestlist_map_.find(transaction->key()) != requestlist_map_.end());
@@ -294,6 +317,27 @@ void AsyncHostResolver::OnTransactionComplete(
request->OnComplete(result, ip_addresses);
}
+ // It is possible that the requests that caused |transaction| to be
+ // created are cancelled by the time |transaction| completes. In that
+ // case |requests| would be empty. We are knowingly throwing away the
+ // result of a DNS resolution in that case, because (a) if there are no
+ // requests, we do not have info to obtain a key from, (b) DnsTransaction
+ // does not have info(), adding one into it just temporarily doesn't make
+ // sense, since HostCache will be replaced with RR cache soon, (c)
+ // recreating info from DnsTransaction::Key adds a lot of temporary
cbentzel 2011/07/21 15:31:10 It seems like it should still be possible to cache
agayev 2011/07/21 17:48:03 Well, it doesn't have host_resolver_flags, whose u
cbentzel 2011/07/21 18:22:15 Yes, I agree that's how it would be done. I think
+ // code/functions (like converting back from qtype to AddressFamily.)
+ // Also, we only cache positive results. All of this will change when RR
+ // cache is added.
+ if (result == OK && cache_.get() && !requests.empty()) {
+ Request* request = requests.front();
+ HostResolver::RequestInfo info = request->info();
+ HostCache::Key key(
+ info.hostname(), info.address_family(), info.host_resolver_flags());
+ AddressList addrlist =
+ AddressList::CreateFromIPAddressList(ip_addresses, info.port());
+ cache_->Set(key, result, addrlist, base::TimeTicks::Now());
+ }
+
// Cleanup requests.
STLDeleteElements(&requests);
requestlist_map_.erase(transaction->key());
@@ -304,6 +348,31 @@ void AsyncHostResolver::OnTransactionComplete(
ProcessPending();
}
+bool AsyncHostResolver::ServeFromCache(Request* request) const {
+ // Sanity check -- it shouldn't be the case that allow_cached_response is
+ // false while only_use_cached_response is true.
+ DCHECK(request->info().allow_cached_response() ||
+ !request->info().only_use_cached_response());
+
+ if (!cache_.get() || !request->info().allow_cached_response())
+ return false;
+
+ HostResolver::RequestInfo info = request->info();
+ HostCache::Key key(info.hostname(), info.address_family(),
+ info.host_resolver_flags());
+ const HostCache::Entry* cache_entry = cache_->Lookup(
+ key, base::TimeTicks::Now());
+ if (cache_entry) {
+ request->request_net_log().AddEvent(
+ NetLog::TYPE_ASYNC_HOST_RESOLVER_CACHE_HIT, NULL);
+ DCHECK_EQ(OK, cache_entry->error);
cbentzel 2011/07/21 15:31:10 Ah - I was going to ask you to handle non-OK error
+ request->set_addresses(
+ CreateAddressListUsingPort(cache_entry->addrlist, info.port()));
+ return true;
+ }
+ return false;
+}
+
AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest(
const RequestInfo& info,
const std::string& dns_name,
@@ -318,9 +387,8 @@ AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest(
NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST);
int id = next_request_id_++;
- Request* request = new Request(
+ return new Request(
source_net_log, request_net_log, id, info, key, callback, addresses);
- return request;
}
bool AsyncHostResolver::AttachToRequestList(Request* request) {
@@ -373,7 +441,7 @@ AsyncHostResolver::Request* AsyncHostResolver::Insert(Request* request) {
return NULL;
}
-size_t AsyncHostResolver::GetNumPending() {
+size_t AsyncHostResolver::GetNumPending() const {
size_t num_pending = 0;
for (size_t i = 0; i < arraysize(pending_requests_); ++i)
num_pending += pending_requests_[i].size();

Powered by Google App Engine
This is Rietveld 408576698