RODBC查询降低了Shiny Server

时间:2015-12-16 15:44:57

标签: r odbc rodbc shiny

我们在RedHat 6.7上运行Shiny Server(和Shiny Dashboard),并且在尝试使用RODBC查询数据库时遇到了段错误。当我们将文件导入app.R或向server.R文件中的数据库发出查询请求时,会发生这种情况。当我们在R控制台中运行相同的代码时,它可以正常工作。

似乎Shiny和RODBC之间必然存在某种类型的互动导致了这个问题。作为一种解决方法,我们正在使用RJDBC,它工作正常,但我们担心它不适合我们。而且速度很慢。

任何人都知道我们可以做些什么来使RODBC正常工作?

以下是我们为生成错误而运行的代码:

library(RODBC)
myConn <- odbcConnect("DSN_Name")
segment <- sqlQuery(myConn, "SELECT * FROM foo")

如果您使用基本的Shiny应用程序并添加上面的代码,您将能够重新创建错误。以下是RStudio的代码。

ui.R

library(shiny)
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# Sidebar with a slider input for the number of bins
sidebarLayout(
  sidebarPanel(
    sliderInput("bins",
              "Number of bins:",
              min = 1,
              max = 50,
              value = 30)
),

# Show a plot of the generated distribution
mainPanel(
  plotOutput("distPlot")
)
  )
    ))

server.R

library(shiny)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
# Expression that generates a histogram. The expression is
# wrapped in a call to renderPlot to indicate that:
#
#  1) It is "reactive" and therefore should re-execute automatically
#     when inputs change
#  2) Its output type is a plot
output$distPlot <- renderPlot({
x    <- faithful[, 2]  # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = input$bins + 1)

# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
  })

以下是来自服务器的错误消息:

An error has occurred

The application exited unexpectedly.

socket hang up

Listening on http://127.0.0.1:37079 Attaching package: ‘shinydashboard’

The following object is masked from ‘package:graphics’: box

Loading required package: ggplot2

Attaching package: ‘plotly’ The following object is masked from ‘package:ggplot2’: last_plot

The following object is masked from ‘package:graphics’: layout Attaching package: ‘DT’

The following objects are masked from ‘package:shiny’: dataTableOutput, renderDataTable

Loading required package: DBI Loading required package: rJava Loading required package:

NLP Attaching package: ‘NLP’ The following object is masked from ‘package:ggplot2’: annotate

Loading required package: RColorBrewer

*** caught segfault ***
address (nil), cause 'unknown'

Traceback:
1: .Call(C_RODBCDriverConnect, as.character(connection), id, as.integer(believeNRows), as.logical(readOnlyOptimize))
2: odbcDriverConnect("DSN=DB_Name")
3: eval(expr, envir, enclos)
4: eval(expr, p)
5: eval.parent(Call)
6: odbcConnect("DB_Name")
7: eval(expr, envir, enclos)
8: eval(ei, envir)
9: withVisible(eval(ei, envir))
10: source("RODBC.R")
11: eval(expr, envir, enclos)
12: eval(ei, envir)
13: withVisible(eval(ei, envir))
14: source(file, ..., keep.source = TRUE, encoding = checkEncoding(file))
15: sourceUTF8(fullpath, local = new.env(parent = globalenv()))
16: func(fname, ...)
17: appObj()
18: handler(req)
19: handler(req)
20: handler(...)
21: handlers$invoke(req)
22: handler(req)
23: func(req)
24: doTryCatch(return(expr), name, parentenv, handler)
25: tryCatchOne(expr, names, parentenv, handlers[[1L]])
26: tryCatchList(expr, classes, parentenv, handlers)
27: tryCatch(expr, error = function(e) { call <- conditionCall(e) if (!is.null(call)) { if (identical(call[[1L]], quote(doTryCatch))) call <- sys.call(-4L) dcall <- deparse(call)[1L] prefix <- paste("Error in", dcall, ": ") LONG <- 75L msg <- conditionMessage(e) sm <- strsplit(msg, "\n")[[1L]] w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L], type = "w") if (is.na(w)) w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L], type = "b") if (w > LONG) prefix <- paste0(prefix, "\n ") } else prefix <- "Error : " msg <- paste0(prefix, conditionMessage(e), "\n") .Internal(seterrmessage(msg[1L])) if (!silent && identical(getOption("show.error.messages"), TRUE)) { cat(msg, file = stderr()) .Internal(printDeferredWarnings()) } invisible(structure(msg, class = "try-error", condition = e))})
28: try({ inputStream <- if (is.null(data)) nullInputStream else InputStream$new(data, dataLength) req$rook.input <- inputStream req$rook.errors <- ErrorStream$new() req$httpuv.version <- packageVersion("httpuv") if (!is.null(req$HTTP_CONTENT_TYPE)) req$CONTENT_TYPE <- req$HTTP_CONTENT_TYPE if (!is.null(req$HTTP_CONTENT_LENGTH)) req$CONTENT_LENGTH <- req$HTTP_CONTENT_LENGTH resp <- func(req) if (is.null(resp) || length(resp) == 0) return(NULL) resp$headers <- lapply(resp$headers, paste) if ("file" %in% names(resp$body)) { filename <- resp$body[["file"]] owned <- FALSE if ("owned" %in% names(resp$body)) owned <- as.logical(resp$body$owned) resp$body <- NULL resp$bodyFile <- filename resp$bodyFileOwned <- owned } resp})
29: rookCall(.app$call, req, req$.bodyData, seek(req$.bodyData))
30: (function (req) { on.exit({ if (!is.null(req$.bodyData)) { close(req$.bodyData) } req$.bodyData <- NULL }) rookCall(.app$call, req, req$.bodyData, seek(req$.bodyData))})(<environment>)
31: eval(substitute(expr), envir, enclos)
32: evalq((function (req) { on.exit({ if (!is.null(req$.bodyData)) { close(req$.bodyData) } req$.bodyData <- NULL }) rookCall(.app$call, req, req$.bodyData, seek(req$.bodyData))})(<environment>), <environment>)
33: doTryCatch(return(expr), name, parentenv, handler)
34: tryCatchOne(expr, names, parentenv, handlers[[1L]])
35: tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
36: doTryCatch(return(expr), name, parentenv, handler)
37: tryCatchOne(tryCatchList(expr, names[-nh], parentenv, handlers[-nh]), names[nh], parentenv, handlers[[nh]])
38: tryCatchList(expr, classes, parentenv, handlers)
39: tryCatch(evalq((function (req) { on.exit({ if (!is.null(req$.bodyData)) { close(req$.bodyData) } req$.bodyData <- NULL }) rookCall(.app$call, req, req$.bodyData, seek(req$.bodyData))})(<environment>), <environment>), error = function (x) x, interrupt = function (x) x)
40: .Call("httpuv_run", PACKAGE = "httpuv", timeoutMillis)
41: run(timeoutMs)
42: service(timeout)
43: serviceApp()
44: withCallingHandlers(expr, error = function(e) { handle <- getOption("shiny.error") if (is.function(handle)) handle()})
45: shinyCallingHandlers(while (!.globals$stopped) { serviceApp() Sys.sleep(0.001)})
46: runApp(Sys.getenv("SHINY_APP"), port = port, launch.browser = FALSE) aborting ...

1 个答案:

答案 0 :(得分:0)

首先,我要感谢RStudio的Joe Cheng。他是一个巨大的帮助,真的竭尽全力帮助我解决这个问题。非常感谢。

所以我遇到的问题是(恕我直言)糟糕的代码结构的结果。以下是我犯的错误,一旦他们被修复,事情按预期工作。

  • 错误1 - 我正在调用server.R文件app.R.这是个 过时的命名约定,不应使用。
  • 错误2 - 我的server.R文件的最后一行称为函数shinyApp(ui, 服务器)。这导致我的odbc驱动程序出现重大问题 数据库。它创建了一个非常大的堆栈,我的客户端将在那里 推得太远,导致了一个段错误。故事的道德启示, 使用服务器功能结束server.R文件。

我的闪亮服务器现在正在快乐地运行! :)

感谢Joe的帮助。

这是完整的主题 - https://groups.google.com/forum/#!topic/shiny-discuss/66Ve60ugmHs