R/Shiny: View full stack/execution log - r

I'm debugging a Shiny web app, and would like to see the entire control flow/execution path over the course of rendering and updating the generated website.
Is there a way to capture/print/dump-to-file every line of code that is executed in the process of rendering/updating a Shiny app? It would also be good (maybe better?) to see every line of R code parsed by the running R interpreter instance; I'm not concerned about length of this output, and would prefer to get things as verbosely as possible.
I have looked into the stack tracing Shiny functions but these seem to be intended for error catching/handling/reporting. The app is not generating errors/warnings, just setting some variables to NULL at some point when they shouldn't be, so I'm not sure if this is the right approach. These stack tracing functions also seem to be more localized, designed to operate within a given reactive variable/function/render rather than following the control/execution flow across differing reactives/rendering functions in an app.
This app is a large, company-internal app so I cannot give a MRE/MWE.

I finally found the profvis package that does more-or-less exactly what I want by taking a snapshot of the execution stack at a fixed time interval (default 10ms). I'm still working on using this tool to debug, but I believe this will get me there and would also be useful to others debugging Shiny apps that need more than browser() and/or reactlog.
Specifically, I have been doing:
#install.packages("profvis")
library(profvis)
exec_log <- profvis(runApp("myShinyApp"))
...interact with the myShinyApp web page enough to trigger the bug, then interrupt execution...
print(exec_log)

Related

Shiny app is stalled when executing a big calculation

I'm new to shiny , couldn't get my answer anywhere tho.
I have a heavy code aggregating tables in R. I wanted to move it to the Web app and I chose Shiny as my original code is written in R so I thought it saves me lots of time.
When I run the code by
ObserveEvent(actionbutton$do,{mybigcalculation(input_tables)})
my code is running but at the time of executing my code, it's not possible to do other stuff like exploring tables in the other tabs.The rendering part works but he web app functionalities is completely frozen at the time the process is running.
Any help would be highly appreciated ? if this doesn't work I have to move to typical web app development by having backend ( e.g plumber ) and frontend (e.g React) in separate servers.
Thank you
After a long investigation, I think I found the answer. I'm writing it down here as you might face this issue quite often developing your web app by Shiny. Always there are some big processes you wanna do and wanna make sure your async works great.
There are libraries (future & promises packages) that Cheng explains them here. it says, they can take the calculations in the background and make them come back with the result while the shiny app is doing its normal job. It didn't work for me and I still had my web app stalled. But what I saw, they did increase mybigcalculation speed dramatically. Also it took it to the background makes it invisible in the console.
I found my answer in a package called Shiny.worker library.
Now my app is working fine while my expensive code is running in the background. I made my ideal execution(fast and async) by wrapping future package inside of a shiny worker library.
So it looks something like this:
load.lib <- c("promises","future","shiny.worker")
install.lib <- load.lib[!load.lib %in% installed.packages()]
for(lib in install.lib) install.packages(lib,dependencies=TRUE)
sapply(load.lib,library,character=TRUE)
plan(multisession)
initiate the worker by:
worker <- shiny.worker::initialize_worker()
then:
wrapper <- function(args) {
future::future(my_heavy_calculations(args$r))
}
reactive_arguments <- reactive({
input$start
list(r = rnorm(1))
})
resultPromise <- worker$run_job("job1", wrapper, args_reactive = reactive_arguments)
resultPromise()$result # contains the result of the calculations
resultPromise()$resolved # contains flag that informs whether the job has finished or not
I'm looking forward for any idea and suggestions that can makes the answer better.

R Shiny Server - set a loading animation on application startup

I've used shinyapps.io in the past and it provides a loading animation (spinner) while the application starts up. This is useful because I load 200MB of .RData-files into the memory (once on startup, not for every server()). This takes up to 40 seconds (in future, I will transition towards storing the data in a database, but for now this is what I got).
For other applications, I've used the docker image rocker/shiny and wanted to fully transition to a Docker-based approach and put all my shiny applications on one server and move away from shinyapps.io. However, the one issue I have with this application is that it does not display a loading animation while it starts so the user is left with a grey screen for a good 30-40 seconds while the data is loaded in the background.
As for the code, I load all data and then I source ui.R and server.R before running shiny::shinyApp(ui = ui, server = server).
Does any of you know a way to specify a loading animation on startup of the application (I haven't found anything in the server configuration itself but I could have overlooked something)? Or have you found a nice workaround to achieve the desired result?
So what I ended up doing was to follow this workaround suggested here: http://www.mazsoft.com/blog/post/2018/01/01/show-progress-bar-when-pre-loading-data-in-shiny-app
The idea is that we initialize all data variables with NULL. Then there is a readData() function outside of server and ui where we load all the data into the global variables and at the beginning of the server function block we check if one of our data variables is.null() which would lead us to call the readData() function.
It is an okay solution for my problem as it's a nice workaround, yet I wasn't able to figure out how to actually display a loading animation on startup, just while loading the data. I hope this helps people with a similar same problem.

Start shiny app with input on shiny-server

My problem is as follows: Think of a shiny-app that handles a text input and presents results for this input. However, I want to limit the possibilities of my customers in a sense, that they can not give the text input manually (due to third-party-API-rate-limits) but only once externally. I retrieve the necessary input in a survey externally and I then want to redirect to my app with the input already given (so that they should not be able to play around with different other inputs).
So basically my question boils down to:
"How can I handle the input to a shiny app through a URL."
Let's say my app runs on
1.1.1.1:3838
which displays my app when I open it in a browser. Could I e.g. transform my app to handle URL-requests such as
1.1.1.1:3838/exampletext
(where 1.1.1.1 represents an IP Address) in a way that it then can process "exampletext" in its calculations and displays already prepared results (without the need of a textInput()-field)
I set up a shiny-server on an AWS EC2 instance but I am struggling to find any recommendations on how to build the infrastructure. I first intended to start a new app for each input in a bash script such as:
./app.R exampletext
and process it in the shiny app then like that:
args <- commandArgs(trailingOnly=TRUE)
textInput <- args[1]
However, I think there should be more clever ways to do this with a shiny app/on a shiny-server (apart from the fact that I don't have a real idea how this could really work out). Should I maybe consider a bash script to help me process the input and automatically start a script? In any case, I would be grateful if someone could at least provide me with some keywords to look for the matter appropriately. Thank you!
EDIT1: As proposed by #jyjek and also in this thread:
How do you pass parameters to a shiny app via URL. I could use an observer object that processes any changes in the URL to other objects. This solved the basic foundations of my problem, however, I could use a more static approach as my main goal is to create a non-changeable input. Therefore it is not necessary for me to adapt to changes in the URL, I rather prefer to give once a URL that should not be changeable.

R JIT compiler - is there a way to automatically pre-compile all functions in a script? (for use with shiny)

Is there a way to get R to precompile all functions in a script?
The reason it matters is because the script is code for rshiny. I'd like to push forward the byte compiling to occur when the server starts up rather when the user is requesting a page.
I know cmpfun() could be used to compile one function at a time and modify function calls accordingly, but I'd like to do this without maintaining the extra boilerplate code if it's possible.
You should be able to use the JIT from compiler with:
library(compiler)
enableJIT(3)
or set the environment variable R_ENABLE_JIT to non-negative (3 is the highest amount of compilation). I did a quick experiment with my Shiny app and this seemed to produce no benefit at all, so maybe something is not working correctly. This page provides a few more details on R compilation options.

What Happens on Shiny runApp()?

I have a shiny app with a login page. Once the user has logged in, it directs them to the rest of the app.
As I have been developing my shiny app, the time it takes to render the initial login page has been increasing (it is now around 30 seconds).
I have put breakpoints all over my code (including the first lines of ui.R, server.R, and other files which are sourced).
The login screen is similar to that of this great post from Huidong Tian.
What is shiny doing for 30 seconds between me doing runApp(), and
hitting the first breakpoint on the first line of my code?
The console simply prints:
Listening on http://127.0.0.1:xxxx, and then waits.
I hope the question is generic enough such that code isn't needed - and I'm not sure what code could help answer the question. Let me know if further info is needed. Thanks.
Answer to the original question: (this is as I have observed, please comment / edit if incorrect)
When I do runApp(), RStudio compiles the all the code within the application, and no breakpoints are triggered.
Once the entire code is compiled (ie reactive expressions stored in the memory, packages loaded), breakpoints are triggered on lines of code as they are hit.
Why my code was slow before first breakpoint
Reactive expression wasn't properly used on the big database call, and I have now sourced much of my code to other files which has improved the speed greatly.
I have also discovered the fantastic function reactivePoll() which has helped.

Resources