Skip to content

Commit 355ea78

Browse files
A future that failed due to the 'callr' worker process was terminated
is now considerred interrupted, which for instance means that it can be `reset()`.
1 parent 0671cfc commit 355ea78

File tree

4 files changed

+36
-18
lines changed

4 files changed

+36
-18
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: future.callr
2-
Version: 0.8.2-9205
2+
Version: 0.8.2-9206
33
Depends:
44
R (>= 3.4.0),
55
future (>= 1.40.0)

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
## New Features
44

55
* Now 'callr' futures can be interrupted using `interrupt()`.
6+
An interrupted future can be `reset()` and relaunched.
7+
8+
* A future that failed due to the 'callr' worker process was
9+
terminated is now considerred interrupted, which for instance
10+
means that it can be `reset()`.
611

712

813
# Version 0.8.2 [2023-08-08]

R/CallrFutureBackend-class.R

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -346,34 +346,47 @@ await <- function(future, ...) {
346346

347347
## Failed?
348348
if (inherits(result, "error")) {
349+
label <- future[["label"]]
350+
if (is.null(label)) label <- "<none>"
351+
pid <- process$get_pid()
352+
exit_code <- tryCatch(process$get_exit_status(), error = function(e) NA_integer_)
353+
alive <- process$is_alive()
354+
355+
## Remove future from FutureRegistry?
356+
if (!alive) {
357+
reg <- backend[["reg"]]
358+
if (FutureRegistry(reg, action = "contains", future = future)) {
359+
FutureRegistry(reg, action = "remove", future = future)
360+
}
361+
}
362+
363+
## Failed to launch?
364+
if (inherits(result, "FutureLaunchError")) {
365+
future[["result"]] <- result
366+
stop(result)
367+
}
368+
369+
## Was the future explicitly interrupted?
349370
if (future[["state"]] == "interrupted") {
350371
if (debug) mdebugf("- Detected interrupted %s whose result cannot be retrieved", sQuote(class(future)[1]))
351-
label <- future[["label"]]
352-
if (is.null(label)) label <- "<none>"
353-
process <- future[["process"]]
354-
pid <- process$get_pid()
355-
msg <- sprintf("A future ('%s') of class %s was interrupted, while running on localhost (pid %d)", label, class(future)[1], pid)
372+
msg <- sprintf("A future ('%s') of class %s was interrupted (exit code %d), while running on localhost (pid %d)", label, class(future)[1], exit_code, pid)
356373
result <- FutureInterruptError(msg, future = future)
357374
future[["result"]] <- result
358375
stop(result)
359376
}
360377

361-
if (inherits(result, "FutureLaunchError")) {
378+
## Was the future implicitly interrupted?
379+
if (!alive) {
380+
msg <- sprintf("A future ('%s') of class %s was interrupted for unknown reasons (exit code %s), while running on localhost (pid %d)", label, class(future)[1], exit_code, pid)
381+
result <- FutureInterruptError(msg, future = future)
382+
future[["state"]] <- "interrupted"
362383
future[["result"]] <- result
363384
stop(result)
364385
}
365386

387+
## Other, unknown reason for callr failure
366388
msg <- post_mortem_failure(result, future = future)
367389
ex <- CallrFutureError(msg, future = future)
368-
369-
## Remove future from FutureRegistry?
370-
if (!process$is_alive()) {
371-
reg <- backend[["reg"]]
372-
if (FutureRegistry(reg, action = "contains", future = future)) {
373-
FutureRegistry(reg, action = "remove", future = future)
374-
}
375-
}
376-
377390
stop(ex)
378391
}
379392

inst/testme/test-callr,launch-failure.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ repeat {
2828
}
2929
print(res)
3030
stopifnot(inherits(res, "error"), inherits(res, "FutureError"),
31-
inherits(res, "CallrFutureError"))
31+
inherits(res, c("FutureInterruptError", "CallrFutureError")))
3232

3333
message(" - Getting results")
3434
res <- tryCatch(result(f), error = identity)
3535
print(res)
3636
stopifnot(inherits(res, "error"), inherits(res, "FutureError"),
37-
inherits(res, "CallrFutureError"))
37+
inherits(res, c("FutureInterruptError", "CallrFutureError")))
3838

3939
file.remove(tf)
4040

0 commit comments

Comments
 (0)