diff --git a/R/class_active.R b/R/class_active.R index 7f888960..5adcd7db 100644 --- a/R/class_active.R +++ b/R/class_active.R @@ -189,7 +189,9 @@ active_class <- R6::R6Class( target <- pipeline_get_target(self$pipeline, name) target_debug(target) target_update_depend(target, self$pipeline, self$meta) - if (target_should_run(target, self$meta)) { + if (counter_exists_name(self$scheduler$trimmed, name)) { + self$scheduler$trim(target, self$pipeline) + } else if (target_should_run(target, self$meta)) { self$flush_upload_meta_file(target) self$run_target(name) } else { diff --git a/R/class_builder.R b/R/class_builder.R index ceb5fa08..78b202bc 100644 --- a/R/class_builder.R +++ b/R/class_builder.R @@ -339,7 +339,7 @@ builder_handle_error <- function(target, pipeline, scheduler, meta) { target$settings$error, continue = builder_error_continue(target, scheduler), abridge = scheduler$abridge(target), - trim = scheduler$trim(target), + trim = scheduler$trim(target, pipeline), stop = builder_error_exit(target, pipeline, scheduler, meta), null = builder_error_null(target, pipeline, scheduler, meta), workspace = builder_error_exit(target, pipeline, scheduler, meta) diff --git a/R/class_pattern.R b/R/class_pattern.R index 63f9db6a..05394502 100644 --- a/R/class_pattern.R +++ b/R/class_pattern.R @@ -17,7 +17,7 @@ pattern_new <- function( #' @export target_get_children.tar_pattern <- function(target) { - target$junction$splits + as.character(target$junction$splits) } #' @export diff --git a/R/class_scheduler.R b/R/class_scheduler.R index 7886e1ca..2d9b43c7 100644 --- a/R/class_scheduler.R +++ b/R/class_scheduler.R @@ -22,14 +22,14 @@ scheduler_init <- function( ) reporter <- reporter_init(reporter, seconds_interval = seconds_reporter) backoff <- tar_options$get_backoff() - canceled <- counter_init() + trimmed <- counter_init() scheduler_new( graph = graph, queue = queue, progress = progress, reporter = reporter, backoff = backoff, - canceled <- canceled + trimmed <- trimmed ) } @@ -55,9 +55,9 @@ scheduler_new <- function( progress = NULL, reporter = NULL, backoff = NULL, - canceled = NULL + trimmed = NULL ) { - scheduler_class$new(graph, queue, progress, reporter, backoff, canceled) + scheduler_class$new(graph, queue, progress, reporter, backoff, trimmed) } scheduler_class <- R6::R6Class( @@ -71,21 +71,21 @@ scheduler_class <- R6::R6Class( progress = NULL, reporter = NULL, backoff = NULL, - canceled = NULL, + trimmed = NULL, initialize = function( graph = NULL, queue = NULL, progress = NULL, reporter = NULL, backoff = NULL, - canceled = NULL + trimmed = NULL ) { self$graph <- graph self$queue <- queue self$progress <- progress self$reporter <- reporter self$backoff <- backoff - self$canceled <- canceled + self$trimmed <- trimmed }, count_unfinished_deps = function(name) { deps <- self$graph$produce_upstream(name) @@ -104,10 +104,12 @@ scheduler_class <- R6::R6Class( self$progress$abridge() self$queue$abridge() }, - trim = function(target) { - - browser() - + trim = function(target, pipeline) { + parent_name <- target_get_parent(target) + parent_target <- pipeline_get_target(pipeline, parent_name) + downstream <- self$graph$produce_downstream(parent_name) + siblings <- target_get_children(parent_target) + counter_set_names(self$trimmed, c(downstream, siblings)) }, validate = function() { self$graph$validate() @@ -115,7 +117,7 @@ scheduler_class <- R6::R6Class( self$progress$validate() self$reporter$validate() self$backoff$validate() - counter_validate(self$canceled) + counter_validate(self$trimmed) } ) ) diff --git a/R/class_stem.R b/R/class_stem.R index ffcf834b..dae613ad 100644 --- a/R/class_stem.R +++ b/R/class_stem.R @@ -72,7 +72,13 @@ target_produce_record.tar_stem <- function(target, pipeline, meta) { } #' @export -target_skip.tar_stem <- function(target, pipeline, scheduler, meta, active) { +target_skip.tar_stem <- function( + target, + pipeline, + scheduler, + meta, + active +) { NextMethod() stem_restore_buds(target, pipeline, scheduler, meta) } diff --git a/R/class_target.R b/R/class_target.R index b6b8bfdb..c59cf0e6 100644 --- a/R/class_target.R +++ b/R/class_target.R @@ -207,7 +207,13 @@ target_produce_record <- function(target, pipeline, meta) { UseMethod("target_produce_record") } -target_skip <- function(target, pipeline, scheduler, meta, active) { +target_skip <- function( + target, + pipeline, + scheduler, + meta, + active +) { UseMethod("target_skip") } diff --git a/R/tar_target.R b/R/tar_target.R index 91631928..f712f4a4 100644 --- a/R/tar_target.R +++ b/R/tar_target.R @@ -216,10 +216,17 @@ #' up to date for the next run of the pipeline. #' * `"abridge"`: any currently running targets keep running, #' but no new targets launch after that. -#' * `"trim"`: any currently running targets keep running, -#' and everything downstream of the error is canceled. -#' In addition, if the error happens in a dynamic branch, -#' then all not-yet-dispatched sibling branches are canceled. +#' * `"trim"`: all currently running targets stay running. In addition, +#' a target not yet running is allowed to start if: +#' +#' 1. It is not downstream of the error, and +#' 2. It is not a sibling branch from the same [tar_target()] call +#' (if the error happened in a dynamic branch). +#' +#' The idea is to avoid starting any new work that the immediate error +#' impacts. `error = "trim"` is just like `error = "abridge"`, +#' but it allows potentially healthy regions of the dependency graph +#' to begin running. #' (Visit #' to learn how to debug targets using saved workspaces.) #' @param memory Character of length 1, memory strategy. diff --git a/man/tar_option_set.Rd b/man/tar_option_set.Rd index bedaec01..8d534697 100644 --- a/man/tar_option_set.Rd +++ b/man/tar_option_set.Rd @@ -174,13 +174,25 @@ stops and throws an error. Options: \itemize{ \item \code{"stop"}: the whole pipeline stops and throws an error. \item \code{"continue"}: the whole pipeline keeps going. +\item \code{"null"}: The errored target continues and returns \code{NULL}. +The data hash is deliberately wrong so the target is not +up to date for the next run of the pipeline. \item \code{"abridge"}: any currently running targets keep running, but no new targets launch after that. +\item \code{"trim"}: all currently running targets stay running. In addition, +a target not yet running is allowed to start if: +\enumerate{ +\item It is not downstream of the error, and +\item It is not a sibling branch from the same \code{\link[=tar_target]{tar_target()}} call +(if the error happened in a dynamic branch). +} + +The idea is to avoid starting any new work that the immediate error +impacts. \code{error = "trim"} is just like \code{error = "abridge"}, +but it allows potentially healthy regions of the dependency graph +to begin running. (Visit \url{https://books.ropensci.org/targets/debugging.html} to learn how to debug targets using saved workspaces.) -\item \code{"null"}: The errored target continues and returns \code{NULL}. -The data hash is deliberately wrong so the target is not -up to date for the next run of the pipeline. }} \item{memory}{Character of length 1, memory strategy. diff --git a/man/tar_target.Rd b/man/tar_target.Rd index 7326b8be..9e716c41 100644 --- a/man/tar_target.Rd +++ b/man/tar_target.Rd @@ -119,13 +119,25 @@ stops and throws an error. Options: \itemize{ \item \code{"stop"}: the whole pipeline stops and throws an error. \item \code{"continue"}: the whole pipeline keeps going. +\item \code{"null"}: The errored target continues and returns \code{NULL}. +The data hash is deliberately wrong so the target is not +up to date for the next run of the pipeline. \item \code{"abridge"}: any currently running targets keep running, but no new targets launch after that. +\item \code{"trim"}: all currently running targets stay running. In addition, +a target not yet running is allowed to start if: +\enumerate{ +\item It is not downstream of the error, and +\item It is not a sibling branch from the same \code{\link[=tar_target]{tar_target()}} call +(if the error happened in a dynamic branch). +} + +The idea is to avoid starting any new work that the immediate error +impacts. \code{error = "trim"} is just like \code{error = "abridge"}, +but it allows potentially healthy regions of the dependency graph +to begin running. (Visit \url{https://books.ropensci.org/targets/debugging.html} to learn how to debug targets using saved workspaces.) -\item \code{"null"}: The errored target continues and returns \code{NULL}. -The data hash is deliberately wrong so the target is not -up to date for the next run of the pipeline. }} \item{memory}{Character of length 1, memory strategy. diff --git a/man/tar_target_raw.Rd b/man/tar_target_raw.Rd index 2c43203e..3dc36db4 100644 --- a/man/tar_target_raw.Rd +++ b/man/tar_target_raw.Rd @@ -134,13 +134,25 @@ stops and throws an error. Options: \itemize{ \item \code{"stop"}: the whole pipeline stops and throws an error. \item \code{"continue"}: the whole pipeline keeps going. +\item \code{"null"}: The errored target continues and returns \code{NULL}. +The data hash is deliberately wrong so the target is not +up to date for the next run of the pipeline. \item \code{"abridge"}: any currently running targets keep running, but no new targets launch after that. +\item \code{"trim"}: all currently running targets stay running. In addition, +a target not yet running is allowed to start if: +\enumerate{ +\item It is not downstream of the error, and +\item It is not a sibling branch from the same \code{\link[=tar_target]{tar_target()}} call +(if the error happened in a dynamic branch). +} + +The idea is to avoid starting any new work that the immediate error +impacts. \code{error = "trim"} is just like \code{error = "abridge"}, +but it allows potentially healthy regions of the dependency graph +to begin running. (Visit \url{https://books.ropensci.org/targets/debugging.html} to learn how to debug targets using saved workspaces.) -\item \code{"null"}: The errored target continues and returns \code{NULL}. -The data hash is deliberately wrong so the target is not -up to date for the next run of the pipeline. }} \item{memory}{Character of length 1, memory strategy.