满足条件后退出水管工 API
Quit a Plumber API once a condition is met
我正在尝试 运行 管道工 API 内联接收输入,一旦接收到正确的输入并满足指定条件,输入将返回到 globalenv 和API 自行关闭,以便脚本可以继续 运行。
我在调用 quit()、stop() 等的 @get 端点内指定了一个条件,none 其中成功关闭了 API。
我尝试使用 future 并行 运行 API 以便父脚本可以关闭 Plumber API。
似乎 Plumber API class 对象中实际上没有关闭 Plumber API 的方法,并且 API 不能从内部封闭。
我已经通过扩展文档、SO 和 Github 问题来寻找解决方案。建议的唯一半相关解决方案是使用 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端点后也没有。
关于如何实现这个的任何想法?
您可以通过以下方式查看 Iterative testing with plumber @Irène Steve's, Dec 23 2018:
trml <- rstudioapi::terminalCreate()
rstudioapi::terminalKill(trml)
她文章的摘录(第 3 版的第 2 版):
.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
}
运行 终端中的管道工在某些情况下可能会起作用,但由于我需要访问 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
}
我正在尝试 运行 管道工 API 内联接收输入,一旦接收到正确的输入并满足指定条件,输入将返回到 globalenv 和API 自行关闭,以便脚本可以继续 运行。
我在调用 quit()、stop() 等的 @get 端点内指定了一个条件,none 其中成功关闭了 API。
我尝试使用 future 并行 运行 API 以便父脚本可以关闭 Plumber API。
似乎 Plumber API class 对象中实际上没有关闭 Plumber API 的方法,并且 API 不能从内部封闭。
我已经通过扩展文档、SO 和 Github 问题来寻找解决方案。建议的唯一半相关解决方案是使用 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端点后也没有。
关于如何实现这个的任何想法?
您可以通过以下方式查看 Iterative testing with plumber @Irène Steve's, Dec 23 2018:
trml <- rstudioapi::terminalCreate()
rstudioapi::terminalKill(trml)
她文章的摘录(第 3 版的第 2 版):
.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
}
运行 终端中的管道工在某些情况下可能会起作用,但由于我需要访问 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
}