My question is regarding keeping the shiny session active after closing the browser tab. I have deployed a shiny app on my university server. The app is developed using async programming (future package and multicore plan) and is capable of sending the results via email to the user after the results are generated (in the future). As the app does some long-running jobs I would prefer the app to remain active even after a user closes the browser tab. But it doesn't. The app is actually capable of remaining active even after the user loses access to their session. I am saying this because the user still gets the results email even when they get disconnected from the internet immediately after they hit the RUN button and then close the tab. However, if the user closes the tab as soon as they hit the RUN button without disconnecting from the internet the app is stopped and no result will be emailed to them.
My major question is: Is there any way to keep the shiny session active after the tab is closed? In other words, what does exactly happen under the hood after the user closes the browser tab? Is there any way to prevent that or somehow neutralize its effect?
Does no one have any clue?! Is it even possible? I also tested the future.callr package and used plan(callr) but it didn't work (the session died after closing the tab).
Thanks, Graham. Honestly, I haven't had experiences with Plumber. I had some readings but couldn't figure out how exactly applying the plumber to the long-running task would keep the shiny session active after the tab is closed. Can you please give me some more specific indications and hints?
I think you should rather detach the long running processes from the session instead of trying to keep the session alive.
You can hide a future from it's session by passing NULL after calling it. This procedure is described here. However, you need to be sure about what you are doing (see Joe Cheng's comment regarding race conditions).
Another possible solution could be to use r_bg() from library(callr) with it's default setting supervise = FALSE. Even base R's system(command, intern = FALSE, wait = FALSE) could be used to run a process and let the session forget about it.
Thanks for your reply. The hiding of the future seems not to work in my case as I have a change of future promises that need to be done one after another which makes things complicated with hiding the futures. I tested this idea and it seemed to hide the future would not work with future_promises.
The same complications are true for r_bg() function as well. For this purpose, I have to sort of re-write the app from scratch.
How about plumber? Have you ever used plumber APIs in combination with shiny? Do you have any idea how should I apply the idea Graham suggested in the comment above?
I recently tested hidden future_promises - they were working fine. Via then() you can access their results and trigger the next promise/function.
You may want to provide us with an example if you need more detailed help.
Regarding plumber I don't know how it should help in this situation besides the fact, that you could use it as an async backend. Maybe @nirgrahamuk can clearify. However, personally I'd much rather stick with the supported promises approach.