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

Unified Diff: net/dns/stale_host_resolver.cc

Issue 1898873006: Cronet: Use stale DNS cache entries experimentally. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dns_stale2
Patch Set: rebase Created 4 years, 8 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/dns/stale_host_resolver.cc
diff --git a/net/dns/stale_host_resolver.cc b/net/dns/stale_host_resolver.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ecbec46998b3189ad663f15c02995d598d70e775
--- /dev/null
+++ b/net/dns/stale_host_resolver.cc
@@ -0,0 +1,221 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/stale_host_resolver.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "base/timer/timer.h"
+#include "base/values.h"
+#include "net/base/net_errors.h"
+#include "net/dns/dns_util.h"
+
+namespace net {
+
+namespace {
+
+bool StaleEntryIsUsable(const StaleHostResolver::StaleOptions& options,
+ const HostCache::StaleEntryInfo& entry) {
+ if (options.max_expired_time != base::TimeDelta()) {
+ if (entry.expired_by > options.max_expired_time)
Ryan Sleevi 2016/04/26 02:25:36 Can't you condense these conditionals?
Julia Tuttle 2016/04/27 14:50:26 Done.
+ return false;
+ }
+ if (options.max_stale_uses > 0u) {
+ if (entry.stale_hits > options.max_stale_uses)
+ return false;
+ }
+ if (!options.allow_other_network) {
+ if (entry.network_changes > 0u)
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+// Used in histograms; please only insert new entries before MAX.
+enum RequestOutcome {
+ // Served from (valid) cache, hosts file, IP literal, etc.
+ SYNCHRONOUS,
+ // Network responded; there was no usable stale data.
+ NETWORK_WITHOUT_STALE,
+ // Network responded before stale delay; there was usable stale data.
+ NETWORK_WITH_STALE,
+ // Stale data returned; network didn't respond before the stale delay.
+ STALE_BEFORE_NETWORK,
+ // Request canceled; there was no usable stale data.
+ CANCELED_WITHOUT_STALE,
+ // Request canceled; there was usable stale data.
+ CANCELED_WITH_STALE,
+ MAX_REQUEST_OUTCOME
+};
+
+void HistogramRequestOutcome(RequestOutcome outcome) {
+ UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolverRequestOutcome", outcome,
+ MAX_REQUEST_OUTCOME);
+}
+
+void HistogramStaleDelta(AddressListDeltaType delta) {
+ UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolverStaleDelta", delta,
+ MAX_DELTA_TYPE);
+}
+
+class StaleHostResolver::Request {
Ryan Sleevi 2016/04/26 02:25:36 Document (throughout)? I'd like to suggest it may
Julia Tuttle 2016/04/27 14:50:26 Done.
+ public:
+ Request(AddressList* addresses,
+ const CompletionCallback& callback,
+ const BoundNetLog& net_log)
+ : addresses_(addresses),
+ callback_(callback),
+ net_log_(net_log),
+ network_handle_(nullptr) {
+ DCHECK(!callback_.is_null());
+ }
+
+ typedef base::Callback<bool(const HostCache::StaleEntryInfo&)>
+ StaleEntryUsableCallback;
+
+ int Start(HostResolver* resolver,
+ const RequestInfo& info,
+ RequestPriority priority,
+ const StaleEntryUsableCallback& usable_callback,
+ base::TimeDelta stale_delay) {
+ HostCache::StaleEntryInfo stale_info;
+ int rv = resolver->ResolveStale(info, priority, &network_addresses_,
+ network_callback(), &network_handle_,
+ &stale_error_, &stale_addresses_,
+ &stale_info, net_log_);
+ if (rv != ERR_IO_PENDING) {
+ *addresses_ = network_addresses_;
+ delete this;
+ HistogramRequestOutcome(SYNCHRONOUS);
+ return rv;
+ }
+
+ if (stale_error_ != ERR_DNS_CACHE_MISS && usable_callback.Run(stale_info))
+ stale_timer_.Start(FROM_HERE, stale_delay, stale_callback());
+ else
+ stale_addresses_.clear();
+
+ return ERR_IO_PENDING;
+ }
+
+ void Cancel(HostResolver* resolver) {
+ DCHECK(!returned_stale_response());
+ DCHECK(network_handle_);
+ resolver->CancelRequest(network_handle_);
+ if (stale_timer_.IsRunning())
+ HistogramRequestOutcome(CANCELED_WITH_STALE);
+ else
+ HistogramRequestOutcome(CANCELED_WITHOUT_STALE);
+ delete this;
+ }
+
+ void OnStaleDelayElapsed() {
+ DCHECK(!returned_stale_response());
+ callback_.Run(HandleResponse(stale_error_, stale_addresses_));
+ HistogramRequestOutcome(STALE_BEFORE_NETWORK);
+ callback_.Reset();
+ }
+
+ void OnNetworkRequestComplete(int error) {
+ if (!returned_stale_response()) {
+ callback_.Run(HandleResponse(error, network_addresses_));
+ if (stale_timer_.IsRunning())
+ HistogramRequestOutcome(NETWORK_WITH_STALE);
+ else
+ HistogramRequestOutcome(NETWORK_WITHOUT_STALE);
+ }
+ if (returned_stale_response() && stale_error_ == OK && error == OK) {
+ HistogramStaleDelta(
+ FindAddressListDeltaType(stale_addresses_, network_addresses_));
+ }
+ delete this;
+ }
+
+ private:
+ int HandleResponse(int rv, const AddressList& addresses) {
+ if (rv == OK)
+ *addresses_ = addresses;
+ return rv;
+ }
+
+ bool returned_stale_response() { return callback_.is_null(); }
+
+ base::Callback<void()> stale_callback() {
+ return base::Bind(&StaleHostResolver::Request::OnStaleDelayElapsed,
+ base::Unretained(this));
+ }
+
+ CompletionCallback network_callback() {
+ return base::Bind(&StaleHostResolver::Request::OnNetworkRequestComplete,
+ base::Unretained(this));
+ }
+
+ AddressList* addresses_;
+ CompletionCallback callback_;
+ BoundNetLog net_log_;
+
+ int stale_error_;
+ AddressList stale_addresses_;
+ base::OneShotTimer stale_timer_;
+
+ AddressList network_addresses_;
+ HostResolver::RequestHandle network_handle_;
+};
+
+StaleHostResolver::StaleHostResolver(
+ std::unique_ptr<HostResolver> inner_resolver,
+ const StaleOptions& stale_options)
+ : resolver_(std::move(inner_resolver)), options_(stale_options) {}
+
+StaleHostResolver::~StaleHostResolver() {}
+
+int StaleHostResolver::Resolve(const RequestInfo& info,
+ RequestPriority priority,
+ AddressList* addresses,
+ const CompletionCallback& callback,
+ RequestHandle* out_req,
+ const BoundNetLog& net_log) {
+ Request* request = new Request(addresses, callback, net_log);
+ int rv =
+ request->Start(resolver_.get(), info, priority,
+ base::Bind(&StaleEntryIsUsable, options_), options_.delay);
+ if (rv == ERR_IO_PENDING && out_req)
+ *out_req = reinterpret_cast<RequestHandle>(request);
+ return rv;
+}
+
+void StaleHostResolver::CancelRequest(RequestHandle req_handle) {
+ Request* request = reinterpret_cast<Request*>(req_handle);
+ DCHECK(request);
+ request->Cancel(resolver_.get());
+}
+
+int StaleHostResolver::ResolveFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ const BoundNetLog& net_log) {
+ return resolver_->ResolveFromCache(info, addresses, net_log);
+}
+
+int StaleHostResolver::ResolveStaleFromCache(
+ const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::StaleEntryInfo* stale_info,
+ const BoundNetLog& net_log) {
+ return resolver_->ResolveStaleFromCache(info, addresses, stale_info, net_log);
+}
+
+void StaleHostResolver::SetDnsClientEnabled(bool enabled) {
+ resolver_->SetDnsClientEnabled(enabled);
+}
+
+HostCache* StaleHostResolver::GetHostCache() {
+ return resolver_->GetHostCache();
+}
+
+std::unique_ptr<base::Value> StaleHostResolver::GetDnsConfigAsValue() const {
+ return resolver_->GetDnsConfigAsValue();
+}
+
+} // namespace net
« net/dns/stale_host_resolver.h ('K') | « net/dns/stale_host_resolver.h ('k') | net/net.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698