在 R Shiny 中運行後台進程

溫家寶

我寫了一個腳本,如果按下按鈕,它應該運行後台進程。該過程完成後,我想進一步處理結果。

下面是我的腳本。此腳本中的過程是 10 秒休眠,然後檢索當前文件夾中文件的名稱列表。後台進程在函數 printLS() 中找到。這是由函數 r_bg() 在後台執行的。

library(shiny)
library(callr)

ui <- fluidPage(
  textOutput("clock"), br(), 
  actionButton("startjob","Start Job"), br(), br(), 
  uiOutput("LS")
)

server <- function(input, output, session) 
{
  output$clock <- renderText({
    invalidateLater(1)
    format(Sys.time(), "%d %b %H:%M:%S")
  })

  global <- reactiveValues(result = NULL)

  printLS <- function() {
    Sys.sleep(10)
    result <- system2(
      command = "ls",
      args    = c("-l"),
      stdout  = TRUE,
      stderr  = TRUE
    )
  }

  observeEvent(input$startjob, {
    global$result <- r_bg(func = printLS, supervise = F)
    global$result$wait()
  })

  output$LS <- renderUI({
    req(global$result)

    if (!global$result$is_alive())
      p(HTML(paste(global$result$get_result(), sep = "", collapse = "<br>")))
  })
}

shinyApp(ui = ui, server = server)

在應用程序中還顯示了一個時鐘。不幸的是,當後台進程運行時時鐘停止運行。我希望時鐘在後台進程中繼續運行。我通過刪除'global$result$wait()'來嘗試這個。但是它會查看後台進程是否一直在運行而沒有提供任何輸出(即當前文件夾中的文件列表)。

我現在的問題是:如何在後台進程運行時讓時鍾繼續運行?

布列陶夫

正如這裡的示例中所解釋的,這wait()意味著我們必須等待後台作業的結果才能繼續其餘進程。

在運行後台作業時保持時鐘更新的一種方法是使用poll_io()檢查作業是否完成(請注意,它比使用更好poll_io()is_alive()如本Github 評論中所述)。我在這個問題中做了類似的事情,雖然一般的應用程序有點複雜。

這是您需要在服務器中修改的內容:

  observeEvent(input$startjob, {
    global$result <- r_bg(func = printLS, supervise = F)
  })
  
  output$LS <- renderUI({
    req(input$startjob)
    if (global$result$poll_io(0)["process"] == "timeout") {
      invalidateLater(1000)
    } else {
      p(HTML(paste(global$result$get_result(), sep = "", collapse = "<br>")))
    }
  })

請注意,這system2(command = "ls", args = c("-l"), stdout = TRUE, stderr = TRUE)在我的筆記本電腦上不起作用,所以我system("ls -l")改用了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章