Как не ждать оценки обещания в R - PullRequest
3 голосов
/ 06 мая 2020

Я хотел бы выполнить очень дорогостоящую функцию (называемую never_ending_cal c в приведенном ниже примере) в отдельном сеансе R в блестящем приложении. Я уже подготовил приведенный ниже код, он работает нормально, но мой родительский сеанс R ожидает результата от объекта обещания, и это использует много ресурсов. Если вы проверите диспетчер задач во время работы приведенного ниже тестового приложения, вы увидите, что родительский сеанс R использует один поток ЦП на максимальной мощности, просто ожидая результатов объекта обещания.

Как я могу оценить обещание таким образом, чтобы не использовать ресурсы родительского сеанса R? (Также нормально, если я потеряю связь между этими двумя сеансами.)

Я пробовал следующее (ни одно из них не сработало):

  • использовать другой «план»
  • отправить настраиваемое сообщение (например, предупреждение) из функции never_ending_cal c 'в ее первой строке, чтобы каким-то образом остановить родительский сеанс для ожидания объекта обещания

Вот пример:

library(shiny)
library(future)
library(promises)
library(future.callr)

never_ending_calc <- function(){
  K = 1
  for (i in 1:20){
    K = K + i
    Sys.sleep(5)
  }
  return(K)
}

ui <- fluidPage(

  # App title ----
  titlePanel("Test app"),

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel ----
    sidebarPanel(

      # action button to start the long test calculation ----
      actionButton(inputId = "start_test",
                   label = "Start test run")

    ),


    mainPanel()
  )
)


server <- function(input, output) {  

  observeEvent(input$start_test, {

  # start execute the long calculation in another separate R session
  future::plan(future.callr::callr)
  long_calculation_future <<- future::future({
    never_ending_calc()
  })
  promises::then(long_calculation_future,
                 onFulfilled = NULL,
                 onRejected = function(error){NULL})
  future::plan(future::sequential)

  # return NULL to keep the shiny app reactive
  NULL

  })


}

shinyApp(ui, server)
...