⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 283438 in webkit


Ignore:
Timestamp:
Oct 2, 2021, 4:57:48 AM (5 years ago)
Author:
youenn@apple.com
Message:

Add support for ServiceWorkerGlobalScope push event handler
https://bugs.webkit.org/show_bug.cgi?id=231008
<rdar://problem/83710760>

Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

  • web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt:

Source/WebCore:

Implement https://w3c.github.io/push-api/#receiving-a-push-message step 6.
In particular we ensure that if any waitUntil promise rejects, the push event is considered to fail.
This status should then be sent back to the emiter of the push message to decide whether to acknowledge the message, retry it or discard it.

We keep push API completion handler in a map to ensure we respond to them even if the service worker gets terminated while processing the push event.

Add necessary internals API to enable testing within the service worker itself.

Covered by added subtests in http/wpt/service-workers/pushEvent.any.serviceworker.html.

  • CMakeLists.txt:
  • DerivedSources-input.xcfilelist:
  • DerivedSources-output.xcfilelist:
  • DerivedSources.make:
  • Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl: Added.
  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/WebCoreBuiltinNames.h:
  • dom/EventNames.h:
  • testing/ServiceWorkerInternals.cpp:
  • testing/ServiceWorkerInternals.h:
  • testing/ServiceWorkerInternals.idl:
  • workers/service/context/SWContextManager.cpp:
  • workers/service/context/SWContextManager.h:
  • workers/service/context/ServiceWorkerThread.cpp:
  • workers/service/context/ServiceWorkerThread.h:
  • workers/service/context/ServiceWorkerThreadProxy.cpp:
  • workers/service/context/ServiceWorkerThreadProxy.h:

LayoutTests:

  • http/wpt/push-api/pushEvent.any.js:
  • http/wpt/push-api/pushEvent.any.serviceworker-expected.txt:
Location:
trunk
Files:
1 added
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r283435 r283438  
     12021-10-02  Youenn Fablet  <youenn@apple.com>
     2
     3        Add support for ServiceWorkerGlobalScope push event handler
     4        https://bugs.webkit.org/show_bug.cgi?id=231008
     5        <rdar://problem/83710760>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * http/wpt/push-api/pushEvent.any.js:
     10        * http/wpt/push-api/pushEvent.any.serviceworker-expected.txt:
     11
    1122021-10-01  Commit Queue  <commit-queue@webkit.org>
    213
  • trunk/LayoutTests/http/wpt/push-api/pushEvent.any.js

    r283377 r283438  
    5353    assert_throws_dom("SyntaxError", () => event.data.json());
    5454}, "PushEvent with bad json");
     55
     56let activatePromise = new Promise(resolve => self.onactivate = resolve);
     57promise_test(async () => {
     58   return activatePromise;
     59}, "Wait for activate promise");
     60
     61promise_test(async () => {
     62    const promise = self.internals.schedulePushEvent("test");
     63    const event = await new Promise(resolve => self.onpush = resolve);
     64    assert_equals(event.data.text(), "test");
     65    assert_true(await promise);
     66}, "Simulating firing of a push event");
     67
     68promise_test(async () => {
     69    if (!self.internals)
     70        return;
     71
     72    let resolveWaitUntilPromise;
     73    const waitUntilPromise = new Promise(resolve => resolveWaitUntilPromise = resolve);
     74
     75    let isPushEventPromiseResolved = false;
     76    const promise = internals.schedulePushEvent("test");
     77    promise.then(() => isPushEventPromiseResolved = true);
     78
     79    const event = await new Promise(resolve => self.onpush = (event) => {
     80        event.waitUntil(waitUntilPromise);
     81        resolve(event);
     82    });
     83    assert_equals(event.data.text(), "test");
     84
     85    await new Promise(resolve => self.setTimeout(resolve, 100));
     86    assert_false(isPushEventPromiseResolved);
     87
     88    resolveWaitUntilPromise();
     89    assert_true(await promise);
     90}, "Simulating firing of a push event - successful waitUntil");
     91
     92promise_test(async () => {
     93    if (!self.internals)
     94        return;
     95
     96    const promise = internals.schedulePushEvent("test");
     97    const event = await new Promise(resolve => self.onpush = (event) => {
     98        event.waitUntil(Promise.resolve());
     99        event.waitUntil(Promise.reject('error'));
     100        resolve(event);
     101    });
     102    assert_equals(event.data.text(), "test");
     103    assert_false(await promise);
     104}, "Simulating firing of a push event - unsuccessful waitUntil");
  • trunk/LayoutTests/http/wpt/push-api/pushEvent.any.serviceworker-expected.txt

    r283377 r283438  
    44PASS PushEvent arrayBuffer handling
    55PASS PushEvent with bad json
     6PASS Wait for activate promise
     7PASS Simulating firing of a push event
     8PASS Simulating firing of a push event - successful waitUntil
     9PASS Simulating firing of a push event - unsuccessful waitUntil
    610
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r283434 r283438  
     12021-10-02  Youenn Fablet  <youenn@apple.com>
     2
     3        Add support for ServiceWorkerGlobalScope push event handler
     4        https://bugs.webkit.org/show_bug.cgi?id=231008
     5        <rdar://problem/83710760>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt:
     10
    1112021-10-01  Nikos Mouchtaris  <nmouchtaris@apple.com>
    212
  • trunk/LayoutTests/imported/w3c/web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt

    r283377 r283438  
    8080FAIL ServiceWorkerRegistration interface: attribute pushManager assert_true: The prototype object must have a property "pushManager" expected true got false
    8181FAIL ServiceWorkerRegistration interface: registration must inherit property "pushManager" with the proper type assert_inherits: property "pushManager" not found in prototype chain
    82 FAIL ServiceWorkerGlobalScope interface: attribute onpush assert_own_property: The global object must have a property "onpush" expected property "onpush" missing
     82PASS ServiceWorkerGlobalScope interface: attribute onpush
    8383FAIL ServiceWorkerGlobalScope interface: attribute onpushsubscriptionchange assert_own_property: The global object must have a property "onpushsubscriptionchange" expected property "onpushsubscriptionchange" missing
    84 FAIL ServiceWorkerGlobalScope interface: self must inherit property "onpush" with the proper type assert_own_property: expected property "onpush" missing
     84PASS ServiceWorkerGlobalScope interface: self must inherit property "onpush" with the proper type
    8585FAIL ServiceWorkerGlobalScope interface: self must inherit property "onpushsubscriptionchange" with the proper type assert_own_property: expected property "onpushsubscriptionchange" missing
    8686
  • trunk/Source/WebCore/CMakeLists.txt

    r283377 r283438  
    502502    Modules/push-api/PushEventInit.idl
    503503    Modules/push-api/PushMessageData.idl
     504    Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl
    504505
    505506    Modules/remoteplayback/RemotePlayback.idl
  • trunk/Source/WebCore/ChangeLog

    r283437 r283438  
     12021-10-02  Youenn Fablet  <youenn@apple.com>
     2
     3        Add support for ServiceWorkerGlobalScope push event handler
     4        https://bugs.webkit.org/show_bug.cgi?id=231008
     5        <rdar://problem/83710760>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Implement https://w3c.github.io/push-api/#receiving-a-push-message step 6.
     10        In particular we ensure that if any waitUntil promise rejects, the push event is considered to fail.
     11        This status should then be sent back to the emiter of the push message to decide whether to acknowledge the message, retry it or discard it.
     12
     13        We keep push API completion handler in a map to ensure we respond to them even if the service worker gets terminated while processing the push event.
     14
     15        Add necessary internals API to enable testing within the service worker itself.
     16
     17        Covered by added subtests in http/wpt/service-workers/pushEvent.any.serviceworker.html.
     18
     19        * CMakeLists.txt:
     20        * DerivedSources-input.xcfilelist:
     21        * DerivedSources-output.xcfilelist:
     22        * DerivedSources.make:
     23        * Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl: Added.
     24        * WebCore.xcodeproj/project.pbxproj:
     25        * bindings/js/WebCoreBuiltinNames.h:
     26        * dom/EventNames.h:
     27        * testing/ServiceWorkerInternals.cpp:
     28        * testing/ServiceWorkerInternals.h:
     29        * testing/ServiceWorkerInternals.idl:
     30        * workers/service/context/SWContextManager.cpp:
     31        * workers/service/context/SWContextManager.h:
     32        * workers/service/context/ServiceWorkerThread.cpp:
     33        * workers/service/context/ServiceWorkerThread.h:
     34        * workers/service/context/ServiceWorkerThreadProxy.cpp:
     35        * workers/service/context/ServiceWorkerThreadProxy.h:
     36
    1372021-10-02  Philippe Normand  <pnormand@igalia.com>
    238
  • trunk/Source/WebCore/DerivedSources-input.xcfilelist

    r283377 r283438  
    425425$(PROJECT_DIR)/Modules/push-api/PushEventInit.idl
    426426$(PROJECT_DIR)/Modules/push-api/PushMessageData.idl
     427$(PROJECT_DIR)/Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl
    427428$(PROJECT_DIR)/Modules/remoteplayback/HTMLMediaElement+RemotePlayback.idl
    428429$(PROJECT_DIR)/Modules/remoteplayback/RemotePlayback.idl
  • trunk/Source/WebCore/DerivedSources-output.xcfilelist

    r283377 r283438  
    22302230$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerContainer.cpp
    22312231$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerContainer.h
     2232$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope+PushAPI.cpp
     2233$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope+PushAPI.h
    22322234$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope.cpp
    22332235$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope.h
  • trunk/Source/WebCore/DerivedSources.make

    r283377 r283438  
    350350    $(WebCore)/Modules/push-api/PushEventInit.idl \
    351351    $(WebCore)/Modules/push-api/PushMessageData.idl \
     352    $(WebCore)/Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl \
    352353    $(WebCore)/Modules/remoteplayback/HTMLMediaElement+RemotePlayback.idl \
    353354    $(WebCore)/Modules/remoteplayback/RemotePlayback.idl \
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r283377 r283438  
    81148114                418FCBC02706E4F800F96ECA /* PushEvent.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushEvent.idl; sourceTree = "<group>"; };
    81158115                418FCBC32706E62C00F96ECA /* PushEventInit.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushEventInit.idl; sourceTree = "<group>"; };
     8116                418FCBCB2706F3CD00F96ECA /* ServiceWorkerGlobalScope+PushAPI.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ServiceWorkerGlobalScope+PushAPI.idl"; sourceTree = "<group>"; };
     8117                418FCBCC2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerGlobalScopePushAPI.h; sourceTree = "<group>"; };
     8118                418FCBCD2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerGlobalScopePushAPI.cpp; sourceTree = "<group>"; };
    81168119                4190F3A1249D152700531C57 /* FrameRateMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameRateMonitor.cpp; sourceTree = "<group>"; };
    81178120                4190F3A3249D152800531C57 /* FrameRateMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameRateMonitor.h; sourceTree = "<group>"; };
     
    1988419887                                418FCBBC2706E4F600F96ECA /* PushMessageData.h */,
    1988519888                                418FCBBA2706E4F500F96ECA /* PushMessageData.idl */,
     19889                                418FCBCB2706F3CD00F96ECA /* ServiceWorkerGlobalScope+PushAPI.idl */,
     19890                                418FCBCD2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.cpp */,
     19891                                418FCBCC2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.h */,
    1988619892                        );
    1988719893                        path = "push-api";
  • trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h

    r283377 r283438  
    403403    macro(matchingElementInFlatTree) \
    404404    macro(mediaStreamTrackConstraints) \
    405     macro(openDatabase) \
     405    macro(onpush) \
    406406    macro(onrtctransform) \
    407407    macro(ontouchcancel) \
     
    418418    macro(onvrdisplayfocus) \
    419419    macro(onvrdisplaypresentchange) \
     420    macro(openDatabase) \
    420421    macro(opener) \
    421422    macro(operations) \
  • trunk/Source/WebCore/dom/EventNames.h

    r282198 r283438  
    222222    macro(processorerror) \
    223223    macro(progress) \
     224    macro(push) \
    224225    macro(ratechange) \
    225226    macro(readystatechange) \
  • trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp

    r282860 r283438  
    5555    callOnMainThread([identifier = m_identifier] () {
    5656        SWContextManager::singleton().terminateWorker(identifier, Seconds::infinity(), [] { });
     57    });
     58}
     59
     60void ServiceWorkerInternals::schedulePushEvent(const String& message, RefPtr<DeferredPromise>&& promise)
     61{
     62    auto counter = ++m_pushEventCounter;
     63    m_pushEventPromises.add(counter, WTFMove(promise));
     64
     65    std::optional<Vector<uint8_t>> data;
     66    if (!message.isNull()) {
     67        auto utf8 = message.utf8();
     68        data = Vector<uint8_t> { reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length()};
     69    }
     70    callOnMainThread([identifier = m_identifier, data = WTFMove(data), weakThis = makeWeakPtr(this), counter]() mutable {
     71        SWContextManager::singleton().firePushEvent(identifier, WTFMove(data), [identifier, weakThis = WTFMove(weakThis), counter](bool result) mutable {
     72            if (auto* proxy = SWContextManager::singleton().workerByID(identifier)) {
     73                proxy->thread().runLoop().postTaskForMode([weakThis = WTFMove(weakThis), counter, result](auto&) {
     74                    if (!weakThis)
     75                        return;
     76                    if (auto promise = weakThis->m_pushEventPromises.take(counter))
     77                        promise->resolve<IDLBoolean>(result);
     78                }, WorkerRunLoop::defaultMode());
     79            }
     80        });
    5781    });
    5882}
  • trunk/Source/WebCore/testing/ServiceWorkerInternals.h

    r279750 r283438  
    5353    Ref<FetchResponse> createOpaqueWithBlobBodyResponse(ScriptExecutionContext&);
    5454
     55    void schedulePushEvent(const String&, RefPtr<DeferredPromise>&&);
    5556    Vector<String> fetchResponseHeaderList(FetchResponse&);
    5657
     
    6869    ServiceWorkerIdentifier m_identifier;
    6970    RefPtr<DeferredPromise> m_lastNavigationWasAppInitiatedPromise;
     71    HashMap<uint64_t, RefPtr<DeferredPromise>> m_pushEventPromises;
     72    uint64_t m_pushEventCounter { 0 };
    7073};
    7174
  • trunk/Source/WebCore/testing/ServiceWorkerInternals.idl

    r279750 r283438  
    3939    sequence<ByteString> fetchResponseHeaderList(FetchResponse response);
    4040
     41    Promise<boolean> schedulePushEvent(optional DOMString data);
     42
    4143    readonly attribute DOMString processName;
    4244    readonly attribute boolean isThrottleable;
  • trunk/Source/WebCore/workers/service/context/SWContextManager.cpp

    r282860 r283438  
    110110}
    111111
     112void SWContextManager::firePushEvent(ServiceWorkerIdentifier identifier, std::optional<Vector<uint8_t>>&& data, CompletionHandler<void(bool)>&& callback)
     113{
     114    auto* serviceWorker = m_workerMap.get(identifier);
     115    if (!serviceWorker) {
     116        callback(false);
     117        return;
     118    }
     119
     120    serviceWorker->firePushEvent(WTFMove(data), WTFMove(callback));
     121}
     122
     123
    112124void SWContextManager::terminateWorker(ServiceWorkerIdentifier identifier, Seconds timeout, Function<void()>&& completionHandler)
    113125{
  • trunk/Source/WebCore/workers/service/context/SWContextManager.h

    r279583 r283438  
    9191    WEBCORE_EXPORT void fireInstallEvent(ServiceWorkerIdentifier);
    9292    WEBCORE_EXPORT void fireActivateEvent(ServiceWorkerIdentifier);
     93    WEBCORE_EXPORT void firePushEvent(ServiceWorkerIdentifier, std::optional<Vector<uint8_t>>&&, CompletionHandler<void(bool)>&&);
     94
    9395    WEBCORE_EXPORT void terminateWorker(ServiceWorkerIdentifier, Seconds timeout, Function<void()>&&);
    9496    WEBCORE_EXPORT void didSaveScriptsToDisk(ServiceWorkerIdentifier, ScriptBuffer&&, HashMap<URL, ScriptBuffer>&& importedScripts);
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp

    r283295 r283438  
    3838#include "Logging.h"
    3939#include "PlatformStrategies.h"
     40#include "PushEvent.h"
    4041#include "SWContextManager.h"
    4142#include "SecurityOrigin.h"
     
    213214}
    214215
     216void ServiceWorkerThread::queueTaskToFirePushEvent(std::optional<Vector<uint8_t>>&& data, Function<void(bool)>&& callback)
     217{
     218    auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(*globalScope());
     219    serviceWorkerGlobalScope.eventLoop().queueTask(TaskSource::DOMManipulation, [weakThis = makeWeakPtr(this), serviceWorkerGlobalScope = Ref { serviceWorkerGlobalScope }, data = WTFMove(data), callback = WTFMove(callback)]() mutable {
     220        RELEASE_LOG(ServiceWorker, "ServiceWorkerThread::queueTaskToFirePushEvent firing event for worker %" PRIu64, serviceWorkerGlobalScope->thread().identifier().toUInt64());
     221
     222        auto pushEvent = PushEvent::create(eventNames().pushEvent, { }, WTFMove(data), ExtendableEvent::IsTrusted::Yes);
     223        serviceWorkerGlobalScope->dispatchEvent(pushEvent);
     224
     225        pushEvent->whenAllExtendLifetimePromisesAreSettled([weakThis = WTFMove(weakThis), callback = WTFMove(callback)](auto&& extendLifetimePromises) mutable {
     226            bool hasRejectedAnyPromise = false;
     227            for (auto& promise : extendLifetimePromises) {
     228                if (promise->status() == DOMPromise::Status::Rejected) {
     229                    hasRejectedAnyPromise = true;
     230                    break;
     231                }
     232            }
     233            callback(!hasRejectedAnyPromise);
     234        });
     235    });
     236}
     237
    215238void ServiceWorkerThread::finishedEvaluatingScript()
    216239{
     
    245268}
    246269
     270void ServiceWorkerThread::startPushEventMonitoring()
     271{
     272    m_isHandlingPushEvent = true;
     273    startHeartBeatTimer();
     274}
     275
    247276void ServiceWorkerThread::startHeartBeatTimer()
    248277{
     
    267296{
    268297    if (!m_ongoingHeartBeatCheck) {
    269         if (m_state == State::Installing || m_state == State::Activating || m_isHandlingFetchEvent || m_messageEventCount)
     298        if (m_state == State::Installing || m_state == State::Activating || m_isHandlingFetchEvent || m_isHandlingPushEvent || m_messageEventCount)
    270299            startHeartBeatTimer();
    271300        return;
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h

    r283295 r283438  
    6767    void queueTaskToFireInstallEvent();
    6868    void queueTaskToFireActivateEvent();
     69    void queueTaskToFirePushEvent(std::optional<Vector<uint8_t>>&&, Function<void(bool)>&&);
    6970
    7071    ServiceWorkerIdentifier identifier() const { return m_serviceWorkerIdentifier; }
     
    7475    void startFetchEventMonitoring();
    7576    void stopFetchEventMonitoring() { m_isHandlingFetchEvent = false; }
     77    void startPushEventMonitoring();
     78    void stopPushEventMonitoring() { m_isHandlingPushEvent = false; }
    7679
    7780protected:
     
    102105
    103106    bool m_isHandlingFetchEvent { false };
     107    bool m_isHandlingPushEvent { false };
    104108    uint64_t m_messageEventCount { 0 };
    105109    enum class State { Idle, Starting, Installing, Activating };
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp

    r283295 r283438  
    123123    ASSERT(allServiceWorkerThreadProxies().contains(this));
    124124    allServiceWorkerThreadProxies().remove(this);
     125
     126    auto pushTasks = WTFMove(m_ongoingPushTasks);
     127    for (auto& callback : pushTasks.values())
     128        callback(false);
    125129}
    126130
     
    295299}
    296300
     301void ServiceWorkerThreadProxy::firePushEvent(std::optional<Vector<uint8_t>>&& data, CompletionHandler<void(bool)>&& callback)
     302{
     303    if (m_ongoingPushTasks.isEmpty())
     304        thread().startPushEventMonitoring();
     305
     306    auto identifier = ++m_pushTasksCounter;
     307    ASSERT(!m_ongoingPushTasks.contains(identifier));
     308    m_ongoingPushTasks.add(identifier, WTFMove(callback));
     309    bool isPosted = postTaskForModeToWorkerOrWorkletGlobalScope([this, protectedThis = Ref { *this }, identifier, data = WTFMove(data)](auto&) mutable {
     310        thread().queueTaskToFirePushEvent(WTFMove(data), [this, protectedThis = WTFMove(protectedThis), identifier](bool result) mutable {
     311            callOnMainThread([this, protectedThis = WTFMove(protectedThis), identifier, result]() mutable {
     312                if (auto callback = m_ongoingPushTasks.take(identifier))
     313                    callback(result);
     314                if (m_ongoingPushTasks.isEmpty())
     315                    thread().stopPushEventMonitoring();
     316            });
     317        });
     318    }, WorkerRunLoop::defaultMode());
     319    if (!isPosted)
     320        m_ongoingPushTasks.take(identifier)(false);
     321}
     322
    297323} // namespace WebCore
    298324
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h

    r283295 r283438  
    8181    void fireInstallEvent();
    8282    void fireActivateEvent();
     83    void firePushEvent(std::optional<Vector<uint8_t>>&&, CompletionHandler<void(bool)>&&);
     84
    8385    void didSaveScriptsToDisk(ScriptBuffer&&, HashMap<URL, ScriptBuffer>&& importedScripts);
    8486
     
    113115    ServiceWorkerInspectorProxy m_inspectorProxy;
    114116    HashMap<std::pair<SWServerConnectionIdentifier, FetchIdentifier>, Ref<ServiceWorkerFetch::Client>> m_ongoingFetchTasks;
     117    uint64_t m_pushTasksCounter { 0 };
     118    HashMap<uint64_t, CompletionHandler<void(bool)>> m_ongoingPushTasks;
    115119};
    116120
Note: See TracChangeset for help on using the changeset viewer.