R Shiny online app: How to properly restart instance when tab browser is closed?

I have a Shiny app deployed online. Each time it runs, it does ~ 10 min of calculations.

If the user closes the tab during the calculations (e.g. because they realised they loaded the wrong data and want to start again), reopening the app does not work. The browser just keeps loading ("Please Wait" is not displayed).

I tried adding
session$onSessionEnded(stopApp)
to my server code but it did not help.

I tried switching all the Advanced timeout settings to 5 sec in the dashboard but that does not seem to help either. Manually stopping the instance in shinyapp.io dashboard does resolve the issue, so I guess that is what I want to cause when the user closes the browser tab.

What is the proper way to solve this? I want the instance to fully stop and the app be ready to restart when the user closes the browser tab.

R is single threaded. Accordingly, once a user starts the 10 min of calculations the R process is busy and your shiny app is blocked. To avoid this you can run your long running functions async. Please check my related answer here.

1 Like

Thank you. Making progress but I'm stuck again. Here is the issue, if you don't mind.

Sticking as best as possible to your SO example, say our function analyze() is defined in another script. I have discovered I can call the function (with arguments) this way:

source('analyzeScript.R')

rv$analyze_process <- callr::r_bg(
  func = analyze,
  args=list(arg1=x,
            arg2=y
            )
)

So far, so good.

Now, function analyze() calls another function, let's call it subanalyze(). subanalyze()is defined in the script analyzeScript.R, just below analyze().

For some reason, that seems to be an issue. I get error:

! could not find function subanalyze()

The subanalyze() function was sourced (source('analyzeScript.R')) and therefore is in the Global Environment. Does it mean I need to edit all the sub-calls as well (i.e. the call to subanalyze() within analyze)? I must be missing something...

r_bg starts a blank R process. The new process has no access to the global env of the parent process. Accordingly the function you pass to r_bg's func parameter needs to be self-contained. In this case subanalyze() needs to be defined in analyze before it is first called.