使用 Shiny 部署的 R 应用程序崩溃 'could not find function "httpdPort"'
Deployed R app with Shiny crash with 'could not find function "httpdPort"'
我有一个使用 Shiny
构建的应用程序(教程,其中 ui.R
和 server.R
取自此处:http://shiny.rstudio.com/tutorial/lesson1/)。
我在 shiny-frontend
文件夹中有这两个文件,如果我在 RStudio 中本地 runApp("shiny-frontend")
- 一切正常,我在浏览器中看到教程。
现在我希望通过 cloudfoundry 将同一个应用程序放入 Bluemix。我正在使用这个:http://www.ibm.com/developerworks/library/ba-rtwitter-app/ 作为教程,但遇到错误。
我有一个 start.r
文件,我 运行 作为 R -f ./start.r --gui-none --no-save
。我正在使用 https://github.com/virtualstaticvoid/heroku-buildpack-r 构建包。
我的 start.r
看起来像这样(取自 bluemix 教程,稍作修改):
library(shiny)
if (Sys.getenv('VCAP_APP_PORT') == "") {
print("Running Shiny")
runApp("shiny-frontend")
} else {
# In case we're on Cloudfoundry, run this:
print('running on CF')
# Starting Rook server during CF startup phase - after 60 seconds start the actual Shiny server
library(Rook)
myPort <- as.numeric(Sys.getenv('VCAP_APP_PORT'))
myInterface <- Sys.getenv('VCAP_APP_HOST')
status <- -1
# R 2.15.1 uses .Internal, but the next release of R will use a .Call.
# Either way it starts the web server.
if (as.integer(R.version[["svn rev"]]) > 59600) {
status <- .Call(tools:::startHTTPD, myInterface, myPort)
} else {
status <- .Internal(startHTTPD(myInterface, myPort))
}
if (status == 0) {
unlockBinding("httpdPort", environment(tools:::startDynamicHelp))
assign("httpdPort", myPort, environment(tools:::startDynamicHelp))
s <- Rhttpd$new()
s$listenAddr <- myInterface
s$listenPort <- myPort
s$print()
Sys.sleep(60)
s$stop()
}
# run shiny server
sink(stderr())
options(bitmapType='cairo')
getOption("bitmapType")
print("test")
write("prints to stderr", stderr())
write("prints to stdout", stdout())
write(port, stdout())
runApp('shiny-frontend',port=myPort,host="0.0.0.0",launch.browser=F)
}
我的 init.r
看起来像这样:
install.packages("shiny", clean=T)
install.packages("Rook", clean=T)
然后当我 运行 时,一切都已正确部署,但是当我尝试按路线走时,我在日志中看到错误:
* ERR Calls: <Anonymous> -> startDynamicHelp
* ERR Execution halted
* ERR Error in startDynamicHelp(FALSE) : could not find function "httpdPort"
我还注意到每次分配的端口都不一样,这很奇怪而且 bluemix 仪表板中的路由没有提到它。但是我将端口输出到日志,并使用那个数字。
而且我的做法似乎有点太复杂了,所以如果有人能提出更简单的方法,我将不胜感激
我花了一段时间才明白这个错误是由 R 抛出的,因为它找不到 函数(不是值)httpdPort
。不是将 httpdPort
绑定到一个函数,而是将它绑定到一个值。 s$stop()
行引起了麻烦。它调用 startDynamicHelp
假设 httpdPort 是在环境 tools
.
中定义的函数
要解决此问题,您可以将代码中的块 if (status == 0){...}
更改为:
if (status == 0) {
getSettable <- function(default){
function(obj = NA){if(!is.na(obj)){default <<- obj};
default}
}
myHttpdPort <- getSettable(myPort)
unlockBinding("httpdPort", environment(tools:::startDynamicHelp))
assign("httpdPort", myHttpdPort, environment(tools:::startDynamicHelp))
s <- Rhttpd$new()
s$listenAddr <- myInterface
s$listenPort <- myPort
s$print()
Sys.sleep(60)
s$stop()
}
我有一个使用 Shiny
构建的应用程序(教程,其中 ui.R
和 server.R
取自此处:http://shiny.rstudio.com/tutorial/lesson1/)。
我在 shiny-frontend
文件夹中有这两个文件,如果我在 RStudio 中本地 runApp("shiny-frontend")
- 一切正常,我在浏览器中看到教程。
现在我希望通过 cloudfoundry 将同一个应用程序放入 Bluemix。我正在使用这个:http://www.ibm.com/developerworks/library/ba-rtwitter-app/ 作为教程,但遇到错误。
我有一个 start.r
文件,我 运行 作为 R -f ./start.r --gui-none --no-save
。我正在使用 https://github.com/virtualstaticvoid/heroku-buildpack-r 构建包。
我的 start.r
看起来像这样(取自 bluemix 教程,稍作修改):
library(shiny)
if (Sys.getenv('VCAP_APP_PORT') == "") {
print("Running Shiny")
runApp("shiny-frontend")
} else {
# In case we're on Cloudfoundry, run this:
print('running on CF')
# Starting Rook server during CF startup phase - after 60 seconds start the actual Shiny server
library(Rook)
myPort <- as.numeric(Sys.getenv('VCAP_APP_PORT'))
myInterface <- Sys.getenv('VCAP_APP_HOST')
status <- -1
# R 2.15.1 uses .Internal, but the next release of R will use a .Call.
# Either way it starts the web server.
if (as.integer(R.version[["svn rev"]]) > 59600) {
status <- .Call(tools:::startHTTPD, myInterface, myPort)
} else {
status <- .Internal(startHTTPD(myInterface, myPort))
}
if (status == 0) {
unlockBinding("httpdPort", environment(tools:::startDynamicHelp))
assign("httpdPort", myPort, environment(tools:::startDynamicHelp))
s <- Rhttpd$new()
s$listenAddr <- myInterface
s$listenPort <- myPort
s$print()
Sys.sleep(60)
s$stop()
}
# run shiny server
sink(stderr())
options(bitmapType='cairo')
getOption("bitmapType")
print("test")
write("prints to stderr", stderr())
write("prints to stdout", stdout())
write(port, stdout())
runApp('shiny-frontend',port=myPort,host="0.0.0.0",launch.browser=F)
}
我的 init.r
看起来像这样:
install.packages("shiny", clean=T)
install.packages("Rook", clean=T)
然后当我 运行 时,一切都已正确部署,但是当我尝试按路线走时,我在日志中看到错误:
* ERR Calls: <Anonymous> -> startDynamicHelp
* ERR Execution halted
* ERR Error in startDynamicHelp(FALSE) : could not find function "httpdPort"
我还注意到每次分配的端口都不一样,这很奇怪而且 bluemix 仪表板中的路由没有提到它。但是我将端口输出到日志,并使用那个数字。
而且我的做法似乎有点太复杂了,所以如果有人能提出更简单的方法,我将不胜感激
我花了一段时间才明白这个错误是由 R 抛出的,因为它找不到 函数(不是值)httpdPort
。不是将 httpdPort
绑定到一个函数,而是将它绑定到一个值。 s$stop()
行引起了麻烦。它调用 startDynamicHelp
假设 httpdPort 是在环境 tools
.
要解决此问题,您可以将代码中的块 if (status == 0){...}
更改为:
if (status == 0) {
getSettable <- function(default){
function(obj = NA){if(!is.na(obj)){default <<- obj};
default}
}
myHttpdPort <- getSettable(myPort)
unlockBinding("httpdPort", environment(tools:::startDynamicHelp))
assign("httpdPort", myHttpdPort, environment(tools:::startDynamicHelp))
s <- Rhttpd$new()
s$listenAddr <- myInterface
s$listenPort <- myPort
s$print()
Sys.sleep(60)
s$stop()
}