From e9eb6b5a39fcc4fe8df687ee0d1e2b5d32f04279 Mon Sep 17 00:00:00 2001 From: wlandau Date: Mon, 11 Nov 2024 15:27:45 -0500 Subject: [PATCH] new crashes() launcher method --- NEWS.md | 1 + R/crew_launcher.R | 15 ++++++++++++++- man/crew_class_launcher.Rd | 30 ++++++++++++++++++++++++++++- man/crew_class_launcher_local.Rd | 1 + tests/local/test-crashes_error.R | 23 +++++++++++++++++++--- tests/testthat/test-crew_launcher.R | 4 ++++ 6 files changed, 69 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index 065c193d..79d3f395 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,7 @@ * Eliminate spurious `launch_max` error from underutilized workers (#189). * Deprecate `launch_max` in favor of `crashes_error` (#189). * Look for crashes of all workers in `rotate()` instead of looking for crashes of a specific worker in `launch()` (#189). +* Add a `crashes()` launcher method to allow plugins to detect and respond to crashes more easily. # crew 0.10.1 diff --git a/R/crew_launcher.R b/R/crew_launcher.R index c8e0844f..cdab1983 100644 --- a/R/crew_launcher.R +++ b/R/crew_launcher.R @@ -321,6 +321,7 @@ crew_class_launcher <- R6::R6Class( #' @param reset_options See [crew_launcher()]. #' @param garbage_collection See [crew_launcher()]. #' @param crashes_error See [crew_launcher()]. + #' @param launch_max Deprecated. #' @param tls See [crew_launcher()]. #' @param processes See [crew_launcher()]. #' @param r_arguments See [crew_launcher()]. @@ -646,7 +647,8 @@ crew_class_launcher <- R6::R6Class( #' `mirai::daemons()` and summed over all #' completed instances of the worker. Does not reflect the activity #' of the currently running instance of the worker. - #' * `socket`: current websocket URL of the worker. + #' * `crashes`: number of consecutive times a worker + #' launched without completing all its assigned tasks. summary = function() { workers <- .subset2(self, "workers") if (is.null(workers)) { @@ -909,6 +911,17 @@ crew_class_launcher <- R6::R6Class( ) list(abstract = TRUE) }, + #' @description Return the number of consecutive times a worker + #' launched without completing all its assigned tasks. + #' @return Non-negative integer, number of consecutive times a worker + #' launched without completing all its assigned tasks. + #' @param index Non-negative integer, index of the worker pointing + #' to a row of the data frame output of the `summary()` method + #' of the launcher. + crashes = function(index) { + workers <- .subset2(private, ".workers") + .subset(.subset2(workers, "crashes"), index) + }, #' @description Abstract worker termination method. #' @details Launcher plugins will overwrite this method. #' @return A handle to mock worker termination. diff --git a/man/crew_class_launcher.Rd b/man/crew_class_launcher.Rd index a57bd8f6..a9e3a0b6 100644 --- a/man/crew_class_launcher.Rd +++ b/man/crew_class_launcher.Rd @@ -123,6 +123,7 @@ asynchronously.} \item \href{#method-crew_class_launcher-wait}{\code{crew_class_launcher$wait()}} \item \href{#method-crew_class_launcher-scale}{\code{crew_class_launcher$scale()}} \item \href{#method-crew_class_launcher-launch_worker}{\code{crew_class_launcher$launch_worker()}} +\item \href{#method-crew_class_launcher-crashes}{\code{crew_class_launcher$crashes()}} \item \href{#method-crew_class_launcher-terminate_worker}{\code{crew_class_launcher$terminate_worker()}} \item \href{#method-crew_class_launcher-terminate_workers}{\code{crew_class_launcher$terminate_workers()}} } @@ -187,6 +188,8 @@ Launcher constructor. \item{\code{crashes_error}}{See \code{\link[=crew_launcher]{crew_launcher()}}.} +\item{\code{launch_max}}{Deprecated.} + \item{\code{tls}}{See \code{\link[=crew_launcher]{crew_launcher()}}.} \item{\code{processes}}{See \code{\link[=crew_launcher]{crew_launcher()}}.} @@ -388,7 +391,8 @@ of the currently running instance of the worker. \code{mirai::daemons()} and summed over all completed instances of the worker. Does not reflect the activity of the currently running instance of the worker. -\item \code{socket}: current websocket URL of the worker. +\item \code{crashes}: number of consecutive times a worker +launched without completing all its assigned tasks. } } } @@ -669,6 +673,30 @@ A handle to mock the worker launch. } } \if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-crew_class_launcher-crashes}{}}} +\subsection{Method \code{crashes()}}{ +Return the number of consecutive times a worker +launched without completing all its assigned tasks. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{crew_class_launcher$crashes(index)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{index}}{Non-negative integer, index of the worker pointing +to a row of the data frame output of the \code{summary()} method +of the launcher.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +Non-negative integer, number of consecutive times a worker +launched without completing all its assigned tasks. +} +} +\if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-crew_class_launcher-terminate_worker}{}}} \subsection{Method \code{terminate_worker()}}{ diff --git a/man/crew_class_launcher_local.Rd b/man/crew_class_launcher_local.Rd index 4d1acaaa..7461de90 100644 --- a/man/crew_class_launcher_local.Rd +++ b/man/crew_class_launcher_local.Rd @@ -69,6 +69,7 @@ Other plugin_local:
  • crew::crew_class_launcher$active()
  • crew::crew_class_launcher$booting()
  • crew::crew_class_launcher$call()
  • +
  • crew::crew_class_launcher$crashes()
  • crew::crew_class_launcher$done()
  • crew::crew_class_launcher$errors()
  • crew::crew_class_launcher$forward()
  • diff --git a/tests/local/test-crashes_error.R b/tests/local/test-crashes_error.R index 27403751..dfa11886 100644 --- a/tests/local/test-crashes_error.R +++ b/tests/local/test-crashes_error.R @@ -6,14 +6,24 @@ test_that("crashes_error allows idle workers to exit", { x$launch() Sys.sleep(5) } + expect_equal(x$launcher$crashes(index = 1L), 0L) expect_equal(index, 10L) }) test_that("crashes_error detects when there are too many crashes", { - x <- crew_controller_local(name = "name", crashes_error = 2L) + x <- crew_controller_local( + name = "name", + workers = 2L, + crashes_error = 2L, + tasks_max = 1L, + seconds_idle = 1 + ) on.exit(x$terminate()) x$start() - x$push(Sys.sleep(1e3), scale = FALSE) + x$push(Sys.sleep(4), scale = TRUE) + Sys.sleep(5) + x$push(Sys.sleep(1e3), scale = TRUE) + x$wait(mode = "one") for (index in seq_len(10L)) { Sys.sleep(5) if (index == 3L) { @@ -22,8 +32,15 @@ test_that("crashes_error detects when there are too many crashes", { } else { expect_silent(x$scale()) } + expect_equal(x$launcher$crashes(index = 1L), 0L) + expect_equal(x$launcher$crashes(index = 2L), index - 1L) Sys.sleep(5) - x$launcher$workers$handle[[1L]]$kill() + client_summary <- x$client$summary() + expect_equal(client_summary$online, c(FALSE, TRUE)) + expect_equal(client_summary$instances, c(1L, index)) + expect_equal(client_summary$assigned, c(1L, 1L)) + expect_equal(client_summary$complete, c(1L, 0L)) + x$launcher$workers$handle[[2L]]$kill() } expect_equal(index, 3L) }) diff --git a/tests/testthat/test-crew_launcher.R b/tests/testthat/test-crew_launcher.R index de9d490c..fa8ccfd2 100644 --- a/tests/testthat/test-crew_launcher.R +++ b/tests/testthat/test-crew_launcher.R @@ -209,6 +209,10 @@ crew_test("launcher start()", { expect_equal(workers$launched, rep(FALSE, 2L)) expect_equal(workers$assigned, rep(0L, 2L)) expect_equal(workers$complete, rep(0L, 2L)) + expect_equal(workers$crashes, rep(0L, 2L)) + for (index in seq_len(2L)) { + expect_equal(launcher$crashes(index), 0L) + } }) crew_test("launcher done()", {