Title: [224506] trunk/Source
Revision
224506
Author
[email protected]
Date
2017-11-06 12:22:11 -0800 (Mon, 06 Nov 2017)

Log Message

[Service Workers] Add proper implementation for 'updatefound' event
https://bugs.webkit.org/show_bug.cgi?id=179302

Reviewed by Brady Eidson.

Source/WebCore:

Add proper implementation for 'updatefound' event instead of faking it.
The 'updatefound' event firing is now triggered from the StorageProcess,
during the install steps, instead of being fired on WebContent process
side in jobResolvedWithRegistration().

Specification:
- https://w3c.github.io/ServiceWorker/#install (step 7)

* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::scheduleJob):
(WebCore::ServiceWorkerContainer::fireUpdateFoundEvent):
(WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
(WebCore::ServiceWorkerContainer::jobDidFinish):
* workers/service/ServiceWorkerContainer.h:
* workers/service/server/SWClientConnection.cpp:
(WebCore::SWClientConnection::fireUpdateFoundEvent):
* workers/service/server/SWClientConnection.h:
* workers/service/server/SWServer.h:
* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::scriptContextStarted):
(WebCore::SWServerJobQueue::install):
* workers/service/server/SWServerJobQueue.h:
* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::fireUpdateFoundEvent):
* workers/service/server/SWServerRegistration.h:

Source/WebKit:

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::fireUpdateFoundEvent):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (224505 => 224506)


--- trunk/Source/WebCore/ChangeLog	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/ChangeLog	2017-11-06 20:22:11 UTC (rev 224506)
@@ -1,3 +1,36 @@
+2017-11-06  Chris Dumez  <[email protected]>
+
+        [Service Workers] Add proper implementation for 'updatefound' event
+        https://bugs.webkit.org/show_bug.cgi?id=179302
+
+        Reviewed by Brady Eidson.
+
+        Add proper implementation for 'updatefound' event instead of faking it.
+        The 'updatefound' event firing is now triggered from the StorageProcess,
+        during the install steps, instead of being fired on WebContent process
+        side in jobResolvedWithRegistration().
+
+        Specification:
+        - https://w3c.github.io/ServiceWorker/#install (step 7)
+
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::scheduleJob):
+        (WebCore::ServiceWorkerContainer::fireUpdateFoundEvent):
+        (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
+        (WebCore::ServiceWorkerContainer::jobDidFinish):
+        * workers/service/ServiceWorkerContainer.h:
+        * workers/service/server/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::fireUpdateFoundEvent):
+        * workers/service/server/SWClientConnection.h:
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::scriptContextStarted):
+        (WebCore::SWServerJobQueue::install):
+        * workers/service/server/SWServerJobQueue.h:
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::fireUpdateFoundEvent):
+        * workers/service/server/SWServerRegistration.h:
+
 2017-11-06  Christopher Reid  <[email protected]>
 
         Use enum classes within FileSystem

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (224505 => 224506)


--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp	2017-11-06 20:22:11 UTC (rev 224506)
@@ -263,22 +263,28 @@
     jobDidFinish(job);
 }
 
-class FakeServiceWorkerInstallMicrotask final : public Microtask {
+class FireUpdateFoundEventMicrotask final : public Microtask {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit FakeServiceWorkerInstallMicrotask(Ref<ServiceWorkerRegistration>&& registration)
-        : m_registration(WTFMove(registration))
+    explicit FireUpdateFoundEventMicrotask(Ref<ServiceWorkerContainer>&& container, Ref<ServiceWorkerRegistration>&& registration)
+        : m_container(WTFMove(container))
+        , m_registration(WTFMove(registration))
     {
     }
-
 private:
     Result run() final
     {
-        // FIXME: We currently resolve the promise at the end of the install instead of the beginning so we need to fake
-        // a few events to make it look like we are installing and activing the service worker.
-        callOnMainThread([registration = WTFMove(m_registration)] () mutable {
+        callOnMainThread([container = WTFMove(m_container), registration = WTFMove(m_registration)] () mutable {
+            if (container->isStopped())
+                return;
+
             registration->dispatchEvent(Event::create(eventNames().updatefoundEvent, false, false));
+
+            // FIXME: We currently fake a few events to make it look like we are installing and activating the service worker.
             callOnMainThread([registration = WTFMove(registration)] () mutable {
+                if (!registration->installing())
+                    return;
+
                 registration->setWaitingWorker(registration->installing());
                 registration->setInstallingWorker(nullptr);
                 registration->waiting()->setState(ServiceWorker::State::Installed);
@@ -295,9 +301,22 @@
         return Result::Done;
     }
 
+    Ref<ServiceWorkerContainer> m_container;
     Ref<ServiceWorkerRegistration> m_registration;
 };
 
+void ServiceWorkerContainer::fireUpdateFoundEvent(const ServiceWorkerRegistrationKey& key)
+{
+    if (isStopped())
+        return;
+
+    auto* registration = m_registrations.get(key);
+    if (!registration)
+        return;
+
+    MicrotaskQueue::mainThreadQueue().append(std::make_unique<FireUpdateFoundEventMicrotask>(*this, *registration));
+}
+
 void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job, ServiceWorkerRegistrationData&& data)
 {
     auto guard = WTF::makeScopeExit([this, &job] {
@@ -326,9 +345,6 @@
     registration->setInstallingWorker(activeServiceWorker);
 
     job.promise().resolve<IDLInterface<ServiceWorkerRegistration>>(*registration);
-
-    // Use a microtask because we need to make sure this is executed after the promise above is resolved.
-    MicrotaskQueue::mainThreadQueue().append(std::make_unique<FakeServiceWorkerInstallMicrotask>(registration.releaseNonNull()));
 }
 
 void ServiceWorkerContainer::jobResolvedWithUnregistrationResult(ServiceWorkerJob& job, bool unregistrationResult)

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (224505 => 224506)


--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h	2017-11-06 20:22:11 UTC (rev 224506)
@@ -66,6 +66,7 @@
 
     void getRegistration(const String& clientURL, Ref<DeferredPromise>&&);
     void updateRegistration(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerIdentifier>&);
+    void fireUpdateFoundEvent(const ServiceWorkerRegistrationKey&);
 
     using RegistrationsPromise = DOMPromiseDeferred<IDLSequence<IDLInterface<ServiceWorkerRegistration>>>;
     void getRegistrations(RegistrationsPromise&&);
@@ -78,6 +79,8 @@
     void ref() final { refEventTarget(); }
     void deref() final { derefEventTarget(); }
 
+    bool isStopped() const { return m_isStopped; };
+
 private:
     void scheduleJob(Ref<ServiceWorkerJob>&&);
 

Modified: trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp (224505 => 224506)


--- trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp	2017-11-06 20:22:11 UTC (rev 224506)
@@ -147,6 +147,15 @@
     }
 }
 
+void SWClientConnection::fireUpdateFoundEvent(const ServiceWorkerRegistrationKey& key)
+{
+    // FIXME: We should iterate over all service worker clients, not only documents.
+    for (auto& document : Document::allDocuments()) {
+        if (auto* container = document->serviceWorkerContainer())
+            container->fireUpdateFoundEvent(key);
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebCore/workers/service/server/SWClientConnection.h (224505 => 224506)


--- trunk/Source/WebCore/workers/service/server/SWClientConnection.h	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/server/SWClientConnection.h	2017-11-06 20:22:11 UTC (rev 224506)
@@ -67,6 +67,7 @@
     WEBCORE_EXPORT void startScriptFetchForServer(uint64_t jobIdentifier);
     WEBCORE_EXPORT void postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, Ref<SerializedScriptValue>&& message, ServiceWorkerIdentifier source, const String& sourceOrigin);
     WEBCORE_EXPORT void updateRegistrationState(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, std::optional<ServiceWorkerIdentifier>);
+    WEBCORE_EXPORT void fireUpdateFoundEvent(const ServiceWorkerRegistrationKey&);
 
 private:
     virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;

Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (224505 => 224506)


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2017-11-06 20:22:11 UTC (rev 224506)
@@ -64,6 +64,7 @@
 
         // Messages to the client WebProcess
         virtual void updateRegistrationStateInClient(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, std::optional<ServiceWorkerIdentifier>) = 0;
+        virtual void fireUpdateFoundEvent(const ServiceWorkerRegistrationKey&) = 0;
 
     protected:
         WEBCORE_EXPORT Connection(SWServer&, uint64_t identifier);

Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp (224505 => 224506)


--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp	2017-11-06 20:22:11 UTC (rev 224506)
@@ -115,7 +115,20 @@
     ASSERT(registration);
     registration->setActiveServiceWorkerIdentifier(identifier);
 
-    m_server.resolveRegistrationJob(firstJob(), registration->data());
+    install(*registration);
+}
+
+// https://w3c.github.io/ServiceWorker/#install
+void SWServerJobQueue::install(SWServerRegistration& registration)
+{
+    // Invoke Resolve Job Promise with job and registration.
+    m_server.resolveRegistrationJob(firstJob(), registration.data());
+
+    // Queue a task to fire an event named updatefound at all the ServiceWorkerRegistration objects
+    // for all the service worker clients whose creation URL matches registration's scope url and
+    // all the service workers whose containing service worker registration is registration.
+    registration.fireUpdateFoundEvent(firstJob().connectionIdentifier());
+
     finishCurrentJob();
 }
 

Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h (224505 => 224506)


--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h	2017-11-06 20:22:11 UTC (rev 224506)
@@ -63,6 +63,7 @@
 
     void tryClearRegistration(SWServerRegistration&);
     void clearRegistration(SWServerRegistration&);
+    void install(SWServerRegistration&);
 
     Deque<ServiceWorkerJobData> m_jobQueue;
 

Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp (224505 => 224506)


--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp	2017-11-06 20:22:11 UTC (rev 224506)
@@ -83,6 +83,22 @@
     }
 }
 
+void SWServerRegistration::fireUpdateFoundEvent(uint64_t connectionIdentifier)
+{
+    // No matter what, we send the event to the connection that scheduled the job. The client registration
+    // may not have gotten a chance to register itself yet.
+    if (auto* connection = m_server.getConnection(connectionIdentifier))
+        connection->fireUpdateFoundEvent(m_registrationKey);
+
+    for (auto& connectionIdentifierWithClients : m_clientRegistrationsByConnection.keys()) {
+        if (connectionIdentifierWithClients == connectionIdentifier)
+            continue;
+
+        if (auto* connection = m_server.getConnection(connectionIdentifierWithClients))
+            connection->fireUpdateFoundEvent(m_registrationKey);
+    }
+}
+
 ServiceWorkerRegistrationData SWServerRegistration::data() const
 {
     return { m_registrationKey, identifier(), m_activeServiceWorkerIdentifier, m_scopeURL, m_scriptURL, m_updateViaCache };

Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.h (224505 => 224506)


--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.h	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.h	2017-11-06 20:22:11 UTC (rev 224506)
@@ -58,6 +58,7 @@
     void setActiveServiceWorkerIdentifier(ServiceWorkerIdentifier identifier) { m_activeServiceWorkerIdentifier = identifier; }
 
     void updateRegistrationState(ServiceWorkerRegistrationState, SWServerWorker*);
+    void fireUpdateFoundEvent(uint64_t connectionIdentifier);
 
     void addClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier);
     void removeClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier);

Modified: trunk/Source/WebKit/ChangeLog (224505 => 224506)


--- trunk/Source/WebKit/ChangeLog	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebKit/ChangeLog	2017-11-06 20:22:11 UTC (rev 224506)
@@ -1,3 +1,15 @@
+2017-11-06  Chris Dumez  <[email protected]>
+
+        [Service Workers] Add proper implementation for 'updatefound' event
+        https://bugs.webkit.org/show_bug.cgi?id=179302
+
+        Reviewed by Brady Eidson.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::fireUpdateFoundEvent):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+
 2017-11-06  Christopher Reid  <[email protected]>
 
         Use enum classes within FileSystem

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (224505 => 224506)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2017-11-06 20:22:11 UTC (rev 224506)
@@ -101,6 +101,11 @@
     send(Messages::WebSWClientConnection::UpdateRegistrationState(key, state, serviceWorkerIdentifier));
 }
 
+void WebSWServerConnection::fireUpdateFoundEvent(const ServiceWorkerRegistrationKey& key)
+{
+    send(Messages::WebSWClientConnection::FireUpdateFoundEvent(key));
+}
+
 void WebSWServerConnection::updateServiceWorkerContext(const ServiceWorkerContextData& data)
 {
     if (sendToContextProcess(Messages::WebSWContextManagerConnection::UpdateServiceWorker(identifier(), data)))

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h (224505 => 224506)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h	2017-11-06 20:22:11 UTC (rev 224506)
@@ -66,6 +66,7 @@
     void resolveUnregistrationJobInClient(uint64_t jobIdentifier, const WebCore::ServiceWorkerRegistrationKey&, bool unregistrationResult) final;
     void startScriptFetchInClient(uint64_t jobIdentifier) final;
     void updateRegistrationStateInClient(const WebCore::ServiceWorkerRegistrationKey&, WebCore::ServiceWorkerRegistrationState, std::optional<WebCore::ServiceWorkerIdentifier>) final;
+    void fireUpdateFoundEvent(const WebCore::ServiceWorkerRegistrationKey&) final;
 
     void startFetch(uint64_t fetchIdentifier, std::optional<WebCore::ServiceWorkerIdentifier>, const WebCore::ResourceRequest&, const WebCore::FetchOptions&);
 

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in (224505 => 224506)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in	2017-11-06 20:20:28 UTC (rev 224505)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in	2017-11-06 20:22:11 UTC (rev 224506)
@@ -29,6 +29,7 @@
     UnregistrationJobResolvedInServer(uint64_t identifier, bool unregistrationResult)
     StartScriptFetchForServer(uint64_t jobIdentifier)
     UpdateRegistrationState(WebCore::ServiceWorkerRegistrationKey key, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerIdentifier> serviceWorkerIdentifier)
+    FireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationKey key)
 
     SetSWOriginTableSharedMemory(WebKit::SharedMemory::Handle handle)
     PostMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, IPC::DataReference message, WebCore::ServiceWorkerIdentifier sourceServiceWorkerIdentifier, String sourceOrigin)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to