我试图内联运行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端点之后都不会关闭。
关于如何实现此目标的任何想法?
答案 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
}