Changeset 225460 in webkit


Ignore:
Timestamp:
Dec 3, 2017 12:32:57 PM (6 years ago)
Author:
Chris Dumez
Message:

Implement self.skipWaiting() inside service workers
https://bugs.webkit.org/show_bug.cgi?id=180329

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaseline WPT tests that are now passing.

  • web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/claim-with-redirect.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/postmessage-from-waiting-serviceworker.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/skip-waiting-without-client.https-expected.txt:

Source/WebCore:

Implement self.skipWaiting() inside service workers:

Also fixes a bug where tryActivate() was calling activate() even though the
registration's active worker was "in use":

No new tests, rebaselined existing tests.

  • workers/service/ServiceWorkerGlobalScope.cpp:

(WebCore::ServiceWorkerGlobalScope::skipWaiting):

  • workers/service/context/SWContextManager.h:
  • workers/service/server/SWServerRegistration.cpp:

(WebCore::SWServerRegistration::tryActivate):

  • workers/service/server/SWServerToContextConnection.cpp:

(WebCore::SWServerToContextConnection::skipWaiting):

  • workers/service/server/SWServerToContextConnection.h:
  • workers/service/server/SWServerWorker.cpp:

(WebCore::SWServerWorker::skipWaiting):

  • workers/service/server/SWServerWorker.h:

(WebCore::SWServerWorker::isSkipWaitingFlagSet const):

Source/WebKit:

  • StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:

(WebKit::WebSWServerToContextConnection::didFinishSkipWaiting):

  • StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
  • StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
  • WebProcess/Storage/WebSWContextManagerConnection.cpp:

(WebKit::WebSWContextManagerConnection::skipWaiting):
(WebKit::WebSWContextManagerConnection::didFinishSkipWaiting):

  • WebProcess/Storage/WebSWContextManagerConnection.h:
  • WebProcess/Storage/WebSWContextManagerConnection.messages.in:

LayoutTests:

  • http/tests/workers/service/resources/service-worker-fetch-worker.js:

add self.skipWaiting() now that we properly wait when the registation's
active worker is in use. This is needed because this worker script is
used by http/tests/workers/service/controller-change.html. The
'controllerchange' event is only fired if an active worker is being
replaced while in use due to the waiting worker calling skipWaiting().

Location:
trunk
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r225456 r225460  
     12017-12-03  Chris Dumez  <cdumez@apple.com>
     2
     3        Implement self.skipWaiting() inside service workers
     4        https://bugs.webkit.org/show_bug.cgi?id=180329
     5
     6        Reviewed by Darin Adler.
     7
     8        * http/tests/workers/service/resources/service-worker-fetch-worker.js:
     9        add self.skipWaiting() now that we properly wait when the registation's
     10        active worker is in use. This is needed because this worker script is
     11        used by http/tests/workers/service/controller-change.html. The
     12        'controllerchange' event is only fired if an active worker is being
     13        replaced while in use due to the waiting worker calling skipWaiting().
     14
    1152017-12-02  Chris Dumez  <cdumez@apple.com>
    216
  • trunk/LayoutTests/http/tests/workers/service/resources/service-worker-fetch-worker.js

    r224903 r225460  
    11var status = "no status";
     2
     3self.skipWaiting();
     4
    25self.addEventListener("fetch", (event) => {
    36    if (event.request.url.indexOf("status") !== -1) {
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r225456 r225460  
     12017-12-03  Chris Dumez  <cdumez@apple.com>
     2
     3        Implement self.skipWaiting() inside service workers
     4        https://bugs.webkit.org/show_bug.cgi?id=180329
     5
     6        Reviewed by Darin Adler.
     7
     8        Rebaseline WPT tests that are now passing.
     9
     10        * web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https-expected.txt:
     11        * web-platform-tests/service-workers/service-worker/claim-with-redirect.https-expected.txt:
     12        * web-platform-tests/service-workers/service-worker/postmessage-from-waiting-serviceworker.https-expected.txt:
     13        * web-platform-tests/service-workers/service-worker/skip-waiting-without-client.https-expected.txt:
     14
    1152017-12-02  Chris Dumez  <cdumez@apple.com>
    216
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https-expected.txt

    r225455 r225460  
    11
     2PASS Update a registration on ServiceWorkerGlobalScope
    23
    3 FAIL Update a registration on ServiceWorkerGlobalScope assert_equals: events seen by the worker expected "updatefound,activate,fetch,message,updatefound,fetch" but got "updatefound,activate,fetch"
    4 
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/claim-with-redirect.https-expected.txt

    r225346 r225460  
    1 CONSOLE MESSAGE: line 27: Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'r.update')
    21 
    32
    4 FAIL Claim works after redirection to another origin assert_equals: expected (string) "updated" but got (undefined) undefined
     3PASS Claim works after redirection to another origin
    54
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/postmessage-from-waiting-serviceworker.https-expected.txt

    r224469 r225460  
    11
     2PASS Client.postMessage() from waiting serviceworker.
    23
    3 FAIL Client.postMessage() from waiting serviceworker. assert_unreached: unexpected rejection: assert_equals: message event source should be correct expected null but got object "[object ServiceWorker]" Reached unreachable code
    4 
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-client.https-expected.txt

    r225364 r225460  
    11
    22PASS Test single skipWaiting() when no client attached
    3 FAIL skipWaiting promise_test: Unhandled rejection with value: object "NotSupportedError: self.skipWaiting() is not yet supported"
     3PASS skipWaiting
    44
  • trunk/Source/WebCore/ChangeLog

    r225459 r225460  
     12017-12-03  Chris Dumez  <cdumez@apple.com>
     2
     3        Implement self.skipWaiting() inside service workers
     4        https://bugs.webkit.org/show_bug.cgi?id=180329
     5
     6        Reviewed by Darin Adler.
     7
     8        Implement self.skipWaiting() inside service workers:
     9        - https://w3c.github.io/ServiceWorker/#service-worker-global-scope-skipwaiting
     10
     11        Also fixes a bug where tryActivate() was calling activate() even though the
     12        registration's active worker was "in use":
     13        - https://w3c.github.io/ServiceWorker/#try-activate-algorithm
     14
     15        No new tests, rebaselined existing tests.
     16
     17        * workers/service/ServiceWorkerGlobalScope.cpp:
     18        (WebCore::ServiceWorkerGlobalScope::skipWaiting):
     19        * workers/service/context/SWContextManager.h:
     20        * workers/service/server/SWServerRegistration.cpp:
     21        (WebCore::SWServerRegistration::tryActivate):
     22        * workers/service/server/SWServerToContextConnection.cpp:
     23        (WebCore::SWServerToContextConnection::skipWaiting):
     24        * workers/service/server/SWServerToContextConnection.h:
     25        * workers/service/server/SWServerWorker.cpp:
     26        (WebCore::SWServerWorker::skipWaiting):
     27        * workers/service/server/SWServerWorker.h:
     28        (WebCore::SWServerWorker::isSkipWaitingFlagSet const):
     29
    1302017-12-03  Carlos Garcia Campos  <cgarcia@igalia.com>
    231
  • trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp

    r225427 r225460  
    5151void ServiceWorkerGlobalScope::skipWaiting(Ref<DeferredPromise>&& promise)
    5252{
    53     // FIXME: Implement this.
    54     promise->reject(Exception { NotSupportedError, ASCIILiteral("self.skipWaiting() is not yet supported") });
     53    callOnMainThread([this, protectedThis = makeRef(*this), threadIdentifier = thread().identifier(), promise = WTFMove(promise)]() mutable {
     54        if (auto* connection = SWContextManager::singleton().connection()) {
     55            connection->skipWaiting(threadIdentifier, [this, protectedThis = WTFMove(protectedThis), promise = WTFMove(promise)]() mutable {
     56                thread().runLoop().postTask([promise = WTFMove(promise), protectedThis = WTFMove(protectedThis)](auto&) {
     57                    promise->resolve();
     58                });
     59            });
     60        }
     61    });
    5562}
    5663
  • trunk/Source/WebCore/workers/service/context/SWContextManager.h

    r225452 r225460  
    5555        virtual void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool) = 0;
    5656        virtual void workerTerminated(ServiceWorkerIdentifier) = 0;
     57        virtual void skipWaiting(ServiceWorkerIdentifier, WTF::Function<void()>&& callback) = 0;
    5758
    5859        using FindClientByIdentifierCallback = WTF::CompletionHandler<void(ExceptionOr<std::optional<ServiceWorkerClientData>>&&)>;
  • trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp

    r225457 r225460  
    233233    // - registration's active worker is null.
    234234    // - The result of running Service Worker Has No Pending Events with registration's active worker is true,
    235     //   and no service worker client is using registration
    236     // FIXME: Check for the skip waiting flag.
    237     if (!activeWorker() || !activeWorker()->hasPendingEvents())
     235    //   and no service worker client is using registration or registration's waiting worker's skip waiting flag is set.
     236    if (!activeWorker() || (!activeWorker()->hasPendingEvents() && (!hasClientsUsingRegistration() || waitingWorker()->isSkipWaitingFlagSet())))
    238237        activate();
    239238}
  • trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp

    r225452 r225460  
    124124}
    125125
     126void SWServerToContextConnection::skipWaiting(ServiceWorkerIdentifier serviceWorkerIdentifier, uint64_t callbackID)
     127{
     128    if (auto* worker = SWServerWorker::existingWorkerForIdentifier(serviceWorkerIdentifier))
     129        worker->skipWaiting();
     130
     131    didFinishSkipWaiting(callbackID);
     132}
     133
    126134} // namespace WebCore
    127135
  • trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h

    r225452 r225460  
    5656    virtual void findClientByIdentifierCompleted(uint64_t requestIdentifier, const std::optional<ServiceWorkerClientData>&, bool hasSecurityError) = 0;
    5757    virtual void matchAllCompleted(uint64_t requestIdentifier, const Vector<ServiceWorkerClientInformation>&) = 0;
     58    virtual void didFinishSkipWaiting(uint64_t callbackID) = 0;
    5859
    5960    // Messages back from the SW host process
     
    6364    WEBCORE_EXPORT void didFinishActivation(ServiceWorkerIdentifier);
    6465    WEBCORE_EXPORT void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool hasPendingEvents);
     66    WEBCORE_EXPORT void skipWaiting(ServiceWorkerIdentifier, uint64_t callbackID);
    6567    WEBCORE_EXPORT void workerTerminated(ServiceWorkerIdentifier);
    6668    WEBCORE_EXPORT void findClientByIdentifier(uint64_t clientIdRequestIdentifier, ServiceWorkerIdentifier, ServiceWorkerClientIdentifier);
  • trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp

    r225452 r225460  
    117117}
    118118
     119void SWServerWorker::skipWaiting()
     120{
     121    m_isSkipWaitingFlagSet = true;
     122
     123    auto* registration = m_server.getRegistration(m_registrationKey);
     124    ASSERT(registration);
     125    registration->tryActivate();
     126}
     127
    119128} // namespace WebCore
    120129
  • trunk/Source/WebCore/workers/service/server/SWServerWorker.h

    r225452 r225460  
    9292    void matchAll(const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&);
    9393
     94    void skipWaiting();
     95    bool isSkipWaitingFlagSet() const { return m_isSkipWaitingFlagSet; }
     96
    9497    WEBCORE_EXPORT static SWServerWorker* existingWorkerForIdentifier(ServiceWorkerIdentifier);
    9598
     
    109112    State m_state { State::NotRunning };
    110113    mutable std::optional<ClientOrigin> m_origin;
     114    bool m_isSkipWaitingFlagSet { false };
    111115};
    112116
  • trunk/Source/WebKit/ChangeLog

    r225452 r225460  
     12017-12-03  Chris Dumez  <cdumez@apple.com>
     2
     3        Implement self.skipWaiting() inside service workers
     4        https://bugs.webkit.org/show_bug.cgi?id=180329
     5
     6        Reviewed by Darin Adler.
     7
     8        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
     9        (WebKit::WebSWServerToContextConnection::didFinishSkipWaiting):
     10        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
     11        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
     12        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
     13        (WebKit::WebSWContextManagerConnection::skipWaiting):
     14        (WebKit::WebSWContextManagerConnection::didFinishSkipWaiting):
     15        * WebProcess/Storage/WebSWContextManagerConnection.h:
     16        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
     17
    1182017-12-02  Youenn Fablet  <youenn@apple.com>
    219
  • trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp

    r225452 r225460  
    9292}
    9393
     94void WebSWServerToContextConnection::didFinishSkipWaiting(uint64_t callbackID)
     95{
     96    send(Messages::WebSWContextManagerConnection::DidFinishSkipWaiting { callbackID });
     97}
     98
    9499} // namespace WebKit
    95100
  • trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h

    r225452 r225460  
    6363    void findClientByIdentifierCompleted(uint64_t requestIdentifier, const std::optional<WebCore::ServiceWorkerClientData>&, bool hasSecurityError) final;
    6464    void matchAllCompleted(uint64_t requestIdentifier, const Vector<WebCore::ServiceWorkerClientInformation>&) final;
     65    void didFinishSkipWaiting(uint64_t callbackID) final;
    6566
    6667    Ref<IPC::Connection> m_ipcConnection;
  • trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in

    r225452 r225460  
    3131    DidFinishActivation(WebCore::ServiceWorkerIdentifier identifier);
    3232    SetServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier identifier, bool hasPendingEvents);
     33    SkipWaiting(WebCore::ServiceWorkerIdentifier identifier, uint64_t callbackID)
    3334    WorkerTerminated(WebCore::ServiceWorkerIdentifier identifier);
    3435    FindClientByIdentifier(uint64_t requestIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, struct WebCore::ServiceWorkerClientIdentifier clientIdentifier);
  • trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp

    r225452 r225460  
    198198}
    199199
     200void WebSWContextManagerConnection::skipWaiting(ServiceWorkerIdentifier serviceWorkerIdentifier, WTF::Function<void()>&& callback)
     201{
     202    auto callbackID = ++m_previousRequestIdentifier;
     203    m_skipWaitingRequests.add(callbackID, WTFMove(callback));
     204    m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::SkipWaiting(serviceWorkerIdentifier, callbackID), 0);
     205}
     206
    200207void WebSWContextManagerConnection::workerTerminated(ServiceWorkerIdentifier serviceWorkerIdentifier)
    201208{
     
    234241}
    235242
     243void WebSWContextManagerConnection::didFinishSkipWaiting(uint64_t callbackID)
     244{
     245    if (auto callback = m_skipWaitingRequests.take(callbackID))
     246        callback();
     247}
     248
    236249} // namespace WebCore
    237250
  • trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h

    r225452 r225460  
    6767    void findClientByIdentifier(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerClientIdentifier, FindClientByIdentifierCallback&&) final;
    6868    void matchAll(WebCore::ServiceWorkerIdentifier, const WebCore::ServiceWorkerClientQueryOptions&, WebCore::ServiceWorkerClientsMatchAllCallback&&) final;
     69    void skipWaiting(WebCore::ServiceWorkerIdentifier, WTF::Function<void()>&& callback) final;
    6970
    7071    // IPC messages.
     
    7980    void findClientByIdentifierCompleted(uint64_t requestIdentifier, std::optional<WebCore::ServiceWorkerClientData>&&, bool hasSecurityError);
    8081    void matchAllCompleted(uint64_t matchAllRequestIdentifier, Vector<WebCore::ServiceWorkerClientInformation>&&);
     82    void didFinishSkipWaiting(uint64_t callbackID);
    8183
    8284    Ref<IPC::Connection> m_connectionToStorageProcess;
     
    8688    HashMap<uint64_t, FindClientByIdentifierCallback> m_findClientByIdentifierRequests;
    8789    HashMap<uint64_t, WebCore::ServiceWorkerClientsMatchAllCallback> m_matchAllRequests;
     90    HashMap<uint64_t, WTF::Function<void()>> m_skipWaitingRequests;
    8891    uint64_t m_previousRequestIdentifier { 0 };
    8992};
  • trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in

    r225452 r225460  
    3333    FindClientByIdentifierCompleted(uint64_t clientIdRequestIdentifier, std::optional<WebCore::ServiceWorkerClientData> data, bool hasSecurityError)
    3434    MatchAllCompleted(uint64_t matchAllRequestIdentifier, Vector<WebCore::ServiceWorkerClientInformation> clientsData)
     35    DidFinishSkipWaiting(uint64_t callbackID)
    3536}
    3637
Note: See TracChangeset for help on using the changeset viewer.