@@ -1045,20 +1045,48 @@ launchFuture.ClusterFutureBackend <- function(backend, future, ...) {
10451045}
10461046
10471047
1048- ClusterFutureBackend <- function (workers , persistent = FALSE , ... ) {
1049- core <- new.env(parent = emptyenv())
1050-
1051- # # Record future plan tweaks, if any
1052- args <- list (workers = workers , persistent = persistent , ... )
1053- for (name in names(args )) {
1054- core [[name ]] <- args [[name ]]
1048+ ClusterFutureBackend <- function (workers = availableWorkers(), persistent = FALSE , ... ) {
1049+ if (is.function(workers )) workers <- workers()
1050+ if (is.null(workers )) {
1051+ getDefaultCluster <- importParallel(" getDefaultCluster" )
1052+ workers <- getDefaultCluster()
1053+ workers <- addCovrLibPath(workers )
1054+ } else if (is.character(workers ) || is.numeric(workers )) {
1055+ # # Which '...' arguments should be passed to Future() and
1056+ # # which should be passed to makeClusterPSOCK()?
1057+ workers <- ClusterRegistry(" start" , workers = workers , ... )
1058+ } else {
1059+ workers <- as.cluster(workers )
1060+ workers <- addCovrLibPath(workers )
10551061 }
1062+ if (! inherits(workers , " cluster" )) {
1063+ stopf(" Argument 'workers' is not of class 'cluster': %s" , commaq(class(workers )))
1064+ }
1065+ stop_if_not(length(workers ) > 0 )
1066+
1067+ core <- FutureBackend(workers = workers , persistent = persistent , ... )
10561068 core $ futureClasses <- c(" ClusterFuture" , " Future" )
10571069 core <- structure(core , class = c(" ClusterFutureBackend" , " FutureBackend" , class(core )))
10581070 core
10591071}
10601072
1061- MultisessionFutureBackend <- function (workers , ... ) {
1073+
1074+ MultisessionFutureBackend <- function (workers = availableCores(), ... ) {
1075+ default_workers <- missing(workers )
1076+ if (is.function(workers )) workers <- workers()
1077+ workers <- structure(as.integer(workers ), class = class(workers ))
1078+ stop_if_not(length(workers ) == 1 , is.finite(workers ), workers > = 1 )
1079+
1080+ # # Fall back to sequential futures if only a single additional R process
1081+ # # can be spawned off, i.e. then use the current main R process.
1082+ # # Sequential futures best reflect how multicore futures handle globals.
1083+ if (workers == 1L && ! inherits(workers , " AsIs" )) {
1084+ # # AD HOC: Make sure plan(multicore) also produces a warning, if needed
1085+ if (default_workers ) supportsMulticore(warn = TRUE )
1086+ # # covr: skip=1
1087+ return (SequentialFutureBackend(... ))
1088+ }
1089+
10621090 core <- ClusterFutureBackend(workers = workers , ... )
10631091 core $ futureClasses <- c(" MultisessionFuture" , core $ futureClasses )
10641092 core <- structure(core , class = c(" MultisessionFutureBackend" , class(core )))
0 commit comments