rstudio/chromote

Session dies after computer goes to sleep

Closed this issue · 6 comments

session <- chromote::ChromoteSession$new()
#> Error:
#> ! Chromote: timed out waiting for response to command Target.createTarget

This happens fairly reliably for me if I leave RStudio running for a while. Restarting RStudio makes the problem go away (for a while)

I see the same issue routinely, also. It seems to hold up Chrome browser processes, too.

Recently started using this package, and this happens a lot to me.

I happened to have a chrome session open on the page, and saw this:

Screenshot 2024-01-25 at 12 52 58

So possibly there's some timeout that leads to devtools shutting down?

When this happens you can fix it with:

chromote:::set_default_chromote_object(chromote::Chromote$new())

Possibly useful, this gives you the error stream:

readLines(chromote::default_chromote_object()$get_browser()$get_process()$get_error_file())

Ok, some extension exploration with @wch revealed that the problem is when your computer goes to sleep, chrome closes both the websocket and the corresponding debugging session. So to fix this problem you need to create a new websocket in the chromote object, something like this:

later::with_loop(chromote$.__enclos_env__$private$child_loop, {
  ws_new <- websocket::WebSocket$new(
    chrome_info$webSocketDebuggerUrl,
    autoConnect = FALSE
  )
  ws_new$onMessage(chromote$.__enclos_env__$private$on_message)
  ws_new$connect()
  ws_new$readyState()
})

And then each session object really needs to be recreated. This is currently hard because the ChromoteSession object only tracks the transient session id, not the target id of the underlying tab/page that you need to recreate it.

A 100% automated fix for this is going to be quite a lot of work and will require time from the chromote team (which is not currently possible as they're working on other things). So in the meantime, I'm going to create the tooling that will allow you to fix this yourself:

  • Extract out the code above into a chromote$reconnect() function.
  • Store the target id in the ChromoteSession so it's possible to recreate a new debugging session for an existing target. (We can then use this in a bunch of the other methods as a small performance optimisation).
  • Create a way to detect this from both Chromote and ChromoteSession, probably by checking the $readyState of the underlying websocket in Chromote, and then in ChromoteSession also checking that the parent is active.

The Chromote object will now restart, and ChromoteSessions will tell you to call $respawn() to get a new debugging session for an existing target.