R光明的未来:计划(多进程)/计划(多核)+杀死长时间运行的进程 [英] R shiny future: plan(multiprocess)/plan(multicore) + Kill long running process

查看:105
本文介绍了R光明的未来:计划(多进程)/计划(多核)+杀死长时间运行的进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写这篇文章,以寻求使用plan(multiprocess)或plan(multicore)的帮助,并杀死我的闪亮应用程序中长时间运行的进程.该应用程序具有多个未来事件(长时间运行的流程),这些事件通过单击相应的actionButton即可运行.以下是在应用程序的服务器功能内使用的future()命令示例应用程序.而且我一直在使用stopMulticoreFuture(fut)杀死进程.

I am writing this to seek some help in using plan(multiprocess) or plan(multicore) and killing long running processes in my shiny app. The app has multiple future events (long running processes) that run on clicking their corresponding actionButton. Below is an example app of future() command used within the server function in the app. And i have been using stopMulticoreFuture(fut) to kill the processes.

library(shiny)
library(shinydashboard)
library(promises)
plan(multicore)
library(ipc)
sidebar <- dashboardSidebar(width = 200, sidebarMenu(id = "tabs",
                                                     menuItem("File", tabName = "tab1", icon = icon("fas fa-file"))))
body <- tabItem(tabName = "tab1",h2("Input File"),
                fluidRow(tabPanel(
                    "Upload file",
                    value = "upload_file",
                    fileInput(
                      inputId = "uploadFile",
                      label = "Upload Input file",
                      multiple = FALSE,
                      accept = c(".txt")
                    ),
                    checkboxInput('header', label = 'Header', TRUE)
                  ),
                  box(
                    title = "Filter X rows",
                    width = 7,
                    status = "info",
                    tabsetPanel(
                      id = "input_tab",
                      tabPanel(
                        "Parameters",
                        numericInput(
                          "nrows",
                          label = "Entire number of rows",
                          value = 5,
                          max = 10
                        ),
                        actionButton("run", "Analyze"),
                        actionButton("cancel", "Cancel")
                      ),
                      tabPanel(
                        "Results",
                        value = "results",
                        navbarPage(NULL,
                                   tabPanel(
                                     "Table", DT::dataTableOutput("res_table"), 
                                     icon = icon("table")
                                   )),
                        downloadButton("downList", "Download")
                      )
                    )
                  )
                ))
ui <-
  shinyUI(dashboardPage(
    dashboardHeader(title = "TestApp", titleWidth = 150),
    sidebar,dashboardBody(tabItems(body))
  ))


server <- function(input, output, session) {
  file_rows <- reactiveVal()
  observeEvent(input$run, {
    prog <- Progress$new(session)
    prog$set(message = "Analysis in progress",
             detail = "This may take a while...",
             value = NULL)
    file_nrows <- reactive({
      return(input$nrows)
    })

    file_nrows_value <- file_nrows()

    file_input <- reactive({
      return(input$uploadFile$datapath)
    })

    file_input_value <- file_input()

    fut<- NULL

    fut<<- future({system(paste(
      "cat",
      file_input_value,
      "|",
      paste0("head -", file_nrows_value) ,
      ">",
      "out.txt"
    ))
    head_rows <- read.delim("out.txt")
    head_rows
    }) %...>%
     file_rows() %>%
     finally(~prog$close())
})

  observeEvent(file_rows(), {
    updateTabsetPanel(session, "input_tab", "results")
    output$res_table <-
      DT::renderDataTable(DT::datatable(
        file_rows(),
        options = list(
          searching = TRUE,
          pageLength = 10,
          rownames(NULL),
          scrollX = T
        )
      ))
  })

  output$downList <- downloadHandler(
    filename = function() {
      paste0("output", ".txt")
    }, content = function(file) {
      write.table(file_rows(), file, row.names = FALSE)
    }
  )

  observeEvent(input$cancel,{
    stopMulticoreFuture(fut)
  })

}

shinyApp(ui = ui, server = server)

当我单击取消"按钮时,UI被禁用,但控制台显示以下警告,并且命令仍在控制台中执行.

When i click "Cancel" button, the UI gets disabled but the console shows the below warning and the command still gets executed in the console.

Warning: Error in stopMulticoreFuture: stopMulticoreFuture only works on multicore futures

由于该示例表示一个快速运行的过程,因此在单击 Cancel 之前,将执行future()命令.

Since this example represents a quick running process the future() command gets executed before clicking Cancel.

实际上,即使在单击取消"后,警告(已禁用UI)后,将来(长过程)中的命令仍会在控制台中运行.

In real case, even after clicking "Cancel" the command inside the future (long process) still runs in the console after the warning while the UI is already disabled.

该应用程序当前在具有4个内核的MAC上运行.我如何才能杀死在控制台中运行的进程,而不仅仅是禁用UI?

The app is currently run on MAC with 4 cores. How could i kill the process running in the console rather just getting the UI disabled?

我目前正在测试我的应用程序,希望能在规划多进程/多核和终止进程方面提供专家意见,以使该应用程序高效地在并行用户之间运行异步进程.最终的应用程序将在具有4个虚拟CPU的Ubuntu计算机上运行.

I am currently testing my app and would be great to have expert input in planning multiprocess/multicore and killing the processes to make the app efficient for running async processes among parallel users. The final app will be running on Ubuntu machine with 4 virtual CPUs.

推荐答案

这里有几个问题:

  1. 您缺少 library(promises) plan(multicore) library(ipc).
  2. fut 并不是未来,这是有前途的,因为%...>%,所以 stopMulticoreFuture 不会在...上下功夫.
  3. ObserveEvent 表达式需要返回承诺以外的内容,否则您的UI将会阻塞.
  4. 由于 stopMulticoreFuture 只是杀死了进程,所以我无法保证它会与创建子进程的 system 调用一起使用.您可能需要找出这些的pid值并自己杀死它们.
  1. You are missing library(promises), plan(multicore) and library(ipc).
  2. fut is not a future, it is a promise because of the %...>%, so stopMulticoreFuture won't work on it.
  3. The ObserveEvent expression needs to return something other than the promise, otherwise your UI will block.
  4. Since stopMulticoreFuture just kills the process, I can't assure you that it will work with system calls that create subprocesses. You may need to figure out the pid values for these and kill them yourself.

这篇关于R光明的未来:计划(多进程)/计划(多核)+杀死长时间运行的进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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