RESOLVED FIXED 204147
Handle page closure for stale-while-revalidate revalidations
https://bugs.webkit.org/show_bug.cgi?id=204147
Summary Handle page closure for stale-while-revalidate revalidations
Rob Buis
Reported 2019-11-13 01:19:42 PST
Attachments
Patch (8.76 KB, patch)
2019-11-22 05:46 PST, Rob Buis
no flags
Patch (11.47 KB, patch)
2019-11-26 09:20 PST, Rob Buis
no flags
Patch (11.14 KB, patch)
2019-11-26 11:23 PST, Rob Buis
no flags
Patch (15.10 KB, patch)
2019-12-03 04:38 PST, Rob Buis
no flags
Patch (15.10 KB, patch)
2019-12-03 06:15 PST, Rob Buis
no flags
Patch (15.44 KB, patch)
2019-12-13 01:51 PST, Rob Buis
no flags
Patch (19.99 KB, patch)
2020-01-06 07:19 PST, Rob Buis
no flags
Patch (29.39 KB, patch)
2020-01-09 06:53 PST, Rob Buis
no flags
Patch (29.42 KB, patch)
2020-01-10 00:01 PST, Rob Buis
no flags
Patch (29.72 KB, patch)
2020-01-23 02:30 PST, Rob Buis
no flags
Patch (29.71 KB, patch)
2020-01-23 05:29 PST, Rob Buis
no flags
Patch (29.72 KB, patch)
2020-01-23 07:10 PST, Rob Buis
no flags
Patch (29.88 KB, patch)
2020-01-24 00:24 PST, Rob Buis
no flags
Patch (28.97 KB, patch)
2020-01-27 00:44 PST, Rob Buis
no flags
Patch (29.71 KB, patch)
2020-01-27 01:10 PST, Rob Buis
no flags
Patch (29.60 KB, patch)
2020-02-07 00:41 PST, Rob Buis
no flags
Patch (29.67 KB, patch)
2020-02-24 06:02 PST, Rob Buis
no flags
Rob Buis
Comment 1 2019-11-22 05:46:20 PST
Rob Buis
Comment 2 2019-11-26 09:20:22 PST
Rob Buis
Comment 3 2019-11-26 11:23:15 PST
Rob Buis
Comment 4 2019-12-03 04:38:42 PST
Rob Buis
Comment 5 2019-12-03 06:15:12 PST
Rob Buis
Comment 6 2019-12-04 01:22:45 PST
Comment on attachment 384711 [details] Patch This still needs a test but I think it can be reviewed to check if it is the right direction. Some remarks: - I picked stopAllLoaders to catch both page close and starting a new navigation within a page. - I do not like adding another HashMap but I think it is hard to avoid. - The cleanup only gets triggered for main frames.
youenn fablet
Comment 7 2019-12-12 00:36:48 PST
Comment on attachment 384711 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=384711&action=review > Source/WebCore/loader/FrameLoader.cpp:1844 > + platformStrategies()->loaderStrategy()->pageContextRemoved(*m_frame.page()); We might actually want to send the message for all contexts since we want to cancel the revalidation when a context is going away and not when its top level context is going away. We may thus need to send pageID/frameID and rename pageContextRemoved. > Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:339 > + m_pendingAsyncRevalidationByPage.remove(webPageID); I do not see here where we are cancelling the async revalidation of the page. > Source/WebKit/NetworkProcess/cache/NetworkCache.h:204 > + HashMap<WebCore::PageIdentifier, std::unique_ptr<Vector<Key>>> m_pendingAsyncRevalidationByPage; Why is it a unique_ptr<Vector> and not a Vector?
Rob Buis
Comment 8 2019-12-13 01:51:15 PST
Rob Buis
Comment 9 2019-12-13 02:58:35 PST
Comment on attachment 384711 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=384711&action=review I started on the test but maybe you can give some clues, it seems really hard to verify that the right thing is done. Even internal testing API seems difficult since we need to verify things in the network process? >> Source/WebCore/loader/FrameLoader.cpp:1844 >> + platformStrategies()->loaderStrategy()->pageContextRemoved(*m_frame.page()); > > We might actually want to send the message for all contexts since we want to cancel the revalidation when a context is going away and not when its top level context is going away. > We may thus need to send pageID/frameID and rename pageContextRemoved. Ok, I initially did it this way to reduce the IPC since I was not sure how intrusive it would be. I now renamed it to browserContextRemoved. >> Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:339 >> + m_pendingAsyncRevalidationByPage.remove(webPageID); > > I do not see here where we are cancelling the async revalidation of the page. Oops you are right, should be fixed now. >> Source/WebKit/NetworkProcess/cache/NetworkCache.h:204 >> + HashMap<WebCore::PageIdentifier, std::unique_ptr<Vector<Key>>> m_pendingAsyncRevalidationByPage; > > Why is it a unique_ptr<Vector> and not a Vector? No real reason, now Use just Vector.
youenn fablet
Comment 10 2019-12-15 23:50:14 PST
Comment on attachment 385586 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=385586&action=review > Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:341 > + m_pendingAsyncRevalidations.remove(key); It seems we take all keys of the page while we should only take the keys that match the frame ID and remove the corresponding revalidations.
youenn fablet
Comment 11 2019-12-15 23:56:50 PST
(In reply to Rob Buis from comment #9) > Comment on attachment 384711 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=384711&action=review > > I started on the test but maybe you can give some clues, it seems really > hard to verify that the right thing is done. Even internal testing API seems > difficult since we need to verify things in the network process? One possibility would be to write a python script that is hanging for 0.5 seconds in case this is a stale revalidation. We could first load an iframe to get the resource. We could then load a new iframe to get the same resource, it should trigger revalidation. Revalidation will be hanging. We could then remove the iframe, this should remove the ongoing revalidation. We could then load a new iframe to get the same resource, it should probably get the cached resource and trigger a revalidation instead of reusing the cancelled revalidation (that would still be hanging without the patch). It might be good to load in parallel another iframe with a different URL that triggers revalidation so that we can check that one frame revalidation is cancelled but not all.
Rob Buis
Comment 12 2020-01-06 07:19:16 PST
Rob Buis
Comment 13 2020-01-09 06:53:05 PST
Rob Buis
Comment 14 2020-01-10 00:01:42 PST
Rob Buis
Comment 15 2020-01-10 06:00:24 PST
(In reply to youenn fablet from comment #11) > (In reply to Rob Buis from comment #9) > > Comment on attachment 384711 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=384711&action=review > > > > I started on the test but maybe you can give some clues, it seems really > > hard to verify that the right thing is done. Even internal testing API seems > > difficult since we need to verify things in the network process? > > One possibility would be to write a python script that is hanging for 0.5 > seconds in case this is a stale revalidation. It seems not so easy to detect stale revalidations. One way I found that worked is responding with ETag and then the stale revalidation request will contain If-None-Match. However the memory cache can also send out If-None-Match so maybe we need to skip memory cache for s-w-r responses first: https://bugs.webkit.org/show_bug.cgi?id=205992 > We could first load an iframe to get the resource. > We could then load a new iframe to get the same resource, it should trigger > revalidation. Revalidation will be hanging. > We could then remove the iframe, this should remove the ongoing revalidation. > We could then load a new iframe to get the same resource, it should probably > get the cached resource and trigger a revalidation instead of reusing the > cancelled revalidation (that would still be hanging without the patch). I tried to add that test case to this patch. Although I think the memory cache issue maybe needs to be fixed first (https://bugs.webkit.org/show_bug.cgi?id=205992), I think this patch can be reviewed again.
youenn fablet
Comment 16 2020-01-22 07:45:42 PST
Comment on attachment 387317 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=387317&action=review > Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:329 > + keys.removeFirst(key); keys will probably be a new vector copied from m_pendingAsyncRevalidationByPage owned vector. So removing might not work here. Can you add some ASSERTS as well so that we are sure 'keys' contains key for instance. Also, why not simplify things and have something like a Map<GlobalID, WeakHashSet<AsyncRevalidation>>. This would allow to write something like: auto loaders = m_pendingAsyncRevalidationByPage.take(globalID); for (auto& loader : loaders) loader->cancel(); > Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:340 > + for (auto key : keys) { s/auto/auto&/ > Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:342 > + if (revalidation) if (auto revalidation = ...) Should we use take instead of get here as well, or cancel will do it automatically?
Rob Buis
Comment 17 2020-01-23 02:30:58 PST
Rob Buis
Comment 18 2020-01-23 05:29:55 PST
Rob Buis
Comment 19 2020-01-23 07:10:40 PST
Rob Buis
Comment 20 2020-01-24 00:24:08 PST
Rob Buis
Comment 21 2020-01-24 01:58:58 PST
Comment on attachment 387317 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=387317&action=review >> Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:329 >> + keys.removeFirst(key); > > keys will probably be a new vector copied from m_pendingAsyncRevalidationByPage owned vector. > So removing might not work here. > Can you add some ASSERTS as well so that we are sure 'keys' contains key for instance. > > Also, why not simplify things and have something like a Map<GlobalID, WeakHashSet<AsyncRevalidation>>. > This would allow to write something like: > auto loaders = m_pendingAsyncRevalidationByPage.take(globalID); > for (auto& loader : loaders) > loader->cancel(); Great idea, things get simpler when using WeakHashSet. >> Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:340 >> + for (auto key : keys) { > > s/auto/auto&/ Done. >> Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:342 >> + if (revalidation) > > if (auto revalidation = ...) > Should we use take instead of get here as well, or cancel will do it automatically? I changed the logic so cancel will do it automatically by calling the completion handler.
youenn fablet
Comment 22 2020-01-24 06:45:35 PST
Comment on attachment 388659 [details] Patch Seems almost ready to me, I have just one question with regards to the new CachedResourceLoader check. View in context: https://bugs.webkit.org/attachment.cgi?id=388659&action=review > Source/WebCore/loader/cache/CachedResourceLoader.cpp:1173 > + if (existingResource->response().cacheControlStaleWhileRevalidate()) { The comment does not match the check, which is about checking for cache control stale while revalidate. Ditto for the message. Also, I am not sure we need this check. It seems that we should reload only if the resource is expired, otherwise we should be able to use it. Can you clarify? > Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:325 > + auto revalidation = makeUnique<AsyncRevalidation>(*this, frameID, request, WTFMove(entry), [this, key](AsyncRevalidation::Result result) { s/AsyncRevalidation::Result/auto > Source/WebKit/NetworkProcess/cache/NetworkCache.h:236 > + HashMap<GlobalFrameID, WTF::WeakHashSet<AsyncRevalidation>> m_pendingAsyncRevalidationByPage; Do we need WTF::?
Rob Buis
Comment 23 2020-01-27 00:44:19 PST
Rob Buis
Comment 24 2020-01-27 01:10:56 PST
Rob Buis
Comment 25 2020-01-27 02:57:29 PST
Comment on attachment 388659 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388659&action=review >> Source/WebCore/loader/cache/CachedResourceLoader.cpp:1173 >> + if (existingResource->response().cacheControlStaleWhileRevalidate()) { > > The comment does not match the check, which is about checking for cache control stale while revalidate. > Ditto for the message. > Also, I am not sure we need this check. > It seems that we should reload only if the resource is expired, otherwise we should be able to use it. > Can you clarify? Sorry, that was a copy pasta mistake. The problem is that frame-removal.htmlt needs to be able to identify stale revalidations to check that the cancel is performed. The standard revalidate for the memory cache sends the same headers, so I propose for stale memory resources with s-w-r headers we leave it up to the network process to handle the revalidate process, and then the test will work fine, but will fail if the revalidation cancel is not done, as the test should. >> Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:325 >> + auto revalidation = makeUnique<AsyncRevalidation>(*this, frameID, request, WTFMove(entry), [this, key](AsyncRevalidation::Result result) { > > s/AsyncRevalidation::Result/auto Done. >> Source/WebKit/NetworkProcess/cache/NetworkCache.h:236 >> + HashMap<GlobalFrameID, WTF::WeakHashSet<AsyncRevalidation>> m_pendingAsyncRevalidationByPage; > > Do we need WTF::? No, fixed.
youenn fablet
Comment 26 2020-02-07 00:35:43 PST
Comment on attachment 388839 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388839&action=review > Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:341 > + fprintf(stderr, "browsingContextRemoved cancel!!!\n"); Remove fprintf. > Source/WebKit/NetworkProcess/cache/NetworkCache.h:76 > +}; We normally do not add ; for namespaces. We could add // NetworkCache comments as well.
Rob Buis
Comment 27 2020-02-07 00:41:10 PST
Rob Buis
Comment 28 2020-02-07 00:42:48 PST
Comment on attachment 388839 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388839&action=review >> Source/WebKit/NetworkProcess/cache/NetworkCache.cpp:341 >> + fprintf(stderr, "browsingContextRemoved cancel!!!\n"); > > Remove fprintf. Ouch! Maybe there should be a pre upload warning hook to protect me :) Fixed. >> Source/WebKit/NetworkProcess/cache/NetworkCache.h:76 >> +}; > > We normally do not add ; for namespaces. > We could add // NetworkCache comments as well. Sure, done.
youenn fablet
Comment 29 2020-02-24 02:48:07 PST
Comment on attachment 390061 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=390061&action=review > Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:72 > + if (m_networkLoad) { We could also write it if (!m_networkLoad) return;
Rob Buis
Comment 30 2020-02-24 06:02:44 PST
WebKit Commit Bot
Comment 31 2020-02-24 07:50:44 PST
Comment on attachment 391530 [details] Patch Clearing flags on attachment: 391530 Committed r257206: <https://trac.webkit.org/changeset/257206>
WebKit Commit Bot
Comment 32 2020-02-24 07:50:46 PST
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 33 2020-02-24 07:51:17 PST
Carlos Alberto Lopez Perez
Comment 34 2020-03-16 20:50:07 PDT
Comment on attachment 391530 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=391530&action=review > Source/WebCore/ChangeLog:11 > + Test: imported/w3c/web-platform-tests/fetch/stale-while-revalidate/frame-removal.html Has this test been merged into WPT? I can't see it on wpt/master. Is there any PR open for it?
Rob Buis
Comment 35 2020-03-17 01:41:31 PDT
(In reply to Carlos Alberto Lopez Perez from comment #34) > Comment on attachment 391530 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=391530&action=review > > > Source/WebCore/ChangeLog:11 > > + Test: imported/w3c/web-platform-tests/fetch/stale-while-revalidate/frame-removal.html > > Has this test been merged into WPT? I can't see it on wpt/master. Is there > any PR open for it? Good find, I started to try to add it here: https://github.com/web-platform-tests/wpt/pull/22292
Note You need to log in before you can comment on or make changes to this bug.