R语言 从S3下载文件时,是否可以更新闪亮的进度条?

ars1skjm  于 2023-06-19  发布在  其他
关注(0)|答案(1)|浏览(108)
    • bounty明天到期**。回答此问题可获得+100声望奖励。thelawnmowerman希望引起更多关注这个问题。

我正在使用AWS S3来存储将从闪亮 Jmeter 板下载的文件。使用s3load(..., with_progress = TRUE)方法,我可以下载一个文件,控制台中会显示一个进度条,而在s3load方法完成之前,Shiny Jmeter 板会被阻塞。我甚至可以使用Waiter同时显示一个微调器,以便用户看到正在发生的事情。但是,我可以在闪亮中显示实际的进展增量吗?百分之十……百分之二十……和打印到控制台的那个一样吗
capture.output这样的方法可以检索s3load方法的输出,但一旦完成,所以我不能即时更新网页。
这可能吗?怎么走?
我已经看到了一些相关但已回答的问题,like this one

    • 编辑**

我尝试过使用capture.outputreactiveFileReader的方法,但网站只在下载完成后更新:

library(shiny)

ui <- fluidPage(
  uiOutput("progress")
)

server <- function(input, output, session) {
  file.create("progress.txt")
  progressInfo <- reactiveFileReader(250, session, 'progress.txt', readLines)
  
  output$progress <- renderTable({
    progressInfo()
  })

  observe({
    capture.output(
      hc <- aws.s3::s3readRDS(path, bucket, show_progress = TRUE),
      file = 'progress.txt',
      append = FALSE,
      type = 'output'
    )
  })
}

shinyApp(ui, server)

我假设这是因为长时间运行的操作s3readRDS阻塞了单个线程。我已经检查了文件progress.txt在运行中正确更新,但是progressInfo直到下载结束才失效。
我想我需要使用future包来运行长时间运行的任务,以释放主UI线程,对吗?有谁能为我指明正确的方向来调整我的代码?

yhuiod9q

yhuiod9q1#

如果您需要使用future packagepromise package在单独的线程或进程中运行长时间运行的任务(以允许Shiny应用在任务运行时保持响应并更新UI),它可能看起来像:

library(future)
library(promises)

server <- function(input, output, session) {
  file.create("progress.txt")
  progressInfo <- reactiveFileReader(250, session, 'progress.txt', readLines)
  
  output$progress <- renderTable({
    progressInfo()
  })

  plan(multiprocess) # or use `plan(multisession)` for Windows

  observe({
    future({
      capture.output(
        hc <- aws.s3::s3readRDS(path, bucket, show_progress = TRUE),
        file = 'progress.txt',
        append = FALSE,
        type = 'output'
      )
    }) %...>% {
      # code to run after the download is complete, if any
    }
  })
}

shinyApp(ui, server)

plan(multiprocess)行将future包设置为在单独的进程中运行以下任务。如果您使用的是不支持分叉进程的Windows系统,则可以将此行替换为plan(multisession)
future({ ... })函数调用在单独的进程中运行下载任务,%...>%运算符用于将promise链接到任务完成时实现的未来。在这种情况下,下载完成后它不会执行任何操作,但如果需要,您可以在那里添加代码。
这将允许Shiny应用程序在文件下载时保持响应并更新进度条。reactiveFileReader将保持每250毫秒阅读一次progress.txt文件,并更新UI中的进度条。
您还需要处理下载过程中可能发生的错误。您可以在%...>%操作符之后添加.catch块,以处理将来可能抛出的任何异常。

相关问题