Detecting and handling unresponsive web processes
Hi WebKit folks! I'm working on improving the detection of unresponsive web processes and how to recover from that situation on the GTK and WPE ports. Investigating how ResponsivenessTimer and BackgroundProcessResponsivenessTimer work, I see that currently there are 3 ways to detect that the process has become unresponsive: * When there's an user event, the event is passed to the web process and the ResponsivenessTimer is started to check whether there's an answer from the web process in the next 3 seconds. If this doesn't happen, the process is marked as unresponsive. * Same that above, but started from some API call (like reload for example) instead of an user event. * When the WebProcessProxy doesn't have visible pages or it's used for a ServiceWorker, the BackgroundProcessResponsivenessTimer will periodically ping the web process, and mark it as un responsive when there's no answer. This is enabled for non Apple ports only. What I see is that there's no way to check the responsiveness of the web process when there are no API calls or the user is not interacting with the page. I'm thinking on the user watching a video without interacting with the page, or some JS script locking the main thread at some point. To improve this, I've created https://bugs.webkit.org/show_bug.cgi?id=224862 and sent a patch for the ResponsivenessTimer to send a ping to the web process every ten seconds after the last reply from the web process. I was thinking of enabling this feature only for GTK and WPE, but maybe some other ports are interested as well. Just answer this or add some comment to the bug and I'll remove the platform guards. Also, in https://bugs.webkit.org/show_bug.cgi?id=224359 I added a property to WebKitWebView (in GTK and WPE) to signal the web process responsiveness, so with these 2 things the detection should be covered. Then there's the problem of recovering from an unresponsive web process. We should probably show a warning to the users so they can decide whether to wait or stop the page. And then, what to do if the user decides to stop the page? I see 2 options here: * Have some API method that allows to kill the problematic web process, and let the browser call it when needed. The next load will create a new web process. * Modify some of the existent load/reload API calls so they check whether the web process is responsive or not. If it's unresponsive, kill the process before trying to do anything else, and a new web process will be created when the rest of the code is executed. On https://bugs.webkit.org/show_bug.cgi?id=224533 we were leaning towards the second option, so we don't need to add new API and the whole situation is handled inside WebKit. But studying the code I found that the Apple ports seem to use the first one: the object handling the responsiveness is an external class that implements the WKNavigationDelegate inteface, and I guess it uses _killWebContentProcess or _killWebContentProcessAndResetState in order to kill the web process before loading some new content. Am I right regarding how Apple ports work? If the answer is yes, is there any special reason to do it what way? Should we follow that approach too? WDYT? Regards! -- Miguel Gomez Igalia - www.igalia.com
On Tue, Apr 27 2021 at 10:18:04 AM +0200, Miguel Gomez via webkit-dev <webkit-dev@lists.webkit.org> wrote:
* Have some API method that allows to kill the problematic web process, and let the browser call it when needed. The next load will create a new web process.
We only need this API if we are unable to fix the existing webkit_web_view_load_* APIs to work when the web process is unresponsive, right? So we probably do not need it.
* Modify some of the existent load/reload API calls so they check whether the web process is responsive or not. If it's unresponsive, kill the process before trying to do anything else, and a new web process will be created when the rest of the code is executed.
This behavior is a better default for most client applications. Applications that want more control would just need a way to disable this behavior, right?
On Wed, 2021-04-28 at 13:11 +0000, Michael Catanzaro wrote:
On Tue, Apr 27 2021 at 10:18:04 AM +0200, Miguel Gomez via webkit-dev <webkit-dev@lists.webkit.org> wrote:
* Have some API method that allows to kill the problematic web process, and let the browser call it when needed. The next load will create a new web process.
We only need this API if we are unable to fix the existing webkit_web_view_load_* APIs to work when the web process is unresponsive, right? So we probably do not need it.
Right. If we adapt the load APIs to handle the situation we don't need any new API.
* Modify some of the existent load/reload API calls so they check whether the web process is responsive or not. If it's unresponsive, kill the process before trying to do anything else, and a new web process will be created when the rest of the code is executed.
This behavior is a better default for most client applications.
It's easier for them for sure, as they don't have to do anything special other than reload the page or load a new one.
Applications that want more control would just need a way to disable this behavior, right?
But if we give the option to disable this behavior, then we need to provide a way for the apps to handle the situation, don't you think? And this means adding new API (being it the one to retrieve the process ID or the one to kill the web content process directly). -- Miguel Gomez Igalia - www.igalia.com
On Wed, Apr 28 2021 at 04:14:16 PM +0200, Miguel Gomez via webkit-dev <webkit-dev@lists.webkit.org> wrote:
But if we give the option to disable this behavior, then we need to provide a way for the apps to handle the situation, don't you think? And this means adding new API (being it the one to retrieve the process ID or the one to kill the web content process directly).
Would an application ever want to do something to handle the situation other than load a new page? Perhaps you would want to use webkit_web_view_load_alternate_html() to display an error page, for example. An API to allow killing the process is only needed if the application wants to do something when the process is killed *without* loading a new page, yes?
participants (2)
-
Michael Catanzaro
-
Miguel Gomez