Speculative disk cache resource revalidations are sometimes wasted
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 Mar 2016 21:22:36 +0000 (21:22 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 Mar 2016 21:22:36 +0000 (21:22 +0000)
commit6d3c8962e319b7dbc622399f715b0701080c6f4c
tree4f1dbbd2a0f214f4dd4fbf7f808d2dbe3ab76cf9
parent6988f7da262cbee8e1304f20ba665f95b5bed519
Speculative disk cache resource revalidations are sometimes wasted
https://bugs.webkit.org/show_bug.cgi?id=155187
<rdar://problem/25032905>

Reviewed by Antti Koivisto.

Speculative disk cache resource revalidations were sometimes wasted.

We would sometimes correctly revalidate a resource but the
NetworkResourceLoader then either:
1. Fail to reuse the speculatively validated entry
2. Reuse the speculatively validated entry but then validate it again

Bug 1 was caused by the revalidated entry key sometimes being
different from the cached entry key. This could happen when
revalidation fails (the server did not send back a 304) in
which case we call NetworkCache::store() which creates a new
cache Entry, generating a cache key from our revalidation
request. If the original request has a cache partition or a
range, then the keys would not match because we did not set
the cache partition or the range on the revalidation request.
This has been addressed by setting the cache partition on the
revalidation request in constructRevalidationRequest() and by
not doing revalidation if the original request had a 'range'
header.

Bug 2 was caused by us marking a speculatively revalidated entry
as "not needing revalidating" only in Cache::update(). Cache::update()
is only called in the case the revalidation was successful (server
returned a 304). If revalidation was not successful, Cache::store()
would be called instead was we would fail to update the
needsRevalidation flag. NetworkResourceLoader would then validate
again the resource that was already speculatively revalidated.
To address the problem, we now update the 'needsRevalidation' flag
as soon as the speculative revalidation completes, in
SpeculativeLoad::didComplete().

* NetworkProcess/cache/NetworkCache.cpp:
(WebKit::NetworkCache::Cache::retrieve):
(WebKit::NetworkCache::makeCacheKey):
(WebKit::NetworkCache::Cache::update):
* NetworkProcess/cache/NetworkCacheEntry.cpp:
(WebKit::NetworkCache::Entry::setNeedsValidation):
* NetworkProcess/cache/NetworkCacheEntry.h:
* NetworkProcess/cache/NetworkCacheKey.cpp:
(WebKit::NetworkCache::noPartitionString):
(WebKit::NetworkCache::Key::Key):
(WebKit::NetworkCache::Key::hasPartition):
* NetworkProcess/cache/NetworkCacheKey.h:
* NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
(WebKit::NetworkCache::SpeculativeLoad::didComplete):
* NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
(WebKit::NetworkCache::constructRevalidationRequest):
(WebKit::NetworkCache::SpeculativeLoadManager::retrieveEntryFromStorage):
(WebKit::NetworkCache::SpeculativeLoadManager::revalidateEntry):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@197879 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h
Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h
Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp