Overly aggressive timer throttling in service workers
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 May 2018 22:31:40 +0000 (22:31 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 May 2018 22:31:40 +0000 (22:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185575
<rdar://problem/40219038>

Reviewed by Geoff Garen.

After ~30 seconds, the system would put the service worker process in "App Nap",
causing its timers to get aggressively throttled. This happens because the
service worker processes are WebProcesses that have no visible WebPages.

To address the issue, we now disable process suppression for all service worker
processes. This causes those processes to construct a UserActivity which prevents
App Nap.

This patch also refactors the code a bit to avoid duplication. The ProcessSuppression
suppression logic in now all on ChildProcessProxy / ChildProcess.

* NetworkProcess/NetworkProcess.messages.in:
* PluginProcess/PluginProcess.messages.in:
* Shared/ChildProcess.messages.in:
* UIProcess/ChildProcessProxy.cpp:
(WebKit::ChildProcessProxy::setProcessSuppressionEnabled):
* UIProcess/ChildProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/mac/NetworkProcessProxyMac.mm: Removed.
* UIProcess/Plugins/PluginProcessProxy.h:
* UIProcess/Plugins/mac/PluginProcessProxyMac.mm:
* UIProcess/ServiceWorkerProcessProxy.cpp:
(WebKit::ServiceWorkerProcessProxy::didFinishLaunching):
* UIProcess/ServiceWorkerProcessProxy.h:
* UIProcess/WebProcessProxy.h:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebProcess.messages.in:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231771 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.messages.in
Source/WebKit/PluginProcess/PluginProcess.messages.in
Source/WebKit/Shared/ChildProcess.messages.in
Source/WebKit/UIProcess/ChildProcessProxy.cpp
Source/WebKit/UIProcess/ChildProcessProxy.h
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit/UIProcess/Network/mac/NetworkProcessProxyMac.mm [deleted file]
Source/WebKit/UIProcess/Plugins/PluginProcessProxy.h
Source/WebKit/UIProcess/Plugins/mac/PluginProcessProxyMac.mm
Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp
Source/WebKit/UIProcess/ServiceWorkerProcessProxy.h
Source/WebKit/UIProcess/WebProcessProxy.h
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/WebProcess.messages.in

index 2ef3654..96da974 100644 (file)
@@ -1,3 +1,39 @@
+2018-05-14  Chris Dumez  <cdumez@apple.com>
+
+        Overly aggressive timer throttling in service workers
+        https://bugs.webkit.org/show_bug.cgi?id=185575
+        <rdar://problem/40219038>
+
+        Reviewed by Geoff Garen.
+
+        After ~30 seconds, the system would put the service worker process in "App Nap",
+        causing its timers to get aggressively throttled. This happens because the
+        service worker processes are WebProcesses that have no visible WebPages.
+
+        To address the issue, we now disable process suppression for all service worker
+        processes. This causes those processes to construct a UserActivity which prevents
+        App Nap.
+
+        This patch also refactors the code a bit to avoid duplication. The ProcessSuppression
+        suppression logic in now all on ChildProcessProxy / ChildProcess.
+
+        * NetworkProcess/NetworkProcess.messages.in:
+        * PluginProcess/PluginProcess.messages.in:
+        * Shared/ChildProcess.messages.in:
+        * UIProcess/ChildProcessProxy.cpp:
+        (WebKit::ChildProcessProxy::setProcessSuppressionEnabled):
+        * UIProcess/ChildProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/mac/NetworkProcessProxyMac.mm: Removed.
+        * UIProcess/Plugins/PluginProcessProxy.h:
+        * UIProcess/Plugins/mac/PluginProcessProxyMac.mm:
+        * UIProcess/ServiceWorkerProcessProxy.cpp:
+        (WebKit::ServiceWorkerProcessProxy::didFinishLaunching):
+        * UIProcess/ServiceWorkerProcessProxy.h:
+        * UIProcess/WebProcessProxy.h:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebProcess.messages.in:
+
 2018-05-14  Andy Estes  <aestes@apple.com>
 
         [Wi-Fi Assertions] Allow clients to specify a context identifier
index 1ad1bb4..563a565 100644 (file)
@@ -52,7 +52,6 @@ messages -> NetworkProcess LegacyReceiver {
     ContinueWillSendRequest(WebKit::DownloadID downloadID, WebCore::ResourceRequest request)
     ContinueDecidePendingDownloadDestination(WebKit::DownloadID downloadID, String destination, WebKit::SandboxExtension::Handle sandboxExtensionHandle, bool allowOverwrite)
 
-    SetProcessSuppressionEnabled(bool flag)
 #if PLATFORM(COCOA)
     SetQOS(int latencyQOS, int throughputQOS)
     SetCookieStoragePartitioningEnabled(bool enabled)
index 1792f92..f346f7e 100644 (file)
@@ -38,7 +38,6 @@ messages -> PluginProcess LegacyReceiver {
     DeleteWebsiteData(WallTime modifiedSince, uint64_t callbackID)
     DeleteWebsiteDataForHostNames(Vector<String> hostNames, uint64_t callbackID)
 
-    SetProcessSuppressionEnabled(bool flag)
 #if PLATFORM(COCOA)
     SetQOS(int latencyQOS, int throughputQOS)
 #endif
index 062691f..1dd1b1a 100644 (file)
@@ -23,4 +23,5 @@
 messages -> ChildProcess {
     ShutDown()
     RegisterURLSchemeServiceWorkersCanHandle(String scheme)
+    SetProcessSuppressionEnabled(bool flag)
 }
index 96511fd..bdff583 100644 (file)
@@ -213,6 +213,18 @@ void ChildProcessProxy::shutDownProcess()
     m_connection = nullptr;
 }
 
+void ChildProcessProxy::setProcessSuppressionEnabled(bool processSuppressionEnabled)
+{
+#if PLATFORM(COCOA)
+    if (state() != State::Running)
+        return;
+
+    connection()->send(Messages::ChildProcess::SetProcessSuppressionEnabled(processSuppressionEnabled), 0);
+#else
+    UNUSED_PARAM(processSuppressionEnabled);
+#endif
+}
+
 void ChildProcessProxy::connectionWillOpen(IPC::Connection&)
 {
 }
index 6d4802f..2d5f15c 100644 (file)
@@ -83,6 +83,8 @@ public:
 
     WebCore::ProcessIdentifier coreProcessIdentifier() const { return m_processIdentifier; }
 
+    void setProcessSuppressionEnabled(bool);
+
 protected:
     // ProcessLauncher::Client
     void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
index 6c690f3..8fc94db 100644 (file)
@@ -76,10 +76,6 @@ public:
     void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WallTime modifiedSince, WTF::Function<void()>&& completionHandler);
     void deleteWebsiteDataForOrigins(PAL::SessionID, OptionSet<WebKit::WebsiteDataType>, const Vector<WebCore::SecurityOriginData>& origins, const Vector<String>& cookieHostNames, WTF::Function<void()>&& completionHandler);
 
-#if PLATFORM(COCOA)
-    void setProcessSuppressionEnabled(bool);
-#endif
-
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void hasStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback);
     void getAllStorageAccessEntries(PAL::SessionID, CompletionHandler<void(Vector<String>&& domains)>&&);
diff --git a/Source/WebKit/UIProcess/Network/mac/NetworkProcessProxyMac.mm b/Source/WebKit/UIProcess/Network/mac/NetworkProcessProxyMac.mm
deleted file mode 100644 (file)
index b8601e8..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-#import "NetworkProcessProxy.h"
-
-#import "NetworkProcessMessages.h"
-
-using namespace WebCore;
-
-namespace WebKit {
-
-void NetworkProcessProxy::setProcessSuppressionEnabled(bool processSuppressionEnabled)
-{
-    if (state() != State::Running)
-        return;
-    
-    connection()->send(Messages::NetworkProcess::SetProcessSuppressionEnabled(processSuppressionEnabled), 0);
-}
-
-} // namespace WebKit
index 2530ffe..6c30970 100644 (file)
@@ -84,11 +84,6 @@ public:
 
     bool isValid() const { return m_connection; }
 
-#if PLATFORM(COCOA)
-    void setProcessSuppressionEnabled(bool);
-
-#endif
-
 #if PLUGIN_ARCHITECTURE(UNIX)
     static bool scanPlugin(const String& pluginPath, RawPluginMetaData& result);
 #endif
index b7f7f1c..73a132e 100644 (file)
@@ -230,14 +230,6 @@ void PluginProcessProxy::applicationDidBecomeActive()
     makePluginProcessTheFrontProcess();
 }
 
-void PluginProcessProxy::setProcessSuppressionEnabled(bool processSuppressionEnabled)
-{
-    if (!isValid())
-        return;
-
-    m_connection->send(Messages::PluginProcess::SetProcessSuppressionEnabled(processSuppressionEnabled), 0);
-}
-
 static bool isFlashUpdater(const String& launchPath, const Vector<String>& arguments)
 {
     if (launchPath != "/Applications/Utilities/Adobe Flash Player Install Manager.app/Contents/MacOS/Adobe Flash Player Install Manager")
index b70b673..c37b950 100644 (file)
@@ -105,6 +105,15 @@ void ServiceWorkerProcessProxy::didReceiveAuthenticationChallenge(uint64_t pageI
     challenge->performDefaultHandling();
 }
 
+void ServiceWorkerProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier)
+{
+    WebProcessProxy::didFinishLaunching(launcher, connectionIdentifier);
+
+    // Prevent App Nap for Service Worker processes.
+    // FIXME: Ideally, the Service Worker process would app nap when all its clients app nap (http://webkit.org/b/185626).
+    setProcessSuppressionEnabled(false);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index 3351b74..cbdefdc 100644 (file)
@@ -54,6 +54,9 @@ private:
     // ChildProcessProxy
     void getLaunchOptions(ProcessLauncher::LaunchOptions&) final;
 
+    // ProcessLauncher::Client
+    void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) final;
+
     bool isServiceWorkerProcess() const final { return true; }
 
     ServiceWorkerProcessProxy(WebProcessPool&, const WebCore::SecurityOriginData&, WebsiteDataStore&);
index 6f5c8ae..964204a 100644 (file)
@@ -230,6 +230,9 @@ protected:
     void connectionWillOpen(IPC::Connection&) override;
     void processWillShutDown(IPC::Connection&) override;
 
+    // ProcessLauncher::Client
+    void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
+
 private:
     // Called when the web process has crashed or we know that it will terminate soon.
     // Will potentially cause the WebProcessProxy object to be freed.
@@ -293,9 +296,6 @@ private:
     void sendProcessDidResume() override;
     void didSetAssertionState(AssertionState) override;
 
-    // ProcessLauncher::Client
-    void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
-
     // Implemented in generated WebProcessProxyMessageReceiver.cpp
     void didReceiveWebProcessProxyMessage(IPC::Connection&, IPC::Decoder&);
     void didReceiveSyncWebProcessProxyMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
index 9fd2227..37550be 100644 (file)
                515E7727183DD6F60007203F /* AsyncRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 515E7725183DD6F60007203F /* AsyncRequest.cpp */; };
                515E7728183DD6F60007203F /* AsyncRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 515E7726183DD6F60007203F /* AsyncRequest.h */; };
                5160BFE113381DF900918999 /* LoggingFoundation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160BFE013381DF900918999 /* LoggingFoundation.mm */; };
-               516319921628980A00E22F00 /* NetworkProcessProxyMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 516319911628980A00E22F00 /* NetworkProcessProxyMac.mm */; };
                5163199416289A6000E22F00 /* NetworkProcessMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51ACC9341628064800342550 /* NetworkProcessMessageReceiver.cpp */; };
                5163199516289A6300E22F00 /* NetworkProcessMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 51ACC9351628064800342550 /* NetworkProcessMessages.h */; };
                516A4A5D120A2CCD00C05B7F /* APIError.h in Headers */ = {isa = PBXBuildFile; fileRef = 516A4A5B120A2CCD00C05B7F /* APIError.h */; };
                CDA29A2B1CBEB67A00901CCF /* PlaybackSessionManagerProxyMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = CDA29A271CBEB67A00901CCF /* PlaybackSessionManagerProxyMessages.h */; };
                CDC2831D201BD79D00E6E745 /* WKFullscreenStackView.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC2831B201BD79D00E6E745 /* WKFullscreenStackView.h */; };
                CDC2831E201BD79D00E6E745 /* WKFullscreenStackView.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC2831C201BD79D00E6E745 /* WKFullscreenStackView.mm */; };
-               CDC382FE17211799008A2FC3 /* SecItemShimLibrary.mm in Sources */ = {isa = PBXBuildFile; fileRef = 511F8A78138B460900A95F44 /* SecItemShimLibrary.mm */; };
                CDCA85C8132ABA4E00E961DF /* WKFullScreenWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDCA85C6132ABA4E00E961DF /* WKFullScreenWindowController.mm */; };
                CDCA85C9132ABA4E00E961DF /* WKFullScreenWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCA85C7132ABA4E00E961DF /* WKFullScreenWindowController.h */; };
                CE11AD501CBC47F800681EE5 /* CodeSigning.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE11AD4F1CBC47F800681EE5 /* CodeSigning.mm */; };
                515E7725183DD6F60007203F /* AsyncRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncRequest.cpp; sourceTree = "<group>"; };
                515E7726183DD6F60007203F /* AsyncRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncRequest.h; sourceTree = "<group>"; };
                5160BFE013381DF900918999 /* LoggingFoundation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoggingFoundation.mm; sourceTree = "<group>"; };
-               516319911628980A00E22F00 /* NetworkProcessProxyMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkProcessProxyMac.mm; path = mac/NetworkProcessProxyMac.mm; sourceTree = "<group>"; };
                5164C0941B05B757004F102A /* ChildProcess.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChildProcess.messages.in; sourceTree = "<group>"; };
                516A4A5B120A2CCD00C05B7F /* APIError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIError.h; sourceTree = "<group>"; };
                517A33B3130B308C00F80CB5 /* WKApplicationCacheManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKApplicationCacheManager.cpp; sourceTree = "<group>"; };
                CDC2831B201BD79D00E6E745 /* WKFullscreenStackView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKFullscreenStackView.h; path = ios/fullscreen/WKFullscreenStackView.h; sourceTree = "<group>"; };
                CDC2831C201BD79D00E6E745 /* WKFullscreenStackView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFullscreenStackView.mm; path = ios/fullscreen/WKFullscreenStackView.mm; sourceTree = "<group>"; };
                CDC382F717211506008A2FC3 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = /System/Library/Frameworks/CFNetwork.framework; sourceTree = "<absolute>"; };
-               CDC3830617211799008A2FC3 /* WebProcessShim.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = WebProcessShim.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                CDC8F4881725E67800166F6E /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
                CDCA85C6132ABA4E00E961DF /* WKFullScreenWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKFullScreenWindowController.mm; sourceTree = "<group>"; };
                CDCA85C7132ABA4E00E961DF /* WKFullScreenWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKFullScreenWindowController.h; sourceTree = "<group>"; };
                516319931628980E00E22F00 /* mac */ = {
                        isa = PBXGroup;
                        children = (
-                               516319911628980A00E22F00 /* NetworkProcessProxyMac.mm */,
                        );
                        name = mac;
                        sourceTree = "<group>";
                                5163199416289A6000E22F00 /* NetworkProcessMessageReceiver.cpp in Sources */,
                                E14A954916E016A40068DE82 /* NetworkProcessPlatformStrategies.cpp in Sources */,
                                5179556D162877B100FA43B6 /* NetworkProcessProxy.cpp in Sources */,
-                               516319921628980A00E22F00 /* NetworkProcessProxyMac.mm in Sources */,
                                513A163C163088F6005D7D22 /* NetworkProcessProxyMessageReceiver.cpp in Sources */,
                                51FD18B51651FBAD00DBE1CE /* NetworkResourceLoader.cpp in Sources */,
                                E152551A17011819003D7ADB /* NetworkResourceLoaderMessageReceiver.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               CDC382FD17211799008A2FC3 /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               CDC382FE17211799008A2FC3 /* SecItemShimLibrary.mm in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
index efb07e3..fa4c066 100644 (file)
@@ -84,7 +84,6 @@ messages -> WebProcess LegacyReceiver {
     DeleteWebsiteDataForOrigins(PAL::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> websiteDataTypes, Vector<WebCore::SecurityOriginData> origins) -> ()
 
     SetHiddenPageDOMTimerThrottlingIncreaseLimit(int milliseconds)
-    SetProcessSuppressionEnabled(bool flag)
 #if PLATFORM(COCOA)
     SetQOS(int latencyQOS, int throughputQOS)
 #endif