Указание зависимостей фьючерсов, которые вызывают функции пользовательского пакета - PullRequest
0 голосов
/ 17 февраля 2020

Как правильно определить future::future(), который должен вызывать функцию пользовательского пакета?

Даже после прочтения Будущее за R: общие проблемы с решениями , я до сих пор не понимаю, как работает и / или анализ кода {future} stati c правильное использование аргументов globals и packages.

Приведенный ниже код срабатывает, если я помещаю его в автономный скрипт и извлекаю его через source():

slow_foo <- function(sleep = 10) {
  Sys.sleep(sleep)
  getwd()
}

async <- function(
  sleep = 10,
  get_value = FALSE
) {
  future::plan(future::multisession)

  promise <- future::future({
    slow_foo(sleep = sleep)
  })

  if (get_value) {
    future::value(promise)
  } else {
    TRUE
  }
}

system.time(async())
#>    user  system elapsed 
#>   0.912   0.168   2.572
system.time(async(get_value = TRUE))
#>    user  system elapsed 
#>   0.877   0.173  12.404

Однако, когда я помещаю определения slow_foo и async в сценарий в my_pkg/R, загружаю пакет через devtools::load_all() и затем запускаю async(get_value = TRUE) Я получаю следующая ошибка:

> async(get_value = TRUE)
List of 2
 $ node_idx: int 1
 $ node    :List of 5
  ..$ con         : 'sockconn' int 3
  .. ..- attr(*, "conn_id")=<externalptr> 
  ..$ host        : chr "localhost"
  .. ..- attr(*, "localhost")= logi TRUE
  ..$ rank        : int 1
  ..$ rshlogfile  : NULL
  ..$ session_info:List of 6
  .. ..$ r      :List of 15
  .. .. ..$ platform      : chr "x86_64-pc-linux-gnu"
  .. .. ..$ arch          : chr "x86_64"
  .. .. ..$ os            : chr "linux-gnu"
  .. .. ..$ system        : chr "x86_64, linux-gnu"
  .. .. ..$ status        : chr ""
  .. .. ..$ major         : chr "3"
  .. .. ..$ minor         : chr "6.1"
  .. .. ..$ year          : chr "2019"
  .. .. ..$ month         : chr "07"
  .. .. ..$ day           : chr "05"
  .. .. ..$ svn rev       : chr "76782"
  .. .. ..$ language      : chr "R"
  .. .. ..$ version.string: chr "R version 3.6.1 (2019-07-05)"
  .. .. ..$ nickname      : chr "Action of the Toes"
  .. .. ..$ os.type       : chr "unix"
  .. ..$ system :List of 8
  .. .. ..$ sysname       : chr "Linux"
  .. .. ..$ release       : chr "5.3.0-7625-generic"
  .. .. ..$ version       : chr "#27~1576774560~19.10~f432cd8-Ubuntu SMP Thu Dec 19 20:35:37 UTC "
  .. .. ..$ nodename      : chr "pop-os"
  .. .. ..$ machine       : chr "x86_64"
  .. .. ..$ login         : chr "janko"
  .. .. ..$ user          : chr "janko"
  .. .. ..$ effective_user: chr "janko"
  .. ..$ libs   : chr [1:4] "/home/janko/R/x86_64-pc-linux-gnu-library/3.6" "/usr/local/lib/R/site-library" "/usr/lib/R/site-library" "/usr/lib/R/library"
  .. ..$ pkgs   : NULL
  .. ..$ pwd    : chr "/path/to/my.pkg"
  .. ..$ process:List of 1
  .. .. ..$ pid: int 15552
  ..- attr(*, "class")= chr "SOCKnode"
 Error: Unexpected result (of class ‘NULL’ != ‘FutureResult’) retrieved for MultisessionFuture
 future (label = ‘<none>’, expression = ‘{; slow_foo(sleep = sleep); }’): . This suggests that 
the communication with MultisessionFuture worker (‘SOCKnode’ #1) is out of sync. 

Затем я попытался переписать async следующим образом:

async <- function(
  sleep = 1,
  get_value = FALSE
) {
  future::plan(future::multisession)

  promise <- future::future({
    do.call("slow_foo", list(sleep = sleep))
  }, globals = structure(TRUE, add = "slow_foo"))

  if (get_value) {
    future::value(promise)
  } else {
    TRUE
  }
}

Это дает мне следующую ошибку:

> async(get_value = TRUE)
List of 2
 $ node_idx: int 1
 $ node    :List of 5
  ..$ con         : 'sockconn' int 3
  .. ..- attr(*, "conn_id")=<externalptr> 
  ..$ host        : chr "localhost"
  .. ..- attr(*, "localhost")= logi TRUE
  ..$ rank        : int 1
  ..$ rshlogfile  : NULL
  ..$ session_info:List of 6
  .. ..$ r      :List of 15
  .. .. ..$ platform      : chr "x86_64-pc-linux-gnu"
  .. .. ..$ arch          : chr "x86_64"
  .. .. ..$ os            : chr "linux-gnu"
  .. .. ..$ system        : chr "x86_64, linux-gnu"
  .. .. ..$ status        : chr ""
  .. .. ..$ major         : chr "3"
  .. .. ..$ minor         : chr "6.1"
  .. .. ..$ year          : chr "2019"
  .. .. ..$ month         : chr "07"
  .. .. ..$ day           : chr "05"
  .. .. ..$ svn rev       : chr "76782"
  .. .. ..$ language      : chr "R"
  .. .. ..$ version.string: chr "R version 3.6.1 (2019-07-05)"
  .. .. ..$ nickname      : chr "Action of the Toes"
  .. .. ..$ os.type       : chr "unix"
  .. ..$ system :List of 8
  .. .. ..$ sysname       : chr "Linux"
  .. .. ..$ release       : chr "5.3.0-7625-generic"
  .. .. ..$ version       : chr "#27~1576774560~19.10~f432cd8-Ubuntu SMP Thu Dec 19 20:35:37 UTC "
  .. .. ..$ nodename      : chr "pop-os"
  .. .. ..$ machine       : chr "x86_64"
  .. .. ..$ login         : chr "janko"
  .. .. ..$ user          : chr "janko"
  .. .. ..$ effective_user: chr "janko"
  .. ..$ libs   : chr [1:4] "/home/janko/R/x86_64-pc-linux-gnu-library/3.6" "/usr/local/lib/R/site-library" "/usr/lib/R/site-library" "/usr/lib/R/library"
  .. ..$ pkgs   : NULL
  .. ..$ pwd    : chr "/path/to/my.pkg"
  .. ..$ process:List of 1
  .. .. ..$ pid: int 28157
  ..- attr(*, "class")= chr "SOCKnode"
 Error: Unexpected result (of class ‘NULL’ != ‘FutureResult’) retrieved for MultisessionFuture
 future (label = ‘<none>’, expression = ‘{; do.call("slow_foo", list(sleep = sleep)); }’): . 
This suggests that the communication with MultisessionFuture worker (‘SOCKnode’ #1) is out of sync. 

Я также пытался

promise <- future::future(
  do.call("slow_foo", list(sleep = sleep)),
  packages = "my.pkg"
)

и

promise <- future::future(
  slow_foo(sleep = sleep),
  packages = "my.pkg"
)

и

promise <- future::future(
  slow_foo(sleep = sleep),
  globals = c("slow_foo")
)

, но всегда получаю одну и ту же ошибку

...