满足条件后退出Plumber API

时间:2019-06-26 19:03:23

标签: r plumber

我试图内联运行Plumber API以接收输入,一旦接收到正确的输入并满足指定的条件,则将输入返回给globalenv,并且API自身将关闭,以便脚本可以继续执行运行。

我已经在@get端点中指定了一个条件,该条件调用quit(),stop()等,但没有一个可以成功关闭API。

我试图使用Future并行运行API,以便父脚本可以关闭Plumber API。

看来,Plumber API类对象中实际上没有关闭Plumber API的方法,而且该API本身也无法关闭。

我一直在寻找扩展文档,SO和Github Issues寻找解决方案。建议的唯一半相关解决方案是使用R.Utils :: withTimeout创建有时间限制的超时。但是,此方法也无法关闭API。

一个简单的用例: 主脚本:

library(plumber)
code_api <- plumber::plumb("code.R")
code_api$run(port = 8000)

code.R


#' @get /<code>
function(code) {
  print(code)
  if (nchar(code) == 3) {
    assign("code",code,envir = globalenv())
  quit()}
  return(code)
}
#' @get /exit
function(exit){
  stop()
}

该输入已成功返回到全局环境,但是该API之后或调用/ exit端点之后都不会关闭。

关于如何实现此目标的任何想法?

2 个答案:

答案 0 :(得分:0)

您可以通过以下方式查看Iterative testing with plumber @Irène Steve's, Dec 23 2018

  • trml <- rstudioapi::terminalCreate()
  • rstudioapi::terminalKill(trml)

她的文章摘录(第2版,第3版):

.state <- new.env(parent = emptyenv()) #create .state when package is first loaded

start_plumber <- function(path, port) {
    trml <- rstudioapi::terminalCreate(show = FALSE)
    rstudioapi::terminalSend(trml, "R\n") 
    Sys.sleep(2)
    cmd <- sprintf('plumber::plumb("%s")$run(port = %s)\n', path, port)
    rstudioapi::terminalSend(trml, cmd)

    .state[["trml"]] <- trml #store terminal name
    invisible(trml)
}

kill_plumber <- function() {
    rstudioapi::terminalKill(.state[["trml"]]) #access terminal name
}

答案 1 :(得分:0)

在终端中运行 Plumber 可能在某些情况下有效,但由于我需要访问 R 会话(对于 insertText),我不得不想出不同的方法。虽然不理想,但以下解决方案有效:

# plumber.R
#* Insert 
#* @param msg The msg to insert to the cursor location 
#* @post /insert
function(msg="") {
  rstudioapi::insertText(paste0(msg))
  stop_plumber(Sys.getpid())
}

.state <- new.env(parent = emptyenv())  #create .state when package is first loaded

stop_plumber <- function(pid) {
  trml <- rstudioapi::terminalCreate(show = FALSE)
  Sys.sleep(2) # Wait for the terminal to initialize  
  # Wait a bit for the Plumber to flash the buffers and then send a SIGINT to the R session process,
  # to terminate the Plumber
  cmd <- sprintf("sleep 2 && kill -SIGINT %s\n", pid)
  rstudioapi::terminalSend(trml, cmd)
  .state[["trml"]] <- trml  # store terminal name
  invisible(trml)
  Sys.sleep(2) # Wait for the Plumber to terminate and then kill the terminal
  rstudioapi::terminalKill(.state[["trml"]])  # access terminal name
}