有没有一种方法可以为R中的管道工API的每次调用提供一个干净的R会话?

xtupzzrd  于 2023-09-27  发布在  其他
关注(0)|答案(1)|浏览(76)

我可以访问plumber API,它可以为我处理一些自动流水线工作流。然而,每个作业都运行在相同的R会话上,我有点担心不同的调用会相互干扰。
在我的脑海中,我的愿望是每一个呼叫都从一个新的R会话开始。在R中定期编程时,我只需要重新启动会话并进行干净的设置,但对于plumber服务器,这似乎“不那么容易”。一些阅读还显示,在没有重新启动的情况下“清理”R会话并不是一件简单的事情。
当然,我也愿意接受其他建议。欢迎任何建议和见解。最后,如果输入相同,我只希望API调用返回相同的内容。

ctehm74n

ctehm74n1#

正如Konrad Rudolph的评论中所建议的那样,callr可以很好地完成这项工作。
对不同的包多次执行1.-3.(参见代码块)将表明每次运行都是在新的R会话中执行的(参见process_id),因此搜索路径是独立的。

# put this code into the file plumber.R and run:
# plumber::plumb("plumber.R")$run(port=9999)
# 1. click "Try it out"
# 2. enter a package name that you want to try
# 3. click "Execute"

#* @get /search_path
#* @param lib library to load
function(lib) {
  # callr runs the anonymous function in a fresh session 
  rp <- callr::r_bg({
    function(lib) {
      library(package = lib, character.only = TRUE)
      return(list(search_path = search(),
                  process_id = Sys.getpid(),
                  the_time = Sys.time()))
    }
  },
  args = list(lib = lib))
  
  # wait for a result with 30 seconds timeout
  rp$wait(30000)
  if(rp$is_alive() == TRUE) {
    rp$kill()
    stop("time exceeded")
  }
  # return the result
  rp$get_result()
}

有点离题,但在这个上下文中可能也很有趣:允许并行请求可以通过future包启用。

# submit two requests for packages within less than 10 seconds of
# each other and compare the time stamps to see that they were processed
# in parallel and in different sessions

future::plan(future::multisession)

#* @get /search_path
#* @param lib library to load
function(lib) {
  future::future({
    # callr runs the anonymous function in a fresh session 
    rp <- callr::r_bg({
      function(lib) {
        Sys.sleep(10)
        library(package = lib, character.only = TRUE)
        return(list(search_path = search(),
                    process_id = Sys.getpid(),
                    the_time = Sys.time()))
      }
    },
    args = list(lib = lib))
    
    # wait for a result with 30 seconds timeout
    rp$wait(30000)
    if(rp$is_alive() == TRUE) {
      rp$kill()
      stop("time exceeded")
    }
    # return the result
    rp$get_result()
  }, seed = TRUE)
}

相关问题