Thanks to your quick comments and research! So it is important that to run expensive calculation in different process, am I right? According to your suggestion, this time I followed SO's solution.
Following code works as expected in my environment. Thanks!!
## example2.1.R
library(shiny)
library(shinydashboard)
options(shiny.port=3131, shiny.host='0.0.0.0')
n <- 30
## To stick scroll bar to the bottom of UI
htmlLogOutput <- function(outputId, placeholder = FALSE) {
div(tags$head(
tags$style(
paste0("#", outputId, "{
color: gray;
font-size: 12px;
max-height: 300px;
font-style: italic;
overflow-y: scroll;
background: ghostwhite;
}")
),
tags$script(
paste0('
Shiny.addCustomMessageHandler("scrollCallback",
function(a) {
var objDiv = document.getElementById("', outputId, '");
objDiv.scrollTop = objDiv.scrollHeight;
}
);'
))
),
shiny::htmlOutput(
outputId = outputId,
placeholder = placeholder
)
)
}
server <- function(input, output, session) {
execStatus <- reactiveValues(textstream = c(""),
timer = reactiveTimer(1000),
started = FALSE)
observeEvent(input$exec, {
execStatus$started <- TRUE
args <- paste('long.computation.R', n, '>', 'long.computation.txt', sep=' ')
system2('Rscript', args, wait = FALSE)
})
observeEvent(input$stop, {
execStatus$started <- FALSE
})
observe({
execStatus$timer()
if (isolate(execStatus$started)==TRUE){
execStatus$textstream <- paste(readLines('long.computation.txt'), collapse = '<br/>')
session$sendCustomMessage(type='scrollCallback', 1)
}
})
output$log <- renderUI({
HTML(execStatus$textstream)
})
}
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem('Exec & Log', tabName='execlog', icon=icon('th'), selected=TRUE)
)
)
body <- dashboardBody(
tabItem(tabName = 'execlog',
actionButton('exec', 'Exec'),
actionButton('stop', 'Stop'),
htmlLogOutput('log'),
)
)
ui <- dashboardPage(
dashboardHeader(title='example'),
sidebar,
body
)
runApp(shinyApp(ui, server))
## long.computation.R
##
long.computation <- function(n){
for (i in seq(1, n)){
Sys.sleep(1)
print(sprintf('Some logging %s: this time logging appears in shiny ui in realtime!!', i))
}
}
args <- commandArgs()
## print(args)
n <- args[6]
long.computation(n)