Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check that a chromote connection is alive #136

Merged
merged 12 commits into from
Feb 2, 2024
3 changes: 3 additions & 0 deletions R/browser.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ Browser <- R6Class("Browser",
#' @description Browser process
get_process = function() private$process,

#' @description Is the process alive?
is_alive = function() private$process$is_alive(),

#' @description Browser Host
get_host = function() private$host,

Expand Down
60 changes: 44 additions & 16 deletions R/chromote.R
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Chromote <- R6Class(
#' `ChromoteSession` object. Otherwise, block during initialization, and
#' return a `ChromoteSession` object directly.
new_session = function(width = 992, height = 1323, targetId = NULL, wait_ = TRUE) {
self$check_active()
create_session(
chromote = self,
width = width,
Expand Down Expand Up @@ -213,9 +214,7 @@ Chromote <- R6Class(
#' @param sessionId Determines which [`ChromoteSession`] with the
#' corresponding to send the command to.
send_command = function(msg, callback = NULL, error = NULL, timeout = NULL, sessionId = NULL) {
if (!private$is_active_) {
stop("Chromote object is closed.")
}
self$check_active()

private$last_msg_id <- private$last_msg_id + 1
msg$id <- private$last_msg_id
Expand Down Expand Up @@ -320,11 +319,41 @@ Chromote <- R6Class(
paste0("http://", private$browser$get_host(), ":", private$browser$get_port(), path)
},

#' @description Retrieve active status
#' Once initialized, the value returned is `TRUE`. If `$close()` has been
#' called, this value will be `FALSE`.
#' @description Is connection active? (i.e. is the websocket open?)
is_active = function() {
private$is_active_
self$is_alive() && private$ws$readyState() %in% c(0L, 1L)
},

#' @description Is the underlying browser process alive?
is_alive = function() {
private$browser$is_alive()
},

#' @description Check that a chromote instance is active and alive,
#' erroring if not.
check_active = function() {
if (!self$is_alive()) {
stop("Chromote has been closed.")
}

if (!self$is_active()) {
self$reactivate()
}
},

reactivate = function() {
inform(c(
"!" = "Reconnecting to chrome process.",
i = "All active sessions will be need to be respawned.")
)
self$connect()

# Mark all sessions as closed
for (session in private$sessions) {
session$mark_closed()
}
private$sessions <- list()
invisible(self)
},

#' @description Retrieve [`Browser`]` object
Expand All @@ -335,13 +364,14 @@ Chromote <- R6Class(

#' @description Close the [`Browser`] object
close = function() {
if (private$is_active_) {
if (self$is_active()) {
private$ws$close()
}
if (self$is_alive()) {
self$Browser$close()
hadley marked this conversation as resolved.
Show resolved Hide resolved
private$is_active_ <- FALSE
return(TRUE)
} else {
FALSE
}

invisible()
},

#' @field default_timeout Default timeout in seconds for \pkg{chromote} to
Expand Down Expand Up @@ -400,9 +430,7 @@ Chromote <- R6Class(
event_manager = NULL,

register_event_listener = function(event, callback = NULL, timeout = NULL) {
if (!private$is_active_) {
stop("Chromote object is closed.")
}
self$check_active()
private$event_manager$register_event_listener(event, callback, timeout)
},

Expand Down Expand Up @@ -496,7 +524,7 @@ default_chromote_object <- function() {
#' @rdname default_chromote_object
#' @export
has_default_chromote_object <- function() {
!is.null(globals$default_chromote) && globals$default_chromote$is_active()
!is.null(globals$default_chromote) && globals$default_chromote$is_alive()
}

#' @param x A \code{\link{Chromote}} object.
Expand Down
24 changes: 17 additions & 7 deletions R/chromote_session.R
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ ChromoteSession <- R6Class(
#' when the `ChromoteSession` is closed. Otherwise, block until the
#' `ChromoteSession` has closed.
close = function(wait_ = TRUE) {
if (!self$is_active()) {
return(invisible())
}

# Even if this session calls Target.closeTarget, the response from
# the browser is sent without a sessionId. In order to wait for the
# correct browser response, we need to invoke this from the parent's
Expand Down Expand Up @@ -507,9 +511,7 @@ ChromoteSession <- R6Class(
#' @param timeout Number of milliseconds for Chrome DevTools Protocol
#' execute a method.
send_command = function(msg, callback = NULL, error = NULL, timeout = NULL) {
if (!private$is_active_) {
stop("Session ", private$session_id, " is closed.")
}
self$check_active()
self$parent$send_command(msg, callback, error, timeout, sessionId = private$session_id)
},

Expand Down Expand Up @@ -547,7 +549,17 @@ ChromoteSession <- R6Class(
#' Once initialized, the value returned is `TRUE`. If `$close()` has been
#' called, this value will be `FALSE`.
is_active = function() {
private$is_active_
private$is_active_ && self$parent$is_alive()
},

#' @description Check that a session is active, erroring if not.
check_active = function() {
if (!self$is_active()) {
abort(c(
paste("Session ", private$session_id, " has been closed."),
i = "Call session$respawn() to create a new session that connects to the same target."
))
}
},

#' @description Initial promise
Expand Down Expand Up @@ -576,9 +588,7 @@ ChromoteSession <- R6Class(
init_promise_ = NULL,

register_event_listener = function(event, callback = NULL, timeout = NULL) {
if (!private$is_active_) {
stop("Session ", private$session_id, " is closed.")
}
self$check_active()
private$event_manager$register_event_listener(event, callback, timeout)
}
)
Expand Down
11 changes: 11 additions & 0 deletions man/Browser.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/Chrome.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/ChromeRemote.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 34 additions & 3 deletions man/Chromote.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions man/ChromoteSession.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.