Title: [221506] trunk/Source
Revision
221506
Author
commit-qu...@webkit.org
Date
2017-09-01 16:28:09 -0700 (Fri, 01 Sep 2017)

Log Message

Do not Reject CacheStorage promises when updating the persistent filesystem data fails
https://bugs.webkit.org/show_bug.cgi?id=176241

Patch by Youenn Fablet <you...@apple.com> on 2017-09-01
Reviewed by Alex Christensen.

Source/WebCore:

Open/Remove caches may succeed in updating the memory representation but the write-to-disk operation may fail.
In that case, the corresponding promise is now resolved since the web page can still proceeed.

There is no way to test that currently as this would require a write disk failure to be triggered.

* Modules/cache/CacheStorage.cpp:
(WebCore::logConsolePersistencyError):
(WebCore::CacheStorage::open):
(WebCore::CacheStorage::remove):
* Modules/cache/DOMCacheEngine.h:
(WebCore::DOMCacheEngine::CacheIdentifierOperationResult::encode const):
(WebCore::DOMCacheEngine::CacheIdentifierOperationResult::decode):

Source/WebKit:

Open/Remove caches may succeed in the memory representation but the write-to-disk operation may fail.
In that case, the callback does not return an error but a value containing the cache identifier.
The value will also contain a boolean flag set to true to notify the client that persistent storage failed this time.

* NetworkProcess/cache/CacheStorageEngine.cpp:
(WebKit::CacheStorage::Engine::open):
(WebKit::CacheStorage::Engine::remove):
* NetworkProcess/cache/CacheStorageEngineCaches.cpp:
(WebKit::CacheStorage::Caches::open):
(WebKit::CacheStorage::Caches::remove):
* NetworkProcess/cache/CacheStorageEngineCaches.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (221505 => 221506)


--- trunk/Source/WebCore/ChangeLog	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebCore/ChangeLog	2017-09-01 23:28:09 UTC (rev 221506)
@@ -1,5 +1,25 @@
 2017-09-01  Youenn Fablet  <you...@apple.com>
 
+        Do not Reject CacheStorage promises when updating the persistent filesystem data fails
+        https://bugs.webkit.org/show_bug.cgi?id=176241
+
+        Reviewed by Alex Christensen.
+
+        Open/Remove caches may succeed in updating the memory representation but the write-to-disk operation may fail.
+        In that case, the corresponding promise is now resolved since the web page can still proceeed.
+
+        There is no way to test that currently as this would require a write disk failure to be triggered.
+
+        * Modules/cache/CacheStorage.cpp:
+        (WebCore::logConsolePersistencyError):
+        (WebCore::CacheStorage::open):
+        (WebCore::CacheStorage::remove):
+        * Modules/cache/DOMCacheEngine.h:
+        (WebCore::DOMCacheEngine::CacheIdentifierOperationResult::encode const):
+        (WebCore::DOMCacheEngine::CacheIdentifierOperationResult::decode):
+
+2017-09-01  Youenn Fablet  <you...@apple.com>
+
         [Fetch API] Add support for consuming a Request ReadableStream body
         https://bugs.webkit.org/show_bug.cgi?id=176182
 

Modified: trunk/Source/WebCore/Modules/cache/CacheStorage.cpp (221505 => 221506)


--- trunk/Source/WebCore/Modules/cache/CacheStorage.cpp	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebCore/Modules/cache/CacheStorage.cpp	2017-09-01 23:28:09 UTC (rev 221506)
@@ -165,6 +165,14 @@
     });
 }
 
+static void logConsolePersistencyError(ScriptExecutionContext* context, const String& cacheName)
+{
+    if (!context)
+        return;
+
+    context->addConsoleMessage(MessageSource::JS, MessageLevel::Error, makeString("There was an error making ", cacheName, " persistent on the filesystem"));
+}
+
 void CacheStorage::open(const String& name, DOMPromiseDeferred<IDLInterface<DOMCache>>&& promise)
 {
     retrieveCaches([this, name, promise = WTFMove(promise)](std::optional<Exception>&& exception) mutable {
@@ -189,7 +197,10 @@
                 if (!result.hasValue())
                     promise.reject(DOMCacheEngine::errorToException(result.error()));
                 else {
-                    auto cache = DOMCache::create(*scriptExecutionContext(), String { name }, result.value(), m_connection.copyRef());
+                    if (result.value().hadStorageError)
+                        logConsolePersistencyError(scriptExecutionContext(), name);
+
+                    auto cache = DOMCache::create(*scriptExecutionContext(), String { name }, result.value().identifier, m_connection.copyRef());
                     promise.resolve(cache);
                     m_caches.append(WTFMove(cache));
                 }
@@ -221,8 +232,11 @@
             if (!m_isStopped) {
                 if (!result.hasValue())
                     promise.reject(DOMCacheEngine::errorToException(result.error()));
-                else
+                else {
+                    if (result.value().hadStorageError)
+                        logConsolePersistencyError(scriptExecutionContext(), name);
                     promise.resolve(true);
+                }
             }
             unsetPendingActivity(this);
         });

Modified: trunk/Source/WebCore/Modules/cache/DOMCacheEngine.h (221505 => 221506)


--- trunk/Source/WebCore/Modules/cache/DOMCacheEngine.h	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebCore/Modules/cache/DOMCacheEngine.h	2017-09-01 23:28:09 UTC (rev 221506)
@@ -83,7 +83,16 @@
     uint64_t updateCounter;
 };
 
-using CacheIdentifierOrError = Expected<uint64_t, Error>;
+struct CacheIdentifierOperationResult {
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static bool decode(Decoder&, CacheIdentifierOperationResult&);
+
+    uint64_t identifier { 0 };
+    // True in case storing cache list on the filesystem failed.
+    bool hadStorageError { false };
+};
+
+using CacheIdentifierOrError = Expected<CacheIdentifierOperationResult, Error>;
 using CacheIdentifierCallback = WTF::Function<void(const CacheIdentifierOrError&)>;
 
 using RecordIdentifiersOrError = Expected<Vector<uint64_t>, Error>;
@@ -111,6 +120,20 @@
     return decoder.decode(cacheInfos.updateCounter);
 }
 
+template<class Encoder> inline void CacheIdentifierOperationResult::encode(Encoder& encoder) const
+{
+    encoder << identifier;
+    encoder << hadStorageError;
+}
+
+template<class Decoder> inline bool CacheIdentifierOperationResult::decode(Decoder& decoder, CacheIdentifierOperationResult& result)
+{
+    if (!decoder.decode(result.identifier))
+        return false;
+
+    return decoder.decode(result.hadStorageError);
+}
+
 } // namespace DOMCacheEngine
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp (221505 => 221506)


--- trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebCore/Modules/cache/WorkerCacheStorageConnection.cpp	2017-09-01 23:28:09 UTC (rev 221506)
@@ -133,7 +133,7 @@
         ASSERT(m_mainThreadConnection);
 
         m_mainThreadConnection->remove(cacheIdentifier, [this, protectedThis = WTFMove(protectedThis), requestIdentifier, cacheIdentifier](const CacheIdentifierOrError& result) mutable {
-            ASSERT(!result.hasValue() || result.value() == cacheIdentifier);
+            ASSERT(!result.hasValue() || result.value().identifier == cacheIdentifier);
             m_proxy.postTaskForModeToWorkerGlobalScope([this, protectedThis = WTFMove(protectedThis), requestIdentifier, result](ScriptExecutionContext& context) mutable {
                 ASSERT_UNUSED(context, context.isWorkerGlobalScope());
                 removeCompleted(requestIdentifier, result);

Modified: trunk/Source/WebKit/ChangeLog (221505 => 221506)


--- trunk/Source/WebKit/ChangeLog	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebKit/ChangeLog	2017-09-01 23:28:09 UTC (rev 221506)
@@ -1,3 +1,22 @@
+2017-09-01  Youenn Fablet  <you...@apple.com>
+
+        Do not Reject CacheStorage promises when updating the persistent filesystem data fails
+        https://bugs.webkit.org/show_bug.cgi?id=176241
+
+        Reviewed by Alex Christensen.
+
+        Open/Remove caches may succeed in the memory representation but the write-to-disk operation may fail.
+        In that case, the callback does not return an error but a value containing the cache identifier.
+        The value will also contain a boolean flag set to true to notify the client that persistent storage failed this time.
+
+        * NetworkProcess/cache/CacheStorageEngine.cpp:
+        (WebKit::CacheStorage::Engine::open):
+        (WebKit::CacheStorage::Engine::remove):
+        * NetworkProcess/cache/CacheStorageEngineCaches.cpp:
+        (WebKit::CacheStorage::Caches::open):
+        (WebKit::CacheStorage::Caches::remove):
+        * NetworkProcess/cache/CacheStorageEngineCaches.h:
+
 2017-09-01  Alex Christensen  <achristen...@webkit.org>
 
         Add WKUIDelegatePrivate equivalent of WKPageUIClient's toolbarsAreVisible

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp (221505 => 221506)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp	2017-09-01 23:28:09 UTC (rev 221506)
@@ -90,16 +90,7 @@
             return;
         }
 
-        Caches& caches = cachesOrError.value();
-
-        if (auto* cache = caches.find(cacheName)) {
-            callback(cache->identifier());
-            return;
-        }
-
-        caches.open(String { cacheName }, [callback = WTFMove(callback)](const CacheIdentifierOrError& result) mutable {
-            callback(result);
-        });
+        cachesOrError.value().get().open(cacheName, WTFMove(callback));
     });
 }
 
@@ -118,13 +109,7 @@
         return;
     }
 
-    cachesToModify->remove(cacheIdentifier, [cacheIdentifier, callback = WTFMove(callback)](std::optional<Error>&& error) {
-        if (error) {
-            callback(makeUnexpected(error.value()));
-            return;
-        }
-        callback(cacheIdentifier);
-    });
+    cachesToModify->remove(cacheIdentifier, WTFMove(callback));
 }
 
 void Engine::retrieveCaches(const String& origin, uint64_t updateCounter, CacheInfosCallback&& callback)

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp (221505 => 221506)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp	2017-09-01 23:28:09 UTC (rev 221506)
@@ -117,24 +117,25 @@
     return (position != notFound) ? &m_removedCaches[position] : nullptr;
 }
 
-void Caches::open(String&& name, CacheIdentifierCallback&& callback)
+void Caches::open(const String& name, CacheIdentifierCallback&& callback)
 {
     ASSERT(m_engine);
 
+    if (auto* cache = find(name)) {
+        callback(CacheIdentifierOperationResult { cache->identifier(), false });
+        return;
+    }
+
     makeDirty();
 
     uint64_t cacheIdentifier = m_engine->nextCacheIdentifier();
-    m_caches.append(Cache { cacheIdentifier, WTFMove(name) });
+    m_caches.append(Cache { cacheIdentifier, String { name } });
     writeCachesToDisk([callback = WTFMove(callback), cacheIdentifier](std::optional<Error>&& error) mutable {
-        if (error) {
-            callback(makeUnexpected(error.value()));
-            return;
-        }
-        callback(cacheIdentifier);
+        callback(CacheIdentifierOperationResult { cacheIdentifier, !!error });
     });
 }
 
-void Caches::remove(uint64_t identifier, CompletionCallback&& callback)
+void Caches::remove(uint64_t identifier, CacheIdentifierCallback&& callback)
 {
     ASSERT(m_engine);
 
@@ -142,7 +143,7 @@
 
     if (position == notFound) {
         ASSERT(m_removedCaches.findMatching([&](const auto& item) { return item.identifier() == identifier; }) != notFound);
-        callback(std::nullopt);
+        callback(CacheIdentifierOperationResult { identifier, false });
         return;
     }
 
@@ -151,9 +152,10 @@
     auto cache = WTFMove(m_caches[position]);
     m_caches.remove(position);
     m_removedCaches.append(WTFMove(cache));
-    ++m_updateCounter;
 
-    writeCachesToDisk(WTFMove(callback));
+    writeCachesToDisk([callback = WTFMove(callback), identifier](std::optional<Error>&& error) mutable {
+        callback(CacheIdentifierOperationResult { identifier, !!error });
+    });
 }
 
 static inline Data encodeCacheNames(const Vector<Cache>& caches)

Modified: trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h (221505 => 221506)


--- trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	2017-09-01 22:56:15 UTC (rev 221505)
+++ trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h	2017-09-01 23:28:09 UTC (rev 221506)
@@ -39,8 +39,8 @@
     static Ref<Caches> create(Engine& engine, const String& origin) { return adoptRef(*new Caches { engine, origin }); }
 
     void initialize(WebCore::DOMCacheEngine::CompletionCallback&&);
-    void open(String&& name, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
-    void remove(uint64_t identifier, WebCore::DOMCacheEngine::CompletionCallback&&);
+    void open(const String& name, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
+    void remove(uint64_t identifier, WebCore::DOMCacheEngine::CacheIdentifierCallback&&);
     void clearMemoryRepresentation();
 
     void detach();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to