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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/stale_host_resolver.h"
6
7 #include "base/metrics/histogram_macros.h"
8 #include "base/timer/timer.h"
9 #include "base/values.h"
10 #include "net/base/net_errors.h"
11 #include "net/dns/dns_util.h"
12
13 namespace net {
14
15 namespace {
16
17 bool StaleEntryIsUsable(const StaleHostResolver::StaleOptions& options,
18 const HostCache::StaleEntryInfo& entry) {
19 if (options.max_expired_time != base::TimeDelta()) {
20 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.
21 return false;
22 }
23 if (options.max_stale_uses > 0u) {
24 if (entry.stale_hits > options.max_stale_uses)
25 return false;
26 }
27 if (!options.allow_other_network) {
28 if (entry.network_changes > 0u)
29 return false;
30 }
31 return true;
32 }
33
34 } // namespace
35
36 // Used in histograms; please only insert new entries before MAX.
37 enum RequestOutcome {
38 // Served from (valid) cache, hosts file, IP literal, etc.
39 SYNCHRONOUS,
40 // Network responded; there was no usable stale data.
41 NETWORK_WITHOUT_STALE,
42 // Network responded before stale delay; there was usable stale data.
43 NETWORK_WITH_STALE,
44 // Stale data returned; network didn't respond before the stale delay.
45 STALE_BEFORE_NETWORK,
46 // Request canceled; there was no usable stale data.
47 CANCELED_WITHOUT_STALE,
48 // Request canceled; there was usable stale data.
49 CANCELED_WITH_STALE,
50 MAX_REQUEST_OUTCOME
51 };
52
53 void HistogramRequestOutcome(RequestOutcome outcome) {
54 UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolverRequestOutcome", outcome,
55 MAX_REQUEST_OUTCOME);
56 }
57
58 void HistogramStaleDelta(AddressListDeltaType delta) {
59 UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolverStaleDelta", delta,
60 MAX_DELTA_TYPE);
61 }
62
63 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.
64 public:
65 Request(AddressList* addresses,
66 const CompletionCallback& callback,
67 const BoundNetLog& net_log)
68 : addresses_(addresses),
69 callback_(callback),
70 net_log_(net_log),
71 network_handle_(nullptr) {
72 DCHECK(!callback_.is_null());
73 }
74
75 typedef base::Callback<bool(const HostCache::StaleEntryInfo&)>
76 StaleEntryUsableCallback;
77
78 int Start(HostResolver* resolver,
79 const RequestInfo& info,
80 RequestPriority priority,
81 const StaleEntryUsableCallback& usable_callback,
82 base::TimeDelta stale_delay) {
83 HostCache::StaleEntryInfo stale_info;
84 int rv = resolver->ResolveStale(info, priority, &network_addresses_,
85 network_callback(), &network_handle_,
86 &stale_error_, &stale_addresses_,
87 &stale_info, net_log_);
88 if (rv != ERR_IO_PENDING) {
89 *addresses_ = network_addresses_;
90 delete this;
91 HistogramRequestOutcome(SYNCHRONOUS);
92 return rv;
93 }
94
95 if (stale_error_ != ERR_DNS_CACHE_MISS && usable_callback.Run(stale_info))
96 stale_timer_.Start(FROM_HERE, stale_delay, stale_callback());
97 else
98 stale_addresses_.clear();
99
100 return ERR_IO_PENDING;
101 }
102
103 void Cancel(HostResolver* resolver) {
104 DCHECK(!returned_stale_response());
105 DCHECK(network_handle_);
106 resolver->CancelRequest(network_handle_);
107 if (stale_timer_.IsRunning())
108 HistogramRequestOutcome(CANCELED_WITH_STALE);
109 else
110 HistogramRequestOutcome(CANCELED_WITHOUT_STALE);
111 delete this;
112 }
113
114 void OnStaleDelayElapsed() {
115 DCHECK(!returned_stale_response());
116 callback_.Run(HandleResponse(stale_error_, stale_addresses_));
117 HistogramRequestOutcome(STALE_BEFORE_NETWORK);
118 callback_.Reset();
119 }
120
121 void OnNetworkRequestComplete(int error) {
122 if (!returned_stale_response()) {
123 callback_.Run(HandleResponse(error, network_addresses_));
124 if (stale_timer_.IsRunning())
125 HistogramRequestOutcome(NETWORK_WITH_STALE);
126 else
127 HistogramRequestOutcome(NETWORK_WITHOUT_STALE);
128 }
129 if (returned_stale_response() && stale_error_ == OK && error == OK) {
130 HistogramStaleDelta(
131 FindAddressListDeltaType(stale_addresses_, network_addresses_));
132 }
133 delete this;
134 }
135
136 private:
137 int HandleResponse(int rv, const AddressList& addresses) {
138 if (rv == OK)
139 *addresses_ = addresses;
140 return rv;
141 }
142
143 bool returned_stale_response() { return callback_.is_null(); }
144
145 base::Callback<void()> stale_callback() {
146 return base::Bind(&StaleHostResolver::Request::OnStaleDelayElapsed,
147 base::Unretained(this));
148 }
149
150 CompletionCallback network_callback() {
151 return base::Bind(&StaleHostResolver::Request::OnNetworkRequestComplete,
152 base::Unretained(this));
153 }
154
155 AddressList* addresses_;
156 CompletionCallback callback_;
157 BoundNetLog net_log_;
158
159 int stale_error_;
160 AddressList stale_addresses_;
161 base::OneShotTimer stale_timer_;
162
163 AddressList network_addresses_;
164 HostResolver::RequestHandle network_handle_;
165 };
166
167 StaleHostResolver::StaleHostResolver(
168 std::unique_ptr<HostResolver> inner_resolver,
169 const StaleOptions& stale_options)
170 : resolver_(std::move(inner_resolver)), options_(stale_options) {}
171
172 StaleHostResolver::~StaleHostResolver() {}
173
174 int StaleHostResolver::Resolve(const RequestInfo& info,
175 RequestPriority priority,
176 AddressList* addresses,
177 const CompletionCallback& callback,
178 RequestHandle* out_req,
179 const BoundNetLog& net_log) {
180 Request* request = new Request(addresses, callback, net_log);
181 int rv =
182 request->Start(resolver_.get(), info, priority,
183 base::Bind(&StaleEntryIsUsable, options_), options_.delay);
184 if (rv == ERR_IO_PENDING && out_req)
185 *out_req = reinterpret_cast<RequestHandle>(request);
186 return rv;
187 }
188
189 void StaleHostResolver::CancelRequest(RequestHandle req_handle) {
190 Request* request = reinterpret_cast<Request*>(req_handle);
191 DCHECK(request);
192 request->Cancel(resolver_.get());
193 }
194
195 int StaleHostResolver::ResolveFromCache(const RequestInfo& info,
196 AddressList* addresses,
197 const BoundNetLog& net_log) {
198 return resolver_->ResolveFromCache(info, addresses, net_log);
199 }
200
201 int StaleHostResolver::ResolveStaleFromCache(
202 const RequestInfo& info,
203 AddressList* addresses,
204 HostCache::StaleEntryInfo* stale_info,
205 const BoundNetLog& net_log) {
206 return resolver_->ResolveStaleFromCache(info, addresses, stale_info, net_log);
207 }
208
209 void StaleHostResolver::SetDnsClientEnabled(bool enabled) {
210 resolver_->SetDnsClientEnabled(enabled);
211 }
212
213 HostCache* StaleHostResolver::GetHostCache() {
214 return resolver_->GetHostCache();
215 }
216
217 std::unique_ptr<base::Value> StaleHostResolver::GetDnsConfigAsValue() const {
218 return resolver_->GetDnsConfigAsValue();
219 }
220
221 } // namespace net
OLDNEW
« 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