Changeset 197879 in webkit
- Timestamp:
- Mar 9, 2016, 1:22:36 PM (9 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r197870 r197879 1 2016-03-09 Chris Dumez <cdumez@apple.com> 2 3 Speculative disk cache resource revalidations are sometimes wasted 4 https://bugs.webkit.org/show_bug.cgi?id=155187 5 <rdar://problem/25032905> 6 7 Reviewed by Antti Koivisto. 8 9 Speculative disk cache resource revalidations were sometimes wasted. 10 11 We would sometimes correctly revalidate a resource but the 12 NetworkResourceLoader then either: 13 1. Fail to reuse the speculatively validated entry 14 2. Reuse the speculatively validated entry but then validate it again 15 16 Bug 1 was caused by the revalidated entry key sometimes being 17 different from the cached entry key. This could happen when 18 revalidation fails (the server did not send back a 304) in 19 which case we call NetworkCache::store() which creates a new 20 cache Entry, generating a cache key from our revalidation 21 request. If the original request has a cache partition or a 22 range, then the keys would not match because we did not set 23 the cache partition or the range on the revalidation request. 24 This has been addressed by setting the cache partition on the 25 revalidation request in constructRevalidationRequest() and by 26 not doing revalidation if the original request had a 'range' 27 header. 28 29 Bug 2 was caused by us marking a speculatively revalidated entry 30 as "not needing revalidating" only in Cache::update(). Cache::update() 31 is only called in the case the revalidation was successful (server 32 returned a 304). If revalidation was not successful, Cache::store() 33 would be called instead was we would fail to update the 34 needsRevalidation flag. NetworkResourceLoader would then validate 35 again the resource that was already speculatively revalidated. 36 To address the problem, we now update the 'needsRevalidation' flag 37 as soon as the speculative revalidation completes, in 38 SpeculativeLoad::didComplete(). 39 40 * NetworkProcess/cache/NetworkCache.cpp: 41 (WebKit::NetworkCache::Cache::retrieve): 42 (WebKit::NetworkCache::makeCacheKey): 43 (WebKit::NetworkCache::Cache::update): 44 * NetworkProcess/cache/NetworkCacheEntry.cpp: 45 (WebKit::NetworkCache::Entry::setNeedsValidation): 46 * NetworkProcess/cache/NetworkCacheEntry.h: 47 * NetworkProcess/cache/NetworkCacheKey.cpp: 48 (WebKit::NetworkCache::noPartitionString): 49 (WebKit::NetworkCache::Key::Key): 50 (WebKit::NetworkCache::Key::hasPartition): 51 * NetworkProcess/cache/NetworkCacheKey.h: 52 * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp: 53 (WebKit::NetworkCache::SpeculativeLoad::didComplete): 54 * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp: 55 (WebKit::NetworkCache::constructRevalidationRequest): 56 (WebKit::NetworkCache::SpeculativeLoadManager::retrieveEntryFromStorage): 57 (WebKit::NetworkCache::SpeculativeLoadManager::revalidateEntry): 58 1 59 2016-03-09 Brent Fulgham <bfulgham@apple.com> 2 60 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp
r197180 r197879 122 122 String partition; 123 123 #endif 124 if (partition.isEmpty())125 partition = ASCIILiteral("No partition");126 124 127 125 // FIXME: This implements minimal Range header disk cache support. We don't parse … … 403 401 break; 404 402 case UseDecision::Validate: 405 entry->setNeedsValidation( );403 entry->setNeedsValidation(true); 406 404 break; 407 405 default: … … 496 494 WebCore::ResourceResponse response = existingEntry.response(); 497 495 WebCore::updateResponseHeadersAfterRevalidation(response, validatingResponse); 498 response.setSource(WebCore::ResourceResponse::Source::DiskCache);499 496 500 497 auto updateEntry = std::make_unique<Entry>(existingEntry.key(), response, existingEntry.buffer(), collectVaryingRequestHeaders(originalRequest, response)); -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp
r194496 r197879 189 189 } 190 190 191 void Entry::setNeedsValidation() 192 { 193 ASSERT(m_response.source() == WebCore::ResourceResponse::Source::DiskCache); 194 m_response.setSource(WebCore::ResourceResponse::Source::DiskCacheAfterValidation); 191 void Entry::setNeedsValidation(bool value) 192 { 193 m_response.setSource(value ? WebCore::ResourceResponse::Source::DiskCacheAfterValidation : WebCore::ResourceResponse::Source::DiskCache); 195 194 } 196 195 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h
r194313 r197879 67 67 68 68 bool needsValidation() const; 69 void setNeedsValidation( );69 void setNeedsValidation(bool); 70 70 71 71 const Storage::Record& sourceStorageRecord() const { return m_sourceStorageRecord; } -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp
r192111 r197879 31 31 #include "NetworkCacheCoders.h" 32 32 #include <wtf/ASCIICType.h> 33 #include <wtf/NeverDestroyed.h> 33 34 #include <wtf/text/CString.h> 34 35 #include <wtf/text/StringBuilder.h> … … 36 37 namespace WebKit { 37 38 namespace NetworkCache { 39 40 static const String& noPartitionString() 41 { 42 static NeverDestroyed<String> noPartition(ASCIILiteral("No partition")); 43 return noPartition; 44 } 38 45 39 46 Key::Key(const Key& o) … … 47 54 48 55 Key::Key(const String& partition, const String& type, const String& range, const String& identifier) 49 : m_partition(partition.is olatedCopy())56 : m_partition(partition.isEmpty() ? noPartitionString().isolatedCopy() : partition.isolatedCopy()) 50 57 , m_type(type.isolatedCopy()) 51 58 , m_identifier(identifier.isolatedCopy()) … … 58 65 : m_identifier(WTF::HashTableDeletedValue) 59 66 { 67 } 68 69 bool Key::hasPartition() const 70 { 71 return m_partition != noPartitionString(); 60 72 } 61 73 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h
r192111 r197879 55 55 bool isNull() const { return m_identifier.isNull(); } 56 56 57 bool hasPartition() const; 57 58 const String& partition() const { return m_partition; } 58 59 const String& identifier() const { return m_identifier; } -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp
r194496 r197879 140 140 m_networkLoad = nullptr; 141 141 142 // Make sure speculatively revalidated resources do not get validated by the NetworkResourceLoader again. 143 if (m_cacheEntryForValidation) 144 m_cacheEntryForValidation->setNeedsValidation(false); 145 142 146 m_completionHandler(WTFMove(m_cacheEntryForValidation)); 143 147 } -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp
r194496 r197879 88 88 { 89 89 ResourceRequest revalidationRequest(entry.key().identifier()); 90 #if ENABLE(CACHE_PARTITIONING) 91 if (entry.key().hasPartition()) 92 revalidationRequest.setCachePartition(entry.key().partition()); 93 #endif 94 ASSERT_WITH_MESSAGE(entry.key().range().isEmpty(), "range is not supported"); 90 95 91 96 String eTag = entry.response().httpHeaderField(HTTPHeaderName::ETag); … … 345 350 346 351 if (responseNeedsRevalidation(response, entry->timeStamp())) 347 entry->setNeedsValidation( );352 entry->setNeedsValidation(true); 348 353 349 354 completionHandler(WTFMove(entry)); … … 370 375 371 376 auto key = entry->key(); 377 378 // Range is not supported. 379 if (!key.range().isEmpty()) 380 return; 381 372 382 LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Speculatively revalidating '%s':", key.identifier().utf8().data()); 373 383 auto revalidator = std::make_unique<SpeculativeLoad>(frameID, constructRevalidationRequest(*entry), WTFMove(entry), [this, key, frameID](std::unique_ptr<Entry> revalidatedEntry) { 374 384 ASSERT(!revalidatedEntry || !revalidatedEntry->needsValidation()); 385 ASSERT(!revalidatedEntry || revalidatedEntry->key() == key); 386 375 387 auto protectRevalidator = m_pendingPreloads.take(key); 376 388 LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Speculative revalidation completed for '%s':", key.identifier().utf8().data());
Note:
See TracChangeset
for help on using the changeset viewer.