Title: [224341] trunk/Source/WebCore
Revision
224341
Author
[email protected]
Date
2017-11-02 10:38:57 -0700 (Thu, 02 Nov 2017)

Log Message

Update SWServerJobQueue to follow the Service Worker specification more closely
https://bugs.webkit.org/show_bug.cgi?id=179147

Reviewed by Youenn Fablet.

Align naming with the specification.

Get rid of unnecessary m_currentJob as the current job is always the first
job in the queue.

Inline some of the tiny methods to simplify code. Those were leftovers from when
we used to have a background thread.

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::scheduleJob):
* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::SWServerJobQueue):
(WebCore::SWServerJobQueue::scriptFetchFinished):
(WebCore::SWServerJobQueue::scriptContextStarted):
(WebCore::SWServerJobQueue::runNextJob):
(WebCore::SWServerJobQueue::runNextJobSynchronously):
(WebCore::SWServerJobQueue::runRegisterJob):
(WebCore::SWServerJobQueue::runUnregisterJob):
(WebCore::SWServerJobQueue::runUpdateJob):
(WebCore::SWServerJobQueue::rejectCurrentJob):
(WebCore::SWServerJobQueue::finishCurrentJob):
* workers/service/server/SWServerJobQueue.h:
(WebCore::SWServerJobQueue::firstJob const):
(WebCore::SWServerJobQueue::lastJob const):
(WebCore::SWServerJobQueue::enqueueJob):
(WebCore::SWServerJobQueue::size const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (224340 => 224341)


--- trunk/Source/WebCore/ChangeLog	2017-11-02 17:24:02 UTC (rev 224340)
+++ trunk/Source/WebCore/ChangeLog	2017-11-02 17:38:57 UTC (rev 224341)
@@ -1,3 +1,37 @@
+2017-11-02  Chris Dumez  <[email protected]>
+
+        Update SWServerJobQueue to follow the Service Worker specification more closely
+        https://bugs.webkit.org/show_bug.cgi?id=179147
+
+        Reviewed by Youenn Fablet.
+
+        Align naming with the specification.
+
+        Get rid of unnecessary m_currentJob as the current job is always the first
+        job in the queue.
+
+        Inline some of the tiny methods to simplify code. Those were leftovers from when
+        we used to have a background thread.
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::scheduleJob):
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::SWServerJobQueue):
+        (WebCore::SWServerJobQueue::scriptFetchFinished):
+        (WebCore::SWServerJobQueue::scriptContextStarted):
+        (WebCore::SWServerJobQueue::runNextJob):
+        (WebCore::SWServerJobQueue::runNextJobSynchronously):
+        (WebCore::SWServerJobQueue::runRegisterJob):
+        (WebCore::SWServerJobQueue::runUnregisterJob):
+        (WebCore::SWServerJobQueue::runUpdateJob):
+        (WebCore::SWServerJobQueue::rejectCurrentJob):
+        (WebCore::SWServerJobQueue::finishCurrentJob):
+        * workers/service/server/SWServerJobQueue.h:
+        (WebCore::SWServerJobQueue::firstJob const):
+        (WebCore::SWServerJobQueue::lastJob const):
+        (WebCore::SWServerJobQueue::enqueueJob):
+        (WebCore::SWServerJobQueue::size const):
+
 2017-11-02  Konstantin Tokarev  <[email protected]>
 
         Unreviewed, removed useless semicolon at the end of namespace

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (224340 => 224341)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2017-11-02 17:24:02 UTC (rev 224340)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2017-11-02 17:38:57 UTC (rev 224341)
@@ -116,17 +116,21 @@
     });
 }
 
+// https://w3c.github.io/ServiceWorker/#schedule-job-algorithm
 void SWServer::scheduleJob(const ServiceWorkerJobData& jobData)
 {
     ASSERT(m_connections.contains(jobData.connectionIdentifier()));
 
-    auto result = m_jobQueues.add(jobData.registrationKey(), nullptr);
-    if (result.isNewEntry)
-        result.iterator->value = std::make_unique<SWServerJobQueue>(*this, jobData.registrationKey());
+    // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
+    // If it is, stack it along with that job.
 
-    ASSERT(result.iterator->value);
+    auto& jobQueue = *m_jobQueues.ensure(jobData.registrationKey(), [this, &jobData] {
+        return std::make_unique<SWServerJobQueue>(*this, jobData.registrationKey());
+    }).iterator->value;
 
-    result.iterator->value->enqueueJob(jobData);
+    jobQueue.enqueueJob(jobData);
+    if (jobQueue.size() == 1)
+        jobQueue.runNextJob();
 }
 
 void SWServer::rejectJob(const ServiceWorkerJobData& jobData, const ExceptionData& exceptionData)

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


--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp	2017-11-02 17:24:02 UTC (rev 224340)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp	2017-11-02 17:38:57 UTC (rev 224341)
@@ -40,7 +40,7 @@
 namespace WebCore {
 
 SWServerJobQueue::SWServerJobQueue(SWServer& server, const ServiceWorkerRegistrationKey& key)
-    : m_jobTimer(*this, &SWServerJobQueue::startNextJob)
+    : m_jobTimer(*this, &SWServerJobQueue::runNextJobSynchronously)
     , m_server(server)
     , m_registrationKey(key)
 {
@@ -51,29 +51,16 @@
     ASSERT(m_jobQueue.isEmpty());
 }
 
-void SWServerJobQueue::enqueueJob(const ServiceWorkerJobData& jobData)
-{
-    // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
-    // If it is, stack it along with that job.
-
-    m_jobQueue.append(jobData);
-
-    if (m_currentJob)
-        return;
-
-    if (!m_jobTimer.isActive())
-        m_jobTimer.startOneShot(0_s);
-}
-
 void SWServerJobQueue::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result)
 {
-    ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier);
+    auto& job = firstJob();
+    ASSERT(job.identifier() == result.jobIdentifier);
 
     auto* registration = m_server.getRegistration(m_registrationKey);
     ASSERT(registration);
 
     if (!result.scriptError.isNull()) {
-        rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) });
+        rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", job.scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) });
 
         // If newestWorker is null, invoke Clear Registration algorithm passing this registration as its argument.
         if (!registration->getNewestWorker())
@@ -86,7 +73,7 @@
     // then resolve and finish the job without doing anything further.
 
     // FIXME: Support the proper worker type (classic vs module)
-    m_server.updateWorker(connection, m_registrationKey, m_currentJob->scriptURL, result.script, WorkerType::Classic);
+    m_server.updateWorker(connection, m_registrationKey, job.scriptURL, result.script, WorkerType::Classic);
 }
 
 void SWServerJobQueue::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message)
@@ -107,22 +94,28 @@
     auto* registration = m_server.getRegistration(m_registrationKey);
     ASSERT(registration);
     registration->setActiveServiceWorkerIdentifier(serviceWorkerIdentifier);
-    resolveCurrentRegistrationJob(registration->data());
+
+    m_server.resolveRegistrationJob(firstJob(), registration->data());
+    finishCurrentJob();
 }
 
-void SWServerJobQueue::startNextJob()
+// https://w3c.github.io/ServiceWorker/#run-job
+void SWServerJobQueue::runNextJob()
 {
-    ASSERT(!m_currentJob);
     ASSERT(!m_jobQueue.isEmpty());
+    ASSERT(!m_jobTimer.isActive());
+    m_jobTimer.startOneShot(0_s);
+}
 
-    m_currentJob = std::make_unique<ServiceWorkerJobData>(m_jobQueue.takeFirst());
-
-    switch (m_currentJob->type) {
+void SWServerJobQueue::runNextJobSynchronously()
+{
+    auto& job = firstJob();
+    switch (job.type) {
     case ServiceWorkerJobType::Register:
-        runRegisterJob(*m_currentJob);
+        runRegisterJob(job);
         return;
     case ServiceWorkerJobType::Unregister:
-        runUnregisterJob(*m_currentJob);
+        runUnregisterJob(job);
         return;
     }
 
@@ -129,6 +122,7 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+// https://w3c.github.io/ServiceWorker/#register-algorithm
 void SWServerJobQueue::runRegisterJob(const ServiceWorkerJobData& job)
 {
     ASSERT(job.type == ServiceWorkerJobType::Register);
@@ -149,7 +143,8 @@
         registration->setIsUninstalling(false);
         auto* newestWorker = registration->getNewestWorker();
         if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == registration->updateViaCache()) {
-            resolveCurrentRegistrationJob(registration->data());
+            m_server.resolveRegistrationJob(firstJob(), registration->data());
+            finishCurrentJob();
             return;
         }
     } else {
@@ -160,6 +155,7 @@
     runUpdateJob(job);
 }
 
+// https://w3c.github.io/ServiceWorker/#unregister-algorithm
 void SWServerJobQueue::runUnregisterJob(const ServiceWorkerJobData& job)
 {
     // If the origin of job’s scope url is not job's client's origin, then:
@@ -172,7 +168,8 @@
     // If registration is null, then:
     if (!registration || registration->isUninstalling()) {
         // Invoke Resolve Job Promise with job and false.
-        resolveCurrentUnregistrationJob(false);
+        m_server.resolveUnregistrationJob(firstJob(), m_registrationKey, false);
+        finishCurrentJob();
         return;
     }
 
@@ -180,10 +177,11 @@
     registration->setIsUninstalling(true);
 
     // Invoke Resolve Job Promise with job and true.
-    resolveCurrentUnregistrationJob(true);
+    m_server.resolveUnregistrationJob(firstJob(), m_registrationKey, true);
 
     // Invoke Try Clear Registration with registration.
     tryClearRegistration(*registration);
+    finishCurrentJob();
 }
 
 // https://w3c.github.io/ServiceWorker/#try-clear-registration-algorithm
@@ -203,6 +201,7 @@
     m_server.removeRegistration(registration.key());
 }
 
+// https://w3c.github.io/ServiceWorker/#update-algorithm
 void SWServerJobQueue::runUpdateJob(const ServiceWorkerJobData& job)
 {
     auto* registration = m_server.getRegistration(m_registrationKey);
@@ -218,56 +217,24 @@
     if (newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
         return rejectCurrentJob(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") });
 
-    startScriptFetchForCurrentJob();
+    m_server.startScriptFetch(job);
 }
 
 void SWServerJobQueue::rejectCurrentJob(const ExceptionData& exceptionData)
 {
-    ASSERT(m_currentJob);
+    m_server.rejectJob(firstJob(), exceptionData);
 
-    m_server.rejectJob(*m_currentJob, exceptionData);
-
     finishCurrentJob();
 }
 
-void SWServerJobQueue::resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData& data)
-{
-    ASSERT(m_currentJob);
-    ASSERT(m_currentJob->type == ServiceWorkerJobType::Register);
-
-    m_server.resolveRegistrationJob(*m_currentJob, data);
-
-    finishCurrentJob();
-}
-
-void SWServerJobQueue::resolveCurrentUnregistrationJob(bool unregistrationResult)
-{
-    ASSERT(m_currentJob);
-    ASSERT(m_currentJob->type == ServiceWorkerJobType::Unregister);
-
-    m_server.resolveUnregistrationJob(*m_currentJob, m_registrationKey, unregistrationResult);
-
-    finishCurrentJob();
-}
-
-void SWServerJobQueue::startScriptFetchForCurrentJob()
-{
-    ASSERT(m_currentJob);
-
-    m_server.startScriptFetch(*m_currentJob);
-}
-
+// https://w3c.github.io/ServiceWorker/#finish-job
 void SWServerJobQueue::finishCurrentJob()
 {
-    ASSERT(m_currentJob);
     ASSERT(!m_jobTimer.isActive());
 
-    m_currentJob = nullptr;
-    if (m_jobQueue.isEmpty())
-        return;
-
-    ASSERT(!m_jobTimer.isActive());
-    m_jobTimer.startOneShot(0_s);
+    m_jobQueue.removeFirst();
+    if (!m_jobQueue.isEmpty())
+        runNextJob();
 }
 
 } // namespace WebCore

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


--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h	2017-11-02 17:24:02 UTC (rev 224340)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h	2017-11-02 17:38:57 UTC (rev 224341)
@@ -40,7 +40,13 @@
     SWServerJobQueue(const SWServerRegistration&) = delete;
     ~SWServerJobQueue();
 
-    void enqueueJob(const ServiceWorkerJobData&);
+    const ServiceWorkerJobData& firstJob() const { return m_jobQueue.first(); }
+    const ServiceWorkerJobData& lastJob() const { return m_jobQueue.last(); }
+    void enqueueJob(const ServiceWorkerJobData& jobData) { m_jobQueue.append(jobData); }
+    size_t size() const { return m_jobQueue.size(); }
+
+    void runNextJob();
+
     void scriptFetchFinished(SWServer::Connection&, const ServiceWorkerFetchResult&);
     void scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message);
     void scriptContextStarted(SWServer::Connection&, uint64_t serviceWorkerIdentifier, const String& workerID);
@@ -47,11 +53,8 @@
 
 private:
     void jobTimerFired();
-    void startNextJob();
+    void runNextJobSynchronously();
     void rejectCurrentJob(const ExceptionData&);
-    void resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData&);
-    void resolveCurrentUnregistrationJob(bool unregistrationResult);
-    void startScriptFetchForCurrentJob();
     void finishCurrentJob();
 
     void runRegisterJob(const ServiceWorkerJobData&);
@@ -62,7 +65,6 @@
     void clearRegistration(SWServerRegistration&);
 
     Deque<ServiceWorkerJobData> m_jobQueue;
-    std::unique_ptr<ServiceWorkerJobData> m_currentJob;
 
     Timer m_jobTimer;
     SWServer& m_server;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to