r - shiny and showNotification in parallel - Stack Overflow

admin2025-04-29  2

Below is my sequential reprex Shiny App that I want to run in a parallel environment:

lapply(c("shiny", "DT", "parallel"), library, character.only = TRUE)

ui <- fluidPage(
    DT::dataTableOutput("SomeTable")
)

server <- function(session, input, output){
    output$SomeTable <- DT::renderDataTable({
        data.frame(a = factor(c("A", "B", "C&", "D")), b = 1:4)
    }, filter = "top")
    
    no_cores <- detectCores()
    MasterSession <<- getDefaultReactiveDomain()
    #showNotification(ui = paste0("Configuring parallelisation (", no_cores, " cores found) and setting up clusters"), type = "message", duration = 8)
    #MyCluster <- makePSOCKcluster(no_cores - 1)
    #clusterEvalQ(MyCluster, {
    #   library(shiny)
    #})
    #clusterExport(MyCluster, c("MasterSession"))
    lapply(X = 1:4, FUN = function(b){
    #parLapply(cl = MyCluster, X = 1:4, fun = function(b){
        showNotification(ui = paste0("Row #", b, " out of 4"), type = "message", session = MasterSession)
    })
    stopCluster(MyCluster)
}

shinyApp(ui, server)

No problem when running this Shiny app in a pure sequential environment/configuration. Now its parallel counterpart:

lapply(c("shiny", "DT", "parallel"), library, character.only = TRUE)

ui <- fluidPage(
    DT::dataTableOutput("SomeTable")
)

server <- function(session, input, output){
    output$SomeTable <- DT::renderDataTable({
        data.frame(a = factor(c("A", "B", "C&", "D")), b = 1:4)
    }, filter = "top")
    
    no_cores <- detectCores()
    MasterSession <<- getDefaultReactiveDomain()
    showNotification(ui = paste0("Configuring parallelisation (", no_cores, " cores found) and setting up clusters"), type = "message", duration = 8)
    MyCluster <- makePSOCKcluster(no_cores - 1)
    clusterEvalQ(MyCluster, {
        library(shiny)
    })
    clusterExport(MyCluster, c("MasterSession"))
    #lapply(X = 1:4, FUN = function(b){
    parLapply(cl = MyCluster, X = 1:4, fun = function(b){
        showNotification(ui = paste0("Row #", b, " out of 4"), type = "message", session = MasterSession)
    })
    stopCluster(MyCluster)
}

shinyApp(ui, server)

I get an error and the other Shiny notifications don't appear:

Listening on http://127.0.0.1:3298
Avis : Error in unserialize: erreur de lecture de la connexion
  49: unserialize
  48: recvData.SOCKnode
  46: FUN
  45: lapply
  44: staticClusterApply
  43: clusterApply
  41: parLapply
  40: server [#15]
   3: runApp
   2: print.shiny.appobj
   1: <Anonymous>
Error in unserialize(node$con) : erreur de lecture de la connexion

After I replaced this row

showNotification(ui = paste0("Row #", b, " out of 4"), type = "message", session = MasterSession)

by this row (removed the argument session)

showNotification(ui = paste0("Row #", b, " out of 4"), type = "message")#, session = MasterSession)

I get another error (and the other Shiny notifications still don't appear):

Listening on http://127.0.0.1:3298
Avis : Error in checkForRemoteErrors: 4 nodes produced errors; first error: tentative d'appliquer un objet qui n'est pas une fonction
  46: stop
  45: checkForRemoteErrors
  44: staticClusterApply
  43: clusterApply
  41: parLapply
  40: server [#15]
   3: runApp
   2: print.shiny.appobj
   1: <Anonymous>
Error in checkForRemoteErrors(val) : 
  4 nodes produced errors; first error: tentative d'appliquer un objet qui n'est pas une fonction

Why can each process not display a Shiny notification?

I guess I will need to look at progress bars in parallel environment like mcprogress or ParallelLogger to inform the user on the progress made by the parallel computations, right?

转载请注明原文地址:http://anycun.com/QandA/1745939774a91403.html