带有“无法找到功能“ httpdPort””的Shiny崩溃的已部署R应用程序 [英] Deployed R app with Shiny crash with 'could not find function "httpdPort"'

查看:89
本文介绍了带有“无法找到功能“ httpdPort””的Shiny崩溃的已部署R应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆