R блестящее будущее: план (многопроцессорность) / план (многоядерность) + убить долго работающий процесс

Я пишу это, чтобы получить некоторую помощь в использовании плана (многопроцессорность) или плана (многоядерность) и уничтожении длительных процессов в моем блестящем приложении. В приложении есть несколько будущих событий (длительные процессы), которые запускаются при нажатии соответствующей кнопки actionButton. Ниже приведен пример приложения команды future (), используемой в функции сервера в приложении. И я использовал stopMulticoreFuture (fut), чтобы убить процессы.

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)

Когда я нажимаю кнопку «Отмена», пользовательский интерфейс отключается, но на консоли отображается предупреждение ниже, и команда по-прежнему выполняется в консоли.

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

Поскольку этот пример представляет собой быстро выполняющийся процесс, команда future () выполняется до нажатия кнопки Cancel.

В действительности, даже после нажатия кнопки «Отмена» команда в будущем (длительный процесс) все еще выполняется в консоли после предупреждения, хотя пользовательский интерфейс уже отключен.

В настоящее время приложение работает на MAC с 4 ядрами. Как я мог убить процесс, запущенный в консоли, а не просто отключить пользовательский интерфейс?

В настоящее время я тестирую свое приложение, и было бы здорово получить экспертную информацию по планированию многопроцессорности / многоядерности и уничтожению процессов, чтобы сделать приложение эффективным для запуска асинхронных процессов между параллельными пользователями. Последнее приложение будет работать на машине Ubuntu с 4 виртуальными процессорами.


person chas    schedule 05.11.2018    source источник
comment
Что такое stopMulticoreFuture()?   -  person HenrikB    schedule 05.11.2018
comment
Приведите простой воспроизводимый пример.   -  person HenrikB    schedule 05.11.2018
comment
stopMulticoreFuture() - это функция, которая отправляет сигналы завершения и уничтожения процессу, выполняющему будущее, и будет работать только для фьючерсов, выполняемых по многоядерному плану. Это из пакета ipc.   -  person chas    schedule 05.11.2018
comment
Пример использования stopMulticoreFuture() задокументирован здесь http://htmlpreview.github.io/?https://github.com/fellstat/ipc/blob/master/inst/doc/shinymp.html   -  person chas    schedule 05.11.2018
comment
К вашему сведению, вот почему так полезно предоставлять полностью воспроизводимые примеры, включая то, какие пакеты загружены и т. Д., То есть включают library() вызовов` и ​​sessionInfo().   -  person HenrikB    schedule 05.11.2018
comment
OP обновлен воспроизводимым примером.   -  person chas    schedule 06.11.2018


Ответы (1)


Здесь пара проблем:

  1. Вам не хватает library(promises), plan(multicore) и library(ipc).
  2. fut - это не будущее, это обещание из-за %...>%, поэтому stopMulticoreFuture не будет работать над ним.
  3. Выражение ObserveEvent должно возвращать что-то другое, кроме обещания, иначе ваш пользовательский интерфейс будет заблокирован.
  4. Поскольку stopMulticoreFuture просто убивает процесс, я не могу заверить вас, что он будет работать с system вызовами, которые создают подпроцессы. Возможно, вам придется вычислить для них значения pid и убить их самостоятельно.
person Ian Fellows    schedule 13.11.2018