Shiny app composed of many, many pages

@Open-meta:

Thanks Tom, your work is great, but I had already found it. I would like have 2 features:

  1. Avoid to restart the entire session. I think it can slow down the server, but actually I'm not sure about this. Do somebody know more about this?

  2. Keep a session data, this way the next page can be aware of the previous, or I can avoid a long reload from a database, or whatever you can do with a session data.

####################

@All:

For my requirements, I would replace your design with this one:

https://github.com/bborgesr/employee-dir

(Thanks Barbara @RStudio for your time.)

In this example:

A. the session is only one,
B. the page is changed changing the "?page=" parameter in the url with the function shiny::updateQueryString()

####################

This is my example:

## app.R ##

## ################################################################
## global.R
library(shiny)
library(shinydashboard)

###################################################################
## Module

## input-module-UI
randModuleOutput <- function(id) {
    ns <- NS(id)
    dataTableOutput(ns("rndData"))
}

## input-module-server
randModule <- function(input, output, session) {
	rv <- reactiveValues()
	observe({
		# generate a random dataframe
		rv$df <- data.frame(rnd = rnorm(n = 10^7))
		# show in shiny the first 3 lines (only to see that the data has been created)
		output$rndData <- renderDataTable({head(rv$df, n = 3)})
	})
	
	# delete data in the module
	destroyData <- reactive({
		rv$df <- NULL
	})
	
	list(
		data = rv$df,
		session = session,
		destroyData = destroyData
	)
}

## ################################################################
## ui.R
ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
        	checkboxInput("explicitDestroy", "Remove data explicitely",
        								value = T)
        ),
        mainPanel(
        	textOutput("meminfo"),
        	actionButton(inputId = "add",
        							 label = "Add a module"),
        	actionButton(inputId = "remove",
        							 label = "Remove a module")
        )
    )
)

## ################################################################
## server.R
server <- 
	function(input, output) {
		modules <- reactiveValues()

		observeEvent(input$add, {
			moduleNumber <- input$add
			moduleName <- paste0("datafile", moduleNumber)    		
			insertUI("#remove",
							 where = "afterEnd",
							 randModuleOutput(id = moduleName))
			moduleLs <- callModule(randModule, moduleName)
			modules[[moduleName]] <- list(data = NULL,
																		session = NULL,
																		destroyData = NULL)
			modules[[moduleName]]$data <- moduleLs$data
			modules[[moduleName]]$session <- moduleLs$session
			modules[[moduleName]]$destroyData <- moduleLs$destroyData
		})
		observeEvent(input$remove, {
			moduleNumber <- input$remove
			moduleName <- paste0("datafile", moduleNumber)	
			removeUI(paste0("#", moduleName, "-rndData"))
			modules[[moduleName]]$data <- NULL
			modules[[moduleName]]$session <- NULL
			if (input$explicitDestroy) {
				modules[[moduleName]]$destroyData()
			}
			modules[[moduleName]]$destroyData <- NULL
			gc()
		})
		output$meminfo <- renderText({
			input$add
			input$remove
			paste(round(pryr::mem_used()/10^6, digits = 0), "Mb")
		})
	}

## ################################################################
## shinyApp()

shinyApp(ui, server)

live example: https://akirocode.shinyapps.io/remove-reactive/

In my example, you can add (and remove) Shiny DataTable to (and from) the interface.

Each Shiny DataTable has a corresponding big dataset behind it. Therefore a big amount of memory is used for each DataTable.

Now if I remove a module (a Shiny DataTable) WITHOUT the flag on "Remove data explicitely" the dataset is not accessible, but still in memory.
If I enable the "Remove data explicitely" I free the content of the reactiveValues, which frees the RAM.

But for the same reason, the reactive is still in memory and no way to remove it.

Any Ideas?

Note: Bug, the used memory is in late of one click, sorry... :frowning:

####################
Summary:

Therefore to clean the memory used by the page we have the following alternatives:

  1. reboot the session (suggested by Tom @Open-meta)

  2. Create a event handler that remove the data from the application (as my above example), but, in this case, the reactive objects can't be removed. Any Idea

1 Like