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

Unified Diff: net/http/http_server_properties_impl.cc

Issue 2898983006: Fix and refactor HttpServerPropertiesImpl's alternative services brokenness expiration behavior (Closed)
Patch Set: Fixed cherie's comments from ps9; added BrokenAlternativeServicesTest.ScheduleExpireTaskAfterExpire Created 3 years, 7 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
« no previous file with comments | « net/http/http_server_properties_impl.h ('k') | net/http/http_server_properties_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_server_properties_impl.cc
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index 7cc4a3298a2f9780dfa30e4059f073ccc824d8e2..abf4bf03e972d01382661f2d955ba06c913446bc 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -20,25 +20,17 @@
namespace net {
-namespace {
-
-// Initial delay for broken alternative services.
-const uint64_t kBrokenAlternativeProtocolDelaySecs = 300;
-// Subsequent failures result in exponential (base 2) backoff.
-// Limit binary shift to limit delay to approximately 2 days.
-const int kBrokenDelayMaxShift = 9;
-
-} // namespace
-
HttpServerPropertiesImpl::HttpServerPropertiesImpl()
- : spdy_servers_map_(SpdyServersMap::NO_AUTO_EVICT),
+ : HttpServerPropertiesImpl(&broken_alternative_services_clock_) {}
+
+HttpServerPropertiesImpl::HttpServerPropertiesImpl(
+ base::TickClock* broken_alternative_services_clock)
+ : broken_alternative_services_(this, broken_alternative_services_clock),
+ spdy_servers_map_(SpdyServersMap::NO_AUTO_EVICT),
alternative_service_map_(AlternativeServiceMap::NO_AUTO_EVICT),
- recently_broken_alternative_services_(
- RecentlyBrokenAlternativeServices::NO_AUTO_EVICT),
server_network_stats_map_(ServerNetworkStatsMap::NO_AUTO_EVICT),
quic_server_info_map_(QuicServerInfoMap::NO_AUTO_EVICT),
- max_server_configs_stored_in_properties_(kMaxQuicServersToPersist),
- weak_ptr_factory_(this) {
+ max_server_configs_stored_in_properties_(kMaxQuicServersToPersist) {
canonical_suffixes_.push_back(".ggpht.com");
canonical_suffixes_.push_back(".c.youtube.com");
canonical_suffixes_.push_back(".googlevideo.com");
@@ -454,71 +446,31 @@ bool HttpServerPropertiesImpl::SetAlternativeServices(
void HttpServerPropertiesImpl::MarkAlternativeServiceBroken(
const AlternativeService& alternative_service) {
- // Empty host means use host of origin, callers are supposed to substitute.
- DCHECK(!alternative_service.host.empty());
- if (alternative_service.protocol == kProtoUnknown) {
- LOG(DFATAL) << "Trying to mark unknown alternate protocol broken.";
- return;
- }
- auto it = recently_broken_alternative_services_.Get(alternative_service);
- int shift = 0;
- if (it == recently_broken_alternative_services_.end()) {
- recently_broken_alternative_services_.Put(alternative_service, 1);
- } else {
- shift = it->second++;
- }
- if (shift > kBrokenDelayMaxShift)
- shift = kBrokenDelayMaxShift;
- base::TimeDelta delay =
- base::TimeDelta::FromSeconds(kBrokenAlternativeProtocolDelaySecs);
- base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << shift);
- auto result = broken_alternative_services_.insert(
- std::make_pair(alternative_service, when));
- // Return if alternative service is already in expiration queue.
- if (!result.second) {
- return;
- }
-
- // If this is the only entry in the list, schedule an expiration task.
- // Otherwise it will be rescheduled automatically when the pending task runs.
- if (broken_alternative_services_.size() == 1) {
- ScheduleBrokenAlternateProtocolMappingsExpiration();
- }
+ broken_alternative_services_.MarkAlternativeServiceBroken(
+ alternative_service);
}
void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken(
const AlternativeService& alternative_service) {
- if (recently_broken_alternative_services_.Get(alternative_service) ==
- recently_broken_alternative_services_.end()) {
- recently_broken_alternative_services_.Put(alternative_service, 1);
- }
+ broken_alternative_services_.MarkAlternativeServiceRecentlyBroken(
+ alternative_service);
}
bool HttpServerPropertiesImpl::IsAlternativeServiceBroken(
const AlternativeService& alternative_service) const {
- // Empty host means use host of origin, callers are supposed to substitute.
- DCHECK(!alternative_service.host.empty());
- return base::ContainsKey(broken_alternative_services_, alternative_service);
+ return broken_alternative_services_.IsAlternativeServiceBroken(
+ alternative_service);
}
bool HttpServerPropertiesImpl::WasAlternativeServiceRecentlyBroken(
const AlternativeService& alternative_service) {
- if (alternative_service.protocol == kProtoUnknown)
- return false;
-
- return recently_broken_alternative_services_.Get(alternative_service) !=
- recently_broken_alternative_services_.end();
+ return broken_alternative_services_.WasAlternativeServiceRecentlyBroken(
+ alternative_service);
}
void HttpServerPropertiesImpl::ConfirmAlternativeService(
const AlternativeService& alternative_service) {
- if (alternative_service.protocol == kProtoUnknown)
- return;
- broken_alternative_services_.erase(alternative_service);
- auto it = recently_broken_alternative_services_.Get(alternative_service);
- if (it != recently_broken_alternative_services_.end()) {
- recently_broken_alternative_services_.Erase(it);
- }
+ broken_alternative_services_.ConfirmAlternativeService(alternative_service);
}
const AlternativeServiceMap& HttpServerPropertiesImpl::alternative_service_map()
@@ -712,65 +664,37 @@ void HttpServerPropertiesImpl::RemoveCanonicalHost(
canonical_host_to_origin_map_.erase(canonical->first);
}
-void HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings() {
- base::TimeTicks now = base::TimeTicks::Now();
- while (!broken_alternative_services_.empty()) {
- BrokenAlternativeServices::iterator it =
- broken_alternative_services_.begin();
- if (now < it->second) {
- break;
- }
-
- const AlternativeService expired_alternative_service = it->first;
- broken_alternative_services_.erase(it);
-
- // Remove every occurrence of |expired_alternative_service| from
- // |alternative_service_map_|.
- for (AlternativeServiceMap::iterator map_it =
- alternative_service_map_.begin();
- map_it != alternative_service_map_.end();) {
- for (AlternativeServiceInfoVector::iterator it = map_it->second.begin();
- it != map_it->second.end();) {
- AlternativeService alternative_service(it->alternative_service);
- // Empty hostname in map means hostname of key: substitute before
- // comparing to |expired_alternative_service|.
- if (alternative_service.host.empty()) {
- alternative_service.host = map_it->first.host();
- }
- if (alternative_service == expired_alternative_service) {
- it = map_it->second.erase(it);
- continue;
- }
- ++it;
+void HttpServerPropertiesImpl::OnExpireBrokenAlternativeService(
+ const AlternativeService& expired_alternative_service) {
+ // Remove every occurrence of |expired_alternative_service| from
+ // |alternative_service_map_|.
+ for (AlternativeServiceMap::iterator map_it =
+ alternative_service_map_.begin();
+ map_it != alternative_service_map_.end();) {
+ for (AlternativeServiceInfoVector::iterator it = map_it->second.begin();
+ it != map_it->second.end();) {
+ AlternativeService alternative_service(it->alternative_service);
+ // Empty hostname in map means hostname of key: substitute before
+ // comparing to |expired_alternative_service|.
+ if (alternative_service.host.empty()) {
+ alternative_service.host = map_it->first.host();
}
- // If an origin has an empty list of alternative services, then remove it
- // from both |canonical_host_to_origin_map_| and
- // |alternative_service_map_|.
- if (map_it->second.empty()) {
- RemoveCanonicalHost(map_it->first);
- map_it = alternative_service_map_.Erase(map_it);
+ if (alternative_service == expired_alternative_service) {
+ it = map_it->second.erase(it);
continue;
}
- ++map_it;
+ ++it;
}
+ // If an origin has an empty list of alternative services, then remove it
+ // from both |canonical_host_to_origin_map_| and
+ // |alternative_service_map_|.
+ if (map_it->second.empty()) {
+ RemoveCanonicalHost(map_it->first);
+ map_it = alternative_service_map_.Erase(map_it);
+ continue;
+ }
+ ++map_it;
}
- ScheduleBrokenAlternateProtocolMappingsExpiration();
-}
-
-void
-HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() {
- if (broken_alternative_services_.empty()) {
- return;
- }
- base::TimeTicks now = base::TimeTicks::Now();
- base::TimeTicks when = broken_alternative_services_.front().second;
- base::TimeDelta delay = when > now ? when - now : base::TimeDelta();
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::Bind(
- &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings,
- weak_ptr_factory_.GetWeakPtr()),
- delay);
}
} // namespace net
« no previous file with comments | « net/http/http_server_properties_impl.h ('k') | net/http/http_server_properties_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698