带有“无法找到功能“ httpdPort””的Shiny崩溃的已部署R应用程序 [英] 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
文件夹中有这两个文件,如果我 runApp( shiny-frontend)
在RStudio中本地运行-一切正常,我在浏览器中看到了该教程。
I have an application built with Shiny
(a tutorial, where ui.R
and server.R
are taken from here: http://shiny.rstudio.com/tutorial/lesson1/).
I have these two files in shiny-frontend
folder, and if I runApp("shiny-frontend")
locally in RStudio - everything works great and I see the tutorial in my browser.
现在,我希望将同一应用程序通过cloudfoundry放入Bluemix中。我正在使用: http://www.ibm.com/developerworks/库/ ba-rtwitter-app / 作为教程,但遇到错误。
Now I want the same app to be put into Bluemix via cloudfoundry. I'm using this: http://www.ibm.com/developerworks/library/ba-rtwitter-app/ as a tutorial, but struggling with an error.
我有一个 start.r
文件,我以 R -f ./start.r --gui-none --no-save
运行。我正在使用 https://github.com/virtualstaticvoid/heroku-buildpack-r buildpack。
I have a start.r
file which I run as R -f ./start.r --gui-none --no-save
. I'm using https://github.com/virtualstaticvoid/heroku-buildpack-r buildpack.
我的 start.r
看起来像这样(摘自bluemix教程,做了很小的修改):
My start.r
looks like this (taken from the bluemix tutorial with a very minor modifications):
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)
然后,当我运行时,一切都正确部署,但是当我尝试沿着路线走,我在日志中看到错误:
Then when I run, everything is deployed correctly, but then when I try to go by the route, I see an error in the log:
* ERR Calls: <Anonymous> -> startDynamicHelp
* ERR Execution halted
* ERR Error in startDynamicHelp(FALSE) : could not find function "httpdPort"
我还注意到分配的端口每次都是不同的,这很奇怪,bluemix仪表板中的路由没有提及它。但是我将端口输出到日志,并使用该数字。
I also noticed that assigned port is different every time, which is weird and the route in bluemix dashboard does not mention it. But I output the port to the log, and use that number.
同样,我这样做的方式似乎太复杂了,因此,如果有人可以建议更简单的方法
Also the way I'm doing it seems a bit too complicated, so if anybody could suggest any easier way, I'd appreciate it
推荐答案
我花了一段时间才明白R抛出了这个错误,因为它不能找到功能(不是值) httpdPort
。而不是将 httpdPort
绑定到函数,而是将其绑定到值。 s $ stop()
行是引起麻烦的行。它调用 startDynamicHelp
,假定httpdPort是在环境 tools
中定义的函数。
it took me a while to understand that this error is thrown by R because it can not find the function (not the value) httpdPort
. Instead of binding httpdPort
to a function you are binding it to a value. The line s$stop()
is the one causing trouble. It calls startDynamicHelp
that assumes that httpdPort is a function defined in the environment tools
.
要解决此问题,您可以将代码中的块 if(status == 0){...}
更改为:
To fix this issue you can change the block if (status == 0){...}
in your code to:
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()
}
这篇关于带有“无法找到功能“ httpdPort””的Shiny崩溃的已部署R应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!