From dc8dc7e56b06e2ac25b4d2d5210e458bd2d2a51c Mon Sep 17 00:00:00 2001 From: Robert Ashton Date: Fri, 22 Apr 2022 14:29:35 +0100 Subject: [PATCH 1/3] Add orderly_cancel_remote function for cancelling remote running reports --- DESCRIPTION | 2 +- NAMESPACE | 1 + NEWS.md | 4 ++++ R/remote.R | 25 +++++++++++++++++++++ man/orderly_cancel_remote.Rd | 42 ++++++++++++++++++++++++++++++++++++ tests/testthat/test-remote.R | 37 +++++++++++++++++++++++++++++++ 6 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 man/orderly_cancel_remote.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 3891b6f5..cb01ef6d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: orderly Title: Lightweight Reproducible Reporting -Version: 1.4.6 +Version: 1.4.7 Description: Order, create and store reports from R. By defining a lightweight interface around the inputs and outputs of an analysis, a lot of the repetitive work for reproducible research diff --git a/NAMESPACE b/NAMESPACE index 16ba728a..2b2a1fc3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,6 +9,7 @@ export(orderly_bundle_list) export(orderly_bundle_pack) export(orderly_bundle_pack_remote) export(orderly_bundle_run) +export(orderly_cancel_remote) export(orderly_cleanup) export(orderly_commit) export(orderly_config) diff --git a/NEWS.md b/NEWS.md index 77e2460d..34789c06 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# orderly 1.4.7 + +* Add `orderly_cancel_remote` which can be used to cancel one or more reports running on a remote via its key (mrc-3167) + # orderly 1.4.3 * Orderly now only records git information where a `.git` directory is found at the orderly root (vimc-4866) diff --git a/R/remote.R b/R/remote.R index 330e3fdc..6088b659 100644 --- a/R/remote.R +++ b/R/remote.R @@ -662,3 +662,28 @@ pull_info <- function(name, id, root, locate, remote, parameters) { config = config, remote = remote) } + + +##' Cancel a report +##' +##' The action will depend on the status of the report: +##' * queued - report run will be deleted +##' * running - report run will be cancelled +##' * complete/errored - no effect +##' +##' @param keys The key or keys for the reports to cancel +##' +##' @inheritParams orderly_pull_dependencies +##' +##' @return List with names as report keys and values are lists containing +##' `killed` - boolean TRUE if report successfully cancelled, FALSE otherwise +##' `message` - string detailing reason why cancellation failed +##' +##' @export +orderly_cancel_remote <- function(keys, root = NULL, locate = TRUE, + remote = NULL) { + remote <- get_remote(remote, orderly_config(root, locate)) + out <- lapply(keys, remote$kill) + names(out) <- keys + out +} diff --git a/man/orderly_cancel_remote.Rd b/man/orderly_cancel_remote.Rd new file mode 100644 index 00000000..e6f13d2e --- /dev/null +++ b/man/orderly_cancel_remote.Rd @@ -0,0 +1,42 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/remote.R +\name{orderly_cancel_remote} +\alias{orderly_cancel_remote} +\title{Cancel a report} +\usage{ +orderly_cancel_remote(keys, root = NULL, locate = TRUE, remote = NULL) +} +\arguments{ +\item{keys}{The key or keys for the reports to cancel} + +\item{root}{The path to an orderly root directory, or \code{NULL} +(the default) to search for one from the current working +directory if \code{locate} is \code{TRUE}.} + +\item{locate}{Logical, indicating if the configuration should be +searched for. If \code{TRUE} and \code{config} is not given, +then orderly looks in the working directory and up through its +parents until it finds an \code{orderly_config.yml} file.} + +\item{remote}{Description of the location. Typically this is a +character string indicating a remote specified in the +\code{remotes} block of your \code{orderly_config.yml}. It is +also possible to pass in a directly created remote object (e.g., +using \code{\link[=orderly_remote_path]{orderly_remote_path()}}, or one provided by +another package). If left \code{NULL}, then the default remote +for this orderly repository is used - by default that is the +first listed remote.} +} +\value{ +List with names as report keys and values are lists containing +\code{killed} - boolean TRUE if report successfully cancelled, FALSE otherwise +\code{message} - string detailing reason why cancellation failed +} +\description{ +The action will depend on the status of the report: +\itemize{ +\item queued - report run will be deleted +\item running - report run will be cancelled +\item complete/errored - no effect +} +} diff --git a/tests/testthat/test-remote.R b/tests/testthat/test-remote.R index 74f2f1ce..cf8187eb 100644 --- a/tests/testthat/test-remote.R +++ b/tests/testthat/test-remote.R @@ -490,3 +490,40 @@ test_that("Can't pull incompatible metadata", { remote = dat$remote), "Report was created with orderly more recent than this, upgrade!") }) + + +test_that("reports can be cancelled", { + path_local <- test_prepare_orderly_example("demo") + + res_1 <- list( + killed = TRUE, + message = NULL + ) + res_2 <- list( + killed = FALSE, + message = "Could not kill task, already complete" + ) + mock_kill <- mockery::mock(res_1, res_2) + ## Create a minimal remote class which will satisfy implements_remote + mock_remote <- R6::R6Class( + "orderly_mock_remote", + lock_objects = FALSE, + public = list( + list_reports = function() TRUE, + list_versions = function() TRUE, + pull = function() TRUE, + run = function() TRUE, + url_report = function() TRUE, + queue_status = function() TRUE, + kill = function(key) mock_kill() + ) + ) + + remote <- mock_remote$new() + res <- orderly_cancel_remote( + c("fungiform_kiwi", "lithe_iaerismetalmark"), remote = remote) + mockery::expect_called(mock_kill, 2) + expect_equal(names(res), c("fungiform_kiwi", "lithe_iaerismetalmark")) + expect_equal(res$fungiform_kiwi, res_1) + expect_equal(res$lithe_iaerismetalmark, res_2) +}) From b0b995530f71f787ceee759902f3b0fc02d15528 Mon Sep 17 00:00:00 2001 From: Robert Ashton Date: Fri, 22 Apr 2022 14:30:45 +0100 Subject: [PATCH 2/3] Tidy docs for cancel --- R/remote.R | 5 +++-- man/orderly_cancel_remote.Rd | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/R/remote.R b/R/remote.R index 6088b659..a246ef4a 100644 --- a/R/remote.R +++ b/R/remote.R @@ -676,8 +676,9 @@ pull_info <- function(name, id, root, locate, remote, parameters) { ##' @inheritParams orderly_pull_dependencies ##' ##' @return List with names as report keys and values are lists containing -##' `killed` - boolean TRUE if report successfully cancelled, FALSE otherwise -##' `message` - string detailing reason why cancellation failed +##' * `killed` - boolean TRUE if report successfully cancelled, FALSE +##' otherwise +##' * `message` - string detailing reason why cancellation failed ##' ##' @export orderly_cancel_remote <- function(keys, root = NULL, locate = TRUE, diff --git a/man/orderly_cancel_remote.Rd b/man/orderly_cancel_remote.Rd index e6f13d2e..b73cec62 100644 --- a/man/orderly_cancel_remote.Rd +++ b/man/orderly_cancel_remote.Rd @@ -29,8 +29,11 @@ first listed remote.} } \value{ List with names as report keys and values are lists containing -\code{killed} - boolean TRUE if report successfully cancelled, FALSE otherwise -\code{message} - string detailing reason why cancellation failed +\itemize{ +\item \code{killed} - boolean TRUE if report successfully cancelled, FALSE +otherwise +\item \code{message} - string detailing reason why cancellation failed +} } \description{ The action will depend on the status of the report: From 8a510b61d40fc7fa99dfd7938f31fc1b12897664 Mon Sep 17 00:00:00 2001 From: Robert Ashton Date: Tue, 26 Apr 2022 09:29:41 +0100 Subject: [PATCH 3/3] Add kill function to implements remote check --- R/remote.R | 3 ++- R/remote_path.R | 4 ++++ tests/testthat/test-remote-path.R | 8 ++++++++ tests/testthat/test-remote.R | 7 +++++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/R/remote.R b/R/remote.R index a246ef4a..34fdf970 100644 --- a/R/remote.R +++ b/R/remote.R @@ -472,7 +472,8 @@ implements_remote <- function(x) { is.function(x$list_versions) && is.function(x$pull) && is.function(x$run) && - is.function(x$url_report) + is.function(x$url_report) && + is.function(x$kill) } diff --git a/R/remote_path.R b/R/remote_path.R index c269e664..d4cf484a 100644 --- a/R/remote_path.R +++ b/R/remote_path.R @@ -96,5 +96,9 @@ orderly_remote_path_ <- R6::R6Class( bundle_import = function(path) { orderly_bundle_import(path, root = self$config, locate = FALSE) + }, + + kill = function(...) { + stop("'orderly_remote_path' remotes do not kill") } )) diff --git a/tests/testthat/test-remote-path.R b/tests/testthat/test-remote-path.R index e8433146..abd781c2 100644 --- a/tests/testthat/test-remote-path.R +++ b/tests/testthat/test-remote-path.R @@ -318,3 +318,11 @@ test_that("bundle pack and import", { expect_equal(remote$list_versions("example"), ans$id) }) + + +test_that("orderly_cancel_remote", { + dat <- prepare_orderly_remote_example() + expect_error( + orderly_cancel_remote("example", root = dat$config), + "'orderly_remote_path' remotes do not kill") +}) diff --git a/tests/testthat/test-remote.R b/tests/testthat/test-remote.R index cf8187eb..bc189fdd 100644 --- a/tests/testthat/test-remote.R +++ b/tests/testthat/test-remote.R @@ -269,7 +269,8 @@ test_that("orderly run remote passes instance to run", { list_reports = function() TRUE, list_versions = function() TRUE, pull = function() TRUE, - url_report = function() TRUE + url_report = function() TRUE, + kill = function() TRUE ) ) @@ -334,7 +335,8 @@ test_that("orderly run remote passes ref to run", { list_reports = function() TRUE, list_versions = function() TRUE, pull = function() TRUE, - url_report = function() TRUE + url_report = function() TRUE, + kill = function() TRUE ) ) @@ -379,6 +381,7 @@ test_that("can get status of remote queue", { pull = function() TRUE, run = function() TRUE, url_report = function() TRUE, + kill = function() TRUE, queue_status = function() mock_status() ) )