Can future processes free themselves?

Viewed 124

i have a script/workframe that calls a function with the future package. The function does not return anything, but instead starts an API-Call, something like this:

library(future)
future::plan("multisession")
future_get_function = function (msg) {
  link <- ("http://127.0.0.1:7774/echo?")
  message <- list(msg=msg)     
  httr::GET(link, query=message)
  Sys.sleep(20)
}

future::future({
   future_get_function(msg)
}, globals = list(msg=msg)}
library(plumber)

#* Echo back the input
#* @param msg The message to echo
#* @get /echo
function(msg="") {
  print("received something")
  list(msg = paste0("The message is: '", msg, "'"))
}

Now, from what ive seen, I need to free up the processes that are done with the value function afterwards, correct? Otherwise, if I have more calls then processers/tasks available, they are stuck?

So is there a function that i can insert at the end of future_get_function or somewhere in the future call (promises would also be fine), that frees the process automatically once its done, without me having to call value or similar?

Thanks in advance.

1 Answers

Future processes definitely free themselves after completion.
You could use then to follow up promises completion, and promise_all to check when all promises are finished :

library(future)
library(promises)
plan(multisession)

tic <- Sys.time()

future_get_function = function (msg,wait) {
  #link <- ("http://127.0.0.1:7774/echo?")
  #message <- list(msg=msg)     
  #httr::GET(link, query=message)
  print(paste(msg,": launched after",round(difftime(Sys.time(),tic),1), 'seconds'))
  Sys.sleep(wait)
  invisible(msg)
}

f1 <- future(future_get_function('msg1',5))
f2 <- future(future_get_function('msg2',10))

f_after <- function(res) {
  print(paste(res,"sent after",round(difftime(Sys.time(),tic),1), 'seconds'))}

f_failed <- function(res) {
  print(paste("future failed"))}

f_end <- function(res) {
  print(paste("All messages sent after",round(difftime(Sys.time(),tic),1), 'seconds'))}


promises::then(f1, onFulfilled = f_after, onRejected = f_failed)
promises::then(f2, onFulfilled = f_after, onRejected = f_failed)

f_wait_all <- promises::promise_all(f1,f2)
promises::then(f_wait_all, onFulfilled = f_end, onRejected = f_failed)

[1] "msg1 : launched after 0 seconds"
[1] "msg1 sent after 5.1 seconds"
[1] "msg2 : launched after 0.2 seconds"
[1] "msg2 sent after 10.2 seconds"
[1] "All messages sent after 10.2 seconds"
Related