【问题标题】:R shiny session with multiple users connected连接多个用户的 R 闪亮会话
【发布时间】:2020-06-22 09:43:48
【问题描述】:

最小的可重现示例:

library("shiny")

ui <- fluidPage(
  actionButton("button1", "Run 1"),
  actionButton("button2", "Run 2")
)

server <- function(session, input, output) {
  cat("session starts\n")
  observeEvent(input$button1, {
    cat("1 starts\n")
    Sys.sleep(15)
    cat("1 stops\n")
  })

  observeEvent(input$button2, {
    cat("2 starts\n")
    Sys.sleep(15)
    cat("2 stops\n")
  })
}

shinyApp(ui = ui, server = server)

每个按钮模拟运行一些长时间的 CPU 密集型算法。

  1. 运行应用程序并在一个浏览器选项卡上打开会话。
  2. 打开另一个浏览器选项卡,其中包含正在运行的应用程序的另一个会话。
  3. 在第一个选项卡中启动 Run 1。转到第二个浏览器选项卡并启动 Run 2

问题: 第二个按钮观察者不会独立启动。它一直等到第一个会话中的第一次运行完成。我认为闪亮的会话是独立的。每个 R 会话中,闪亮如何处理多个闪亮会话?如果多个用户想同时连接到应用程序怎么办?

如何处理同时运行同一个应用的多个用户? 谢谢

【问题讨论】:

  • R 是单线程的,所以默认情况下,请求将排队。 Shiny 团队推出了promisesfutures 包,让用户可以进行async 操作rstudio.github.io/promises/articles/shiny.html
  • 我想这是我看到的唯一解决方案。我只是认为闪亮固有地使用其中一个并行化包来处理多个会话。这就提出了一个问题:是否可以使用 'future' 包将整个服务器功能包装在单个 Promise 中?
  • 不要低估单线程应用程序的好处,不用担心太多。 Node,shiny 的后端,是单线程的,但它可以在任何给定时间轻松支持 50k 并发用户。 Wrt 在服务器周围使用 Promise,简短的回答可能是否定的。如果您想将应用程序包装在“独立”应用程序中,请查看 docker shinyproxy.io
  • 我们有机器学习功能,最多可能需要几十分钟。我知道 R 是单线程的,但正如我所说,我假设(错误地 - 我的错)闪亮是并行的。

标签: r session shiny user-management


【解决方案1】:

限制每个工作进程的连接数,即为每个用户提供自己的 R 工作进程。您可以通过将每个工作进程允许的并发连接数设置为 1 来做到这一点。

如果您通过 shinyapps.io 部署您的应用程序,请参阅此处的说明和更多背景信息: https://shiny.rstudio.com/articles/scaling-and-tuning.html

如果您要部署到自己的闪亮服务器,请参阅此处的说明和更多背景信息: https://support.rstudio.com/hc/en-us/articles/220546267-Scaling-and-Performance-Tuning-Applications-in-Shiny-Server-Pro

最小的工作示例:

library("shiny")

ui <- fluidPage(
  actionButton("button1", "Run 1"),
  actionButton("button2", "Run 2")
)

server <- function(session, input, output) {

  observeEvent(input$button1, {

    withProgress(message = 'Run 1', detail = '', value = 0, {
        for (i in 1:15) {
            incProgress(1/15)
            Sys.sleep(0.25)
        }
    })

  })

  observeEvent(input$button2, {

    withProgress(message = 'Run 2', detail = '', value = 0, {
        for (i in 1:15) {
            incProgress(1/15)
            Sys.sleep(0.25)
        }
    })

  })
}

shinyApp(ui = ui, server = server)

【讨论】:

  • 嗨@Ash,请问ShinyServer如何处理不同用户的下载文件?例如,假设我的应用程序允许用户根据他们的输入下载一些生成的数据。文件通过downloadHandler写入.csv,文件名设置为“data.csv”。那么如果有两个用户同时点击下载按钮,他们会得到自己的数据文件还是其中一个会覆盖另一个?我了解到每个用户都有自己的会话,但是关于编写文件,他们会有自己的路径吗?
  • 你好@YunzhaoXing。那不会是问题。 Shiny 不会在用户之间混合数据,无论每个工作进程是否有多个用户。唯一的例外是,如果您有意使数据全局化,即使用
  • 嗨@Ash,感谢您的解释。我知道数据不会在用户之间混合,但我对下载文件有点困惑。在闪亮的文档中,downloadHandler 中的“内容”参数的描述中,它说“......一个单独的参数文件,它是一个不存在的临时文件的文件路径(字符串),并将内容写入该文件路径...... ”。似乎闪亮会首先将数据保存到服务器上的临时文件中,然后让用户下载它。由于所有应用程序用户将具有相同的下载文件名,会不会有任何冲突?每个用户都会有新的路径吗?
  • Shiny Server 开源版本的性能调整设置是否可用? support.rstudio.com/hc/en-us/articles/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
相关资源
最近更新 更多